diff --git a/INSTALL b/INSTALL
index d2f08ec677e270d49f071a968ed7ca0a79c55a08..2f5f29c788fe9f03aead9f973da1080e954a90a3 100644
--- a/INSTALL
+++ b/INSTALL
@@ -23,6 +23,11 @@ Building the python wrapper requires the following:
 
   # apt-get install python-all-dev python-virtualenv
 
+If you want to install in a different directory than the default /usr/lib, you can
+override it on the command line:
+
+  # make install prefix=/opt
+
 
 *******************************
 * More detailled instructions *
@@ -95,6 +100,44 @@ will need clang and its instrumented libc++:
 
   # apt-get install clang libc++-dev
 
+Mac-specific notes:
+-------------------
+
+For a Mac system, git is not available by default. You will first need to
+install Xcode from the Mac AppStore and then run the following command from a
+terminal:
+
+  $ sudo xcode-select --install
+
+You should also install "port" following the instructions at
+https://www.macports.org . This will reside in /opt/local/bin/port for
+most Mac installations. Do the "git submodule" command listed above.
+
+Then execute the following for all the needed build dependencies
+
+  $ sudo /opt/local/bin/port install autoconf automake libtool gflags cmake
+  $ mkdir ~/gtest
+  $ svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
+  $ mkdir mybuild
+  $ cd mybuild
+  $ cmake ../gtest-svn
+  $ make
+  $ make gtest.a gtest_main.a
+  $ sudo cp libgtest.a libgtest_main.a /opt/local/lib
+  $ sudo mkdir /opt/local/include/gtest
+  $ sudo cp -pr ../gtest-svn/include/gtest /opt/local/include/gtest 
+
+We will also need to make openssl and install it appropriately
+
+  $ cd <git directory>
+  $ cd third_party/openssl
+  $ sudo make install
+  $ cd ../../
+
+If you are going to make changes and need to regenerate the projects file,
+you will need to install certain modules for python.
+
+  $ sudo easy_install simplejson mako
 
 A word on OpenSSL
 -----------------
diff --git a/Makefile b/Makefile
index e5262b3db580b17495ff65610b77d3347f67838c..0a53adda97083c222d9e3343419f9e2f957e721b 100644
--- a/Makefile
+++ b/Makefile
@@ -86,7 +86,6 @@ CXX_tsan = clang++
 LD_tsan = clang
 LDXX_tsan = clang++
 CPPFLAGS_tsan = -O1 -fsanitize=thread -fno-omit-frame-pointer
-OPENSSL_CONFIG_tsan = no-asm
 LDFLAGS_tsan = -fsanitize=thread
 DEFINES_tsan = NDEBUG
 
@@ -97,7 +96,6 @@ CXX_asan = clang++
 LD_asan = clang
 LDXX_asan = clang++
 CPPFLAGS_asan = -O1 -fsanitize=address -fno-omit-frame-pointer
-OPENSSL_CONFIG_asan = no-asm
 LDFLAGS_asan = -fsanitize=address
 DEFINES_asan = NDEBUG
 
@@ -109,7 +107,6 @@ LD_msan = clang
 LDXX_msan = clang++-libc++
 CPPFLAGS_msan = -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
 OPENSSL_CFLAGS_msan = -DPURIFY
-OPENSSL_CONFIG_msan = no-asm
 LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
 DEFINES_msan = NDEBUG
 
@@ -121,7 +118,6 @@ LD_ubsan = clang
 LDXX_ubsan = clang++
 CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer
 OPENSSL_CFLAGS_ubsan = -DPURIFY
-OPENSSL_CONFIG_ubsan = no-asm
 LDFLAGS_ubsan = -fsanitize=undefined
 DEFINES_ubsan = NDEBUG
 
@@ -177,7 +173,9 @@ LDFLAGS += -g -fPIC
 
 INCLUDES = . include $(GENDIR)
 ifeq ($(SYSTEM),Darwin)
+INCLUDES += /usr/local/ssl/include /opt/local/include
 LIBS = m z
+LDFLAGS += -L/usr/local/ssl/lib -L/opt/local/lib
 else
 LIBS = rt m z pthread
 LDFLAGS += -pthread
@@ -330,9 +328,9 @@ endif
 
 .SECONDARY = %.pb.h %.pb.cc
 
-PROTOC_PLUGINS= $(BINDIR)/$(CONFIG)/cpp_plugin $(BINDIR)/$(CONFIG)/ruby_plugin
+PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin
 ifeq ($(DEP_MISSING),)
-all: static shared
+all: static shared plugins
 dep_error:
 	@echo "You shouldn't see this message - all of your dependencies are correct."
 else
@@ -494,8 +492,11 @@ time_averaged_stats_test: $(BINDIR)/$(CONFIG)/time_averaged_stats_test
 time_test: $(BINDIR)/$(CONFIG)/time_test
 timeout_encoding_test: $(BINDIR)/$(CONFIG)/timeout_encoding_test
 transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test
+async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
 channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
-cpp_plugin: $(BINDIR)/$(CONFIG)/cpp_plugin
+grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
+grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
 credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
 end2end_test: $(BINDIR)/$(CONFIG)/end2end_test
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
@@ -505,9 +506,7 @@ pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test
 pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test
 qps_client: $(BINDIR)/$(CONFIG)/qps_client
 qps_server: $(BINDIR)/$(CONFIG)/qps_server
-ruby_plugin: $(BINDIR)/$(CONFIG)/ruby_plugin
 status_test: $(BINDIR)/$(CONFIG)/status_test
-sync_client_async_server_test: $(BINDIR)/$(CONFIG)/sync_client_async_server_test
 thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test
 chttp2_fake_security_cancel_after_accept_test: $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test
 chttp2_fake_security_cancel_after_accept_and_writes_closed_test: $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test
@@ -864,9 +863,9 @@ $(LIBDIR)/$(CONFIG)/zlib/libz.a:
 $(LIBDIR)/$(CONFIG)/openssl/libssl.a:
 	$(E) "[MAKE]    Building openssl for $(SYSTEM)"
 ifeq ($(SYSTEM),Darwin)
-	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./Configure darwin64-x86_64-cc $(OPENSSL_CONFIG_$(CONFIG)))
+	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./Configure darwin64-x86_64-cc)
 else
-	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./config $(OPENSSL_CONFIG_$(CONFIG)))
+	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./config no-asm $(OPENSSL_CONFIG_$(CONFIG)))
 endif
 	$(Q)$(MAKE) -C third_party/openssl clean
 	$(Q)$(MAKE) -C third_party/openssl build_crypto build_ssl
@@ -890,16 +889,21 @@ $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
 
 static: static_c static_cxx
 
-static_c:  $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
+static_c:  $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 
 static_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++.a
 
 shared: shared_c shared_cxx
 
-shared_c:  $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
+shared_c:  $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
 
 shared_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT)
 
+shared_csharp: shared_c  $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
+grpc_csharp_ext: shared_csharp
+
+plugins: $(PROTOC_PLUGINS)
+
 privatelibs: privatelibs_c privatelibs_cxx
 
 privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack_uds.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a $(LIBDIR)/$(CONFIG)/libend2end_test_empty_batch.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_thread_stress.a $(LIBDIR)/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_thread_stress_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a
@@ -910,7 +914,7 @@ buildtests: buildtests_c buildtests_cxx
 
 buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test
 
-buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/sync_client_async_server_test $(BINDIR)/$(CONFIG)/thread_pool_test
+buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
 
 test: test_c test_cxx
 
@@ -1722,6 +1726,8 @@ test_c: buildtests_c
 
 
 test_cxx: buildtests_cxx
+	$(E) "[RUN]     Testing async_end2end_test"
+	$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_arguments_test"
 	$(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
 	$(E) "[RUN]     Testing credentials_test"
@@ -1734,8 +1740,6 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/pubsub_subscriber_test || ( echo test pubsub_subscriber_test failed ; exit 1 )
 	$(E) "[RUN]     Testing status_test"
 	$(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 )
-	$(E) "[RUN]     Testing sync_client_async_server_test"
-	$(Q) $(BINDIR)/$(CONFIG)/sync_client_async_server_test || ( echo test sync_client_async_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing thread_pool_test"
 	$(Q) $(BINDIR)/$(CONFIG)/thread_pool_test || ( echo test thread_pool_test failed ; exit 1 )
 
@@ -1763,8 +1767,6 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[STRIP]   Stripping libgrpc.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc.a
-	$(E) "[STRIP]   Stripping libgrpc_csharp_ext.a"
-	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
 	$(E) "[STRIP]   Stripping libgrpc_unsecure.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 endif
@@ -1781,8 +1783,6 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping libgrpc.so"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT)
-	$(E) "[STRIP]   Stripping libgrpc_csharp_ext.so"
-	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping libgrpc_unsecure.so"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
 endif
@@ -1793,13 +1793,19 @@ ifeq ($(CONFIG),opt)
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT)
 endif
 
+strip-shared_csharp: shared_csharp
+ifeq ($(CONFIG),opt)
+	$(E) "[STRIP]   Stripping libgrpc_csharp_ext.so"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT)
+endif
+
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/examples/pubsub/empty.pb.cc: protoc_dep_error
 else
 $(GENDIR)/examples/pubsub/empty.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1808,7 +1814,7 @@ else
 $(GENDIR)/examples/pubsub/label.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1817,7 +1823,7 @@ else
 $(GENDIR)/examples/pubsub/pubsub.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1826,7 +1832,7 @@ else
 $(GENDIR)/test/cpp/interop/empty.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1835,7 +1841,7 @@ else
 $(GENDIR)/test/cpp/interop/messages.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1844,7 +1850,7 @@ else
 $(GENDIR)/test/cpp/interop/test.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1853,7 +1859,7 @@ else
 $(GENDIR)/test/cpp/qps/qpstest.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1862,7 +1868,7 @@ else
 $(GENDIR)/test/cpp/util/echo.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1871,7 +1877,7 @@ else
 $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
@@ -1880,7 +1886,7 @@ else
 $(GENDIR)/test/cpp/util/messages.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 
@@ -1905,12 +1911,16 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc
 	$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 
-install: install_c install_cxx
+install: install_c install_cxx install-protobuf install-plugins
 
 install_c: install-headers_c install-static_c install-shared_c
 
 install_cxx: install-headers_cxx install-static_cxx install-shared_cxx
 
+install_csharp: install-shared_csharp install_c
+
+install_grpc_csharp_ext: install_csharp
+
 install-headers: install-headers_c install-headers_cxx
 
 install-headers_c:
@@ -1928,8 +1938,6 @@ install-static_c: static_c strip-static_c
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.a $(prefix)/lib/libgpr.a
 	$(E) "[INSTALL] Installing libgrpc.a"
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
-	$(E) "[INSTALL] Installing libgrpc_csharp_ext.a"
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(prefix)/lib/libgrpc_csharp_ext.a
 	$(E) "[INSTALL] Installing libgrpc_unsecure.a"
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
 
@@ -1937,6 +1945,8 @@ install-static_cxx: static_cxx strip-static_cxx
 	$(E) "[INSTALL] Installing libgrpc++.a"
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
 
+
+
 install-shared_c: shared_c strip-shared_c
 ifeq ($(SYSTEM),MINGW32)
 	$(E) "[INSTALL] Installing gpr.$(SHARED_EXT)"
@@ -1960,17 +1970,6 @@ ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so
 endif
 endif
-ifeq ($(SYSTEM),MINGW32)
-	$(E) "[INSTALL] Installing grpc_csharp_ext.$(SHARED_EXT)"
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
-else
-	$(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)"
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
-ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
-endif
-endif
 ifeq ($(SYSTEM),MINGW32)
 	$(E) "[INSTALL] Installing grpc_unsecure.$(SHARED_EXT)"
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc_unsecure.$(SHARED_EXT)
@@ -1984,11 +1983,12 @@ endif
 endif
 ifneq ($(SYSTEM),MINGW32)
 ifneq ($(SYSTEM),Darwin)
-	$(Q) ldconfig
+	$(Q) ldconfig || true
 endif
 endif
 
-install-shared_cxx: shared_cxx strip-shared_cxx
+
+install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c
 ifeq ($(SYSTEM),MINGW32)
 	$(E) "[INSTALL] Installing grpc++.$(SHARED_EXT)"
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(prefix)/lib/grpc++.$(SHARED_EXT)
@@ -2002,11 +2002,53 @@ endif
 endif
 ifneq ($(SYSTEM),MINGW32)
 ifneq ($(SYSTEM),Darwin)
-	$(Q) ldconfig
+	$(Q) ldconfig || true
+endif
+endif
+
+
+install-shared_csharp: shared_csharp strip-shared_csharp
+ifeq ($(SYSTEM),MINGW32)
+	$(E) "[INSTALL] Installing grpc_csharp_ext.$(SHARED_EXT)"
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
+else
+	$(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)"
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
+endif
+endif
+ifneq ($(SYSTEM),MINGW32)
+ifneq ($(SYSTEM),Darwin)
+	$(Q) ldconfig || true
 endif
 endif
 
+
+install-protobuf: $(PROTOBUF_DEP)
+ifneq ($(PROTOBUF_DEP),)
+	$(E) "[INSTALL] Installing embedded protobufs"
+	$(Q) $(MAKE) -C third_party/protobuf install prefix=$(prefix)
+ifneq ($(SYSTEM),MINGW32)
+ifneq ($(SYSTEM),Darwin)
+	$(Q) ldconfig || true
+endif
+endif
+endif
+
+install-plugins: $(PROTOC_PLUGINS)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) false
+else
+	$(E) "[INSTALL] Installing grpc protoc plugins"
+	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(prefix)/bin/grpc_cpp_plugin
+	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin
+	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_python_plugin $(prefix)/bin/grpc_python_plugin
+endif
+
 clean:
+	$(E) "[CLEAN]   Cleaning build directories."
 	$(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR)
 
 
@@ -2990,27 +3032,24 @@ LIBGRPC++_SRC = \
     src/cpp/client/channel.cc \
     src/cpp/client/channel_arguments.cc \
     src/cpp/client/client_context.cc \
+    src/cpp/client/client_unary_call.cc \
     src/cpp/client/create_channel.cc \
     src/cpp/client/credentials.cc \
     src/cpp/client/internal_stub.cc \
+    src/cpp/common/call.cc \
     src/cpp/common/completion_queue.cc \
     src/cpp/common/rpc_method.cc \
     src/cpp/proto/proto_utils.cc \
-    src/cpp/server/async_server.cc \
-    src/cpp/server/async_server_context.cc \
     src/cpp/server/server.cc \
     src/cpp/server/server_builder.cc \
-    src/cpp/server/server_context_impl.cc \
+    src/cpp/server/server_context.cc \
     src/cpp/server/server_credentials.cc \
-    src/cpp/server/server_rpc_handler.cc \
     src/cpp/server/thread_pool.cc \
-    src/cpp/stream/stream_context.cc \
     src/cpp/util/status.cc \
     src/cpp/util/time.cc \
 
 PUBLIC_HEADERS_CXX += \
-    include/grpc++/async_server.h \
-    include/grpc++/async_server_context.h \
+    include/grpc++/async_unary_call.h \
     include/grpc++/channel_arguments.h \
     include/grpc++/channel_interface.h \
     include/grpc++/client_context.h \
@@ -3018,16 +3057,20 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/config.h \
     include/grpc++/create_channel.h \
     include/grpc++/credentials.h \
+    include/grpc++/impl/call.h \
+    include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/internal_stub.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
+    include/grpc++/impl/service_type.h \
     include/grpc++/server.h \
     include/grpc++/server_builder.h \
     include/grpc++/server_context.h \
     include/grpc++/server_credentials.h \
     include/grpc++/status.h \
+    include/grpc++/status_code_enum.h \
     include/grpc++/stream.h \
-    include/grpc++/stream_context_interface.h \
+    include/grpc++/thread_pool_interface.h \
 
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
@@ -3066,21 +3109,19 @@ ifneq ($(OPENSSL_DEP),)
 src/cpp/client/channel.cc: $(OPENSSL_DEP)
 src/cpp/client/channel_arguments.cc: $(OPENSSL_DEP)
 src/cpp/client/client_context.cc: $(OPENSSL_DEP)
+src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP)
 src/cpp/client/create_channel.cc: $(OPENSSL_DEP)
 src/cpp/client/credentials.cc: $(OPENSSL_DEP)
 src/cpp/client/internal_stub.cc: $(OPENSSL_DEP)
+src/cpp/common/call.cc: $(OPENSSL_DEP)
 src/cpp/common/completion_queue.cc: $(OPENSSL_DEP)
 src/cpp/common/rpc_method.cc: $(OPENSSL_DEP)
 src/cpp/proto/proto_utils.cc: $(OPENSSL_DEP)
-src/cpp/server/async_server.cc: $(OPENSSL_DEP)
-src/cpp/server/async_server_context.cc: $(OPENSSL_DEP)
 src/cpp/server/server.cc: $(OPENSSL_DEP)
 src/cpp/server/server_builder.cc: $(OPENSSL_DEP)
-src/cpp/server/server_context_impl.cc: $(OPENSSL_DEP)
+src/cpp/server/server_context.cc: $(OPENSSL_DEP)
 src/cpp/server/server_credentials.cc: $(OPENSSL_DEP)
-src/cpp/server/server_rpc_handler.cc: $(OPENSSL_DEP)
 src/cpp/server/thread_pool.cc: $(OPENSSL_DEP)
-src/cpp/stream/stream_context.cc: $(OPENSSL_DEP)
 src/cpp/util/status.cc: $(OPENSSL_DEP)
 src/cpp/util/time.cc: $(OPENSSL_DEP)
 endif
@@ -3127,21 +3168,19 @@ endif
 $(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: 
-$(OBJDIR)/$(CONFIG)/src/cpp/server/async_server.o: 
-$(OBJDIR)/$(CONFIG)/src/cpp/server/async_server_context.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: 
-$(OBJDIR)/$(CONFIG)/src/cpp/server/server_context_impl.o: 
+$(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/server_credentials.o: 
-$(OBJDIR)/$(CONFIG)/src/cpp/server/server_rpc_handler.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/server/thread_pool.o: 
-$(OBJDIR)/$(CONFIG)/src/cpp/stream/stream_context.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/util/status.o: 
 $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: 
 
@@ -3150,7 +3189,6 @@ LIBGRPC++_TEST_UTIL_SRC = \
     $(GENDIR)/test/cpp/util/messages.pb.cc \
     $(GENDIR)/test/cpp/util/echo.pb.cc \
     $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc \
-    test/cpp/end2end/async_test_server.cc \
     test/cpp/util/create_test_channel.cc \
 
 
@@ -3181,7 +3219,6 @@ ifneq ($(OPENSSL_DEP),)
 test/cpp/util/messages.proto: $(OPENSSL_DEP)
 test/cpp/util/echo.proto: $(OPENSSL_DEP)
 test/cpp/util/echo_duplicate.proto: $(OPENSSL_DEP)
-test/cpp/end2end/async_test_server.cc: $(OPENSSL_DEP)
 test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
 endif
 
@@ -3210,7 +3247,6 @@ endif
 
 
 
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_test_server.o:     $(GENDIR)/test/cpp/util/messages.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o:     $(GENDIR)/test/cpp/util/messages.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
 
 
@@ -7281,6 +7317,37 @@ endif
 endif
 
 
+ASYNC_END2END_TEST_SRC = \
+    test/cpp/end2end/async_end2end_test.cc \
+
+ASYNC_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ASYNC_END2END_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/async_end2end_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/async_end2end_test: $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/async_end2end_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(ASYNC_END2END_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 CHANNEL_ARGUMENTS_TEST_SRC = \
     test/cpp/client/channel_arguments_test.cc \
 
@@ -7312,35 +7379,99 @@ endif
 endif
 
 
-CPP_PLUGIN_SRC = \
+GRPC_CPP_PLUGIN_SRC = \
     src/compiler/cpp_generator.cc \
     src/compiler/cpp_plugin.cc \
 
-CPP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CPP_PLUGIN_SRC))))
+GRPC_CPP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CPP_PLUGIN_SRC))))
 
 
 ifeq ($(NO_PROTOBUF),true)
 
 # You can't build the protoc plugins if you don't have protobuf 3.0.0+.
 
-$(BINDIR)/$(CONFIG)/cpp_plugin: protobuf_dep_error
+$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: protobuf_dep_error
 
 else
 
-$(BINDIR)/$(CONFIG)/cpp_plugin: $(PROTOBUF_DEP) $(CPP_PLUGIN_OBJS)
+$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: $(PROTOBUF_DEP) $(GRPC_CPP_PLUGIN_OBJS)
 	$(E) "[HOSTLD]  Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(CPP_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/cpp_plugin
+	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CPP_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
 
 endif
 
 $(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o: 
 $(OBJDIR)/$(CONFIG)/src/compiler/cpp_plugin.o: 
 
-deps_cpp_plugin: $(CPP_PLUGIN_OBJS:.o=.dep)
+deps_grpc_cpp_plugin: $(GRPC_CPP_PLUGIN_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_CPP_PLUGIN_OBJS:.o=.dep)
+endif
+
+
+GRPC_RUBY_PLUGIN_SRC = \
+    src/compiler/ruby_generator.cc \
+    src/compiler/ruby_plugin.cc \
+
+GRPC_RUBY_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_RUBY_PLUGIN_SRC))))
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: $(PROTOBUF_DEP) $(GRPC_RUBY_PLUGIN_OBJS)
+	$(E) "[HOSTLD]  Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_RUBY_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o: 
+$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o: 
+
+deps_grpc_ruby_plugin: $(GRPC_RUBY_PLUGIN_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_RUBY_PLUGIN_OBJS:.o=.dep)
+endif
+
+
+GRPC_PYTHON_PLUGIN_SRC = \
+    src/compiler/python_generator.cc \
+    src/compiler/python_plugin.cc \
+
+GRPC_PYTHON_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PYTHON_PLUGIN_SRC))))
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpc_python_plugin: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS)
+	$(E) "[HOSTLD]  Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: 
+$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o: 
+
+deps_grpc_python_plugin: $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep)
 
 ifneq ($(NO_DEPS),true)
--include $(CPP_PLUGIN_OBJS:.o=.dep)
+-include $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep)
 endif
 
 
@@ -7639,38 +7770,6 @@ endif
 endif
 
 
-RUBY_PLUGIN_SRC = \
-    src/compiler/ruby_generator.cc \
-    src/compiler/ruby_plugin.cc \
-
-RUBY_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RUBY_PLUGIN_SRC))))
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
-
-$(BINDIR)/$(CONFIG)/ruby_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/ruby_plugin: $(PROTOBUF_DEP) $(RUBY_PLUGIN_OBJS)
-	$(E) "[HOSTLD]  Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(RUBY_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/ruby_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o: 
-$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o: 
-
-deps_ruby_plugin: $(RUBY_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(RUBY_PLUGIN_OBJS:.o=.dep)
-endif
-
-
 STATUS_TEST_SRC = \
     test/cpp/util/status_test.cc \
 
@@ -7702,37 +7801,6 @@ endif
 endif
 
 
-SYNC_CLIENT_ASYNC_SERVER_TEST_SRC = \
-    test/cpp/end2end/sync_client_async_server_test.cc \
-
-SYNC_CLIENT_ASYNC_SERVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SYNC_CLIENT_ASYNC_SERVER_TEST_SRC))))
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/sync_client_async_server_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/sync_client_async_server_test: $(SYNC_CLIENT_ASYNC_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(SYNC_CLIENT_ASYNC_SERVER_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sync_client_async_server_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/sync_client_async_server_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_sync_client_async_server_test: $(SYNC_CLIENT_ASYNC_SERVER_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(SYNC_CLIENT_ASYNC_SERVER_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 THREAD_POOL_TEST_SRC = \
     test/cpp/server/thread_pool_test.cc \
 
diff --git a/README.md b/README.md
index 99e19db337b2a50c3698c9f332b87f7a83de51d3..1985176753626792605e39dfbfcaeac76444dccf 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,39 @@ Copyright 2015 Google Inc.
 
 See grpc/INSTALL for installation instructions for various platforms.
 
+#Repository Structure
+
+This repository contains source code for gRPC libraries for multiple lanugages written on top
+of shared C core library [src/core] (src/core).
+
+   * C++ source code: [src/cpp] (src/cpp)
+   * Python source code: [src/python] (src/python)
+   * Ruby source code: [src/ruby] (src/ruby)
+   * NodeJS source code: [src/node] (src/node)
+   * PHP source code: [src/php] (src/php)
+   * C# source code: [src/csharp] (src/csharp)
+   * Objective-C source code: [src/objective-c] (src/objective-c)
+   
+Java source code is in [grpc-java] (http://github.com/grpc/grpc-java) repository. 
+Go source code is in [grpc-go] (http://github.com/grpc/grpc-go) repository.
+
+#Documentation
+
+You can find more detailed documentation and examples in the [grpc-common repository](http://github.com/grpc/grpc-common).
+
+#Current Status of libraries
+
+Libraries in different languages are in different state of development. We are seeking contributions for all of these libraries.
+
+   * shared C core library [src/core] (src/core) : Early adopter ready - Alpha.
+   * C++ Library: [src/cpp] (src/cpp) : Early adopter ready - Alpha.
+   * Python Library: [src/python] (src/python) : Early adopter ready - Alpha.
+   * Ruby Library: [src/ruby] (src/ruby) : Early adopter ready - Alpha.
+   * NodeJS Library: [src/node] (src/node) : Early adopter ready - Alpha.
+   * PHP Library: [src/php] (src/php) : Pre-Alpha.
+   * C# Library: [src/csharp] (src/csharp) : Pre-Alpha.
+   * Objective-C Library: [src/objective-c] (src/objective-c): Pre-Alpha.
+
 #Overview
 
 
diff --git a/build.json b/build.json
index 610fa03a08eb1c7ec5b270224546e48198ab9df4..8fdca5a25507e4db560d6130ea08b5df4bd06a8d 100644
--- a/build.json
+++ b/build.json
@@ -239,7 +239,6 @@
         "include/grpc/support/useful.h"
       ],
       "headers": [
-        "src/core/support/cpu.h",
         "src/core/support/env.h",
         "src/core/support/file.h",
         "src/core/support/murmur_hash.h",
@@ -345,7 +344,7 @@
     {
       "name": "grpc_csharp_ext",
       "build": "all",
-      "language": "c",
+      "language": "csharp",
       "src": [
         "src/csharp/ext/grpc_csharp_ext.c"
       ],
@@ -398,8 +397,7 @@
       "build": "all",
       "language": "c++",
       "public_headers": [
-        "include/grpc++/async_server.h",
-        "include/grpc++/async_server_context.h",
+        "include/grpc++/async_unary_call.h",
         "include/grpc++/channel_arguments.h",
         "include/grpc++/channel_interface.h",
         "include/grpc++/client_context.h",
@@ -407,44 +405,44 @@
         "include/grpc++/config.h",
         "include/grpc++/create_channel.h",
         "include/grpc++/credentials.h",
+        "include/grpc++/impl/call.h",
+        "include/grpc++/impl/client_unary_call.h",
         "include/grpc++/impl/internal_stub.h",
         "include/grpc++/impl/rpc_method.h",
         "include/grpc++/impl/rpc_service_method.h",
+        "include/grpc++/impl/service_type.h",
         "include/grpc++/server.h",
         "include/grpc++/server_builder.h",
         "include/grpc++/server_context.h",
         "include/grpc++/server_credentials.h",
         "include/grpc++/status.h",
+        "include/grpc++/status_code_enum.h",
         "include/grpc++/stream.h",
-        "include/grpc++/stream_context_interface.h"
+        "include/grpc++/thread_pool_interface.h"
       ],
       "headers": [
         "src/cpp/client/channel.h",
         "src/cpp/proto/proto_utils.h",
-        "src/cpp/server/server_rpc_handler.h",
         "src/cpp/server/thread_pool.h",
-        "src/cpp/stream/stream_context.h",
         "src/cpp/util/time.h"
       ],
       "src": [
         "src/cpp/client/channel.cc",
         "src/cpp/client/channel_arguments.cc",
         "src/cpp/client/client_context.cc",
+        "src/cpp/client/client_unary_call.cc",
         "src/cpp/client/create_channel.cc",
         "src/cpp/client/credentials.cc",
         "src/cpp/client/internal_stub.cc",
+        "src/cpp/common/call.cc",
         "src/cpp/common/completion_queue.cc",
         "src/cpp/common/rpc_method.cc",
         "src/cpp/proto/proto_utils.cc",
-        "src/cpp/server/async_server.cc",
-        "src/cpp/server/async_server_context.cc",
         "src/cpp/server/server.cc",
         "src/cpp/server/server_builder.cc",
-        "src/cpp/server/server_context_impl.cc",
+        "src/cpp/server/server_context.cc",
         "src/cpp/server/server_credentials.cc",
-        "src/cpp/server/server_rpc_handler.cc",
         "src/cpp/server/thread_pool.cc",
-        "src/cpp/stream/stream_context.cc",
         "src/cpp/util/status.cc",
         "src/cpp/util/time.cc"
       ],
@@ -462,7 +460,6 @@
         "test/cpp/util/messages.proto",
         "test/cpp/util/echo.proto",
         "test/cpp/util/echo_duplicate.proto",
-        "test/cpp/end2end/async_test_server.cc",
         "test/cpp/util/create_test_channel.cc"
       ]
     },
@@ -1550,6 +1547,22 @@
         "gpr"
       ]
     },
+    {
+      "name": "async_end2end_test",
+      "build": "test",
+      "language": "c++",
+      "src": [
+        "test/cpp/end2end/async_end2end_test.cc"
+      ],
+      "deps": [
+        "grpc++_test_util",
+        "grpc_test_util",
+        "grpc++",
+        "grpc",
+        "gpr_test_util",
+        "gpr"
+      ]
+    },
     {
       "name": "channel_arguments_test",
       "build": "test",
@@ -1564,7 +1577,7 @@
       ]
     },
     {
-      "name": "cpp_plugin",
+      "name": "grpc_cpp_plugin",
       "build": "protoc",
       "language": "c++",
       "headers": [
@@ -1578,6 +1591,31 @@
       "deps": [],
       "secure": false
     },
+    {
+      "name": "grpc_ruby_plugin",
+      "build": "protoc",
+      "language": "c++",
+      "src": [
+        "src/compiler/ruby_generator.cc",
+        "src/compiler/ruby_plugin.cc"
+      ],
+      "deps": [],
+      "secure": false
+    },
+    {
+      "name": "grpc_python_plugin",
+      "build": "protoc",
+      "language": "c++",
+      "headers": [
+        "src/compiler/python_generator.h"
+      ],
+      "src": [
+        "src/compiler/python_generator.cc",
+        "src/compiler/python_plugin.cc"
+      ],
+      "deps": [],
+      "secure": false
+    },
     {
       "name": "credentials_test",
       "build": "test",
@@ -1735,23 +1773,6 @@
         "gpr"
       ]
     },
-    {
-      "name": "ruby_plugin",
-      "build": "protoc",
-      "language": "c++",
-      "headers": [
-        "src/compiler/cpp_generator.h",
-        "src/compiler/cpp_generator_helpers-inl.h",
-        "src/compiler/cpp_generator_map-inl.h",
-        "src/compiler/cpp_generator_string-inl.h"
-      ],
-      "src": [
-        "src/compiler/ruby_generator.cc",
-        "src/compiler/ruby_plugin.cc"
-      ],
-      "deps": [],
-      "secure": false
-    },
     {
       "name": "status_test",
       "build": "test",
@@ -1767,22 +1788,6 @@
         "gpr"
       ]
     },
-    {
-      "name": "sync_client_async_server_test",
-      "build": "test",
-      "language": "c++",
-      "src": [
-        "test/cpp/end2end/sync_client_async_server_test.cc"
-      ],
-      "deps": [
-        "grpc++_test_util",
-        "grpc_test_util",
-        "grpc++",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
     {
       "name": "thread_pool_test",
       "build": "test",
diff --git a/examples/pubsub/empty.proto b/examples/pubsub/empty.proto
index c34738fb4a79c022227d929fe81072c24a88c14d..5d6eb1084119fbf2c9c87803a307b47f24fc2665 100644
--- a/examples/pubsub/empty.proto
+++ b/examples/pubsub/empty.proto
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
diff --git a/examples/pubsub/label.proto b/examples/pubsub/label.proto
index 08350b8ba22b42f4ceb8c50507e6c3323cd4e304..0af15a25a610443eebbfbd6770ad3b5bf3534db6 100644
--- a/examples/pubsub/label.proto
+++ b/examples/pubsub/label.proto
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc
index 18c81c426dc744993f8e1ed83118ce2e7de47a4b..39fb8aea15c8cf5355bf841c5cdba410aede88ff 100644
--- a/examples/pubsub/main.cc
+++ b/examples/pubsub/main.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@
 
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
-#include <google/gflags.h>
+#include <gflags/gflags.h>
 #include <grpc++/channel_interface.h>
 #include <grpc++/create_channel.h>
 #include <grpc++/credentials.h>
@@ -60,6 +60,13 @@ DEFINE_string(oauth_scope,
               "https://www.googleapis.com/auth/cloud-platform",
               "Scope for OAuth tokens.");
 
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google { }
+namespace gflags { }
+using namespace google;
+using namespace gflags;
+
 namespace {
 
 const char kTopic[] = "testtopics";
@@ -81,7 +88,7 @@ grpc::string GetServiceAccountJsonKey() {
 
 int main(int argc, char** argv) {
   grpc_init();
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  ParseCommandLineFlags(&argc, &argv, true);
   gpr_log(GPR_INFO, "Start PUBSUB client");
 
   std::ostringstream ss;
diff --git a/examples/pubsub/publisher.cc b/examples/pubsub/publisher.cc
index cdefd08662e27c4155bd33a4c4321595162e65e4..308f9a77e5715a8f35fa5150ac0f6d6137840041 100644
--- a/examples/pubsub/publisher.cc
+++ b/examples/pubsub/publisher.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h
index 8eb666aea5437c48483be43a427f44b39d3f4be7..2d64a2abfa3d572e85e735c959df9dcef246c0ec 100644
--- a/examples/pubsub/publisher.h
+++ b/examples/pubsub/publisher.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc
index 298a5a2703b43af019d0eaa803134244ed28a750..b7bea5b1bd25e12da37f65a10a85f0a71cc07c13 100644
--- a/examples/pubsub/publisher_test.cc
+++ b/examples/pubsub/publisher_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -107,7 +107,7 @@ class PublisherTest : public ::testing::Test {
     server_address_ << "localhost:" << port;
     ServerBuilder builder;
     builder.AddPort(server_address_.str());
-    builder.RegisterService(service_.service());
+    builder.RegisterService(&service_);
     server_ = builder.BuildAndStart();
 
     channel_ = CreateChannel(server_address_.str(), ChannelArguments());
@@ -138,7 +138,7 @@ TEST_F(PublisherTest, TestPublisher) {
 
   std::vector<grpc::string> topics;
   EXPECT_TRUE(publisher_->ListTopics(kProjectId, &topics).IsOk());
-  EXPECT_EQ(topics.size(), 1);
+  EXPECT_EQ(topics.size(), static_cast<size_t>(1));
   EXPECT_EQ(topics[0], kTopic);
 }
 
diff --git a/examples/pubsub/pubsub.proto b/examples/pubsub/pubsub.proto
index 793cdae9e6f08d2cd0648094d6ca42744949c8c2..ac896933201b553ed9992db76757a8b27b5532b0 100644
--- a/examples/pubsub/pubsub.proto
+++ b/examples/pubsub/pubsub.proto
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
diff --git a/examples/pubsub/subscriber.cc b/examples/pubsub/subscriber.cc
index 18ce0721f67096fd832f4e129ec5d6a9a54eb545..29f6635b7c9221baf8367973c5f23ad81d986fae 100644
--- a/examples/pubsub/subscriber.cc
+++ b/examples/pubsub/subscriber.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h
index e5f036f89f9f54deba3d3e9b04f02db91e0436eb..a973cd755c7539a4c91f325ecfbe9bb52f245f4e 100644
--- a/examples/pubsub/subscriber.h
+++ b/examples/pubsub/subscriber.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc
index 65a9af394a3cc908be18973446d3c345c5c2f31f..1fdcc8f755f435978fe2b77aac087172d50808b3 100644
--- a/examples/pubsub/subscriber_test.cc
+++ b/examples/pubsub/subscriber_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -106,7 +106,7 @@ class SubscriberTest : public ::testing::Test {
     server_address_ << "localhost:" << port;
     ServerBuilder builder;
     builder.AddPort(server_address_.str());
-    builder.RegisterService(service_.service());
+    builder.RegisterService(&service_);
     server_ = builder.BuildAndStart();
 
     channel_ = CreateChannel(server_address_.str(), ChannelArguments());
diff --git a/include/grpc++/async_server_context.h b/include/grpc++/async_server_context.h
deleted file mode 100644
index c038286ac136e58584b8bd28f9eb65209097e4aa..0000000000000000000000000000000000000000
--- a/include/grpc++/async_server_context.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *
- * Copyright 2014, 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 __GRPCPP_ASYNC_SERVER_CONTEXT_H__
-#define __GRPCPP_ASYNC_SERVER_CONTEXT_H__
-
-#include <chrono>
-
-#include <grpc++/config.h>
-
-struct grpc_byte_buffer;
-struct grpc_call;
-struct grpc_completion_queue;
-
-namespace google {
-namespace protobuf {
-class Message;
-}
-}
-
-using std::chrono::system_clock;
-
-namespace grpc {
-class Status;
-
-// TODO(rocking): wrap grpc c structures.
-class AsyncServerContext {
- public:
-  AsyncServerContext(grpc_call* call, const grpc::string& method,
-                     const grpc::string& host,
-                     system_clock::time_point absolute_deadline);
-  ~AsyncServerContext();
-
-  // Accept this rpc, bind it to a completion queue.
-  void Accept(grpc_completion_queue* cq);
-
-  // Read and write calls, all async. Return true for success.
-  bool StartRead(google::protobuf::Message* request);
-  bool StartWrite(const google::protobuf::Message& response, int flags);
-  bool StartWriteStatus(const Status& status);
-
-  bool ParseRead(grpc_byte_buffer* read_buffer);
-
-  grpc::string method() const { return method_; }
-  grpc::string host() const { return host_; }
-  system_clock::time_point absolute_deadline() { return absolute_deadline_; }
-
-  grpc_call* call() { return call_; }
-
- private:
-  AsyncServerContext(const AsyncServerContext&);
-  AsyncServerContext& operator=(const AsyncServerContext&);
-
-  // These properties may be moved to a ServerContext class.
-  const grpc::string method_;
-  const grpc::string host_;
-  system_clock::time_point absolute_deadline_;
-
-  google::protobuf::Message* request_;  // not owned
-  grpc_call* call_;                     // owned
-};
-
-}  // namespace grpc
-
-#endif  // __GRPCPP_ASYNC_SERVER_CONTEXT_H__
diff --git a/include/grpc++/async_unary_call.h b/include/grpc++/async_unary_call.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4a654c4a9886df289c4e257c1d319a69b2f3e27
--- /dev/null
+++ b/include/grpc++/async_unary_call.h
@@ -0,0 +1,140 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_ASYNC_UNARY_CALL_H__
+#define __GRPCPP_ASYNC_UNARY_CALL_H__
+
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/completion_queue.h>
+#include <grpc++/server_context.h>
+#include <grpc++/impl/call.h>
+#include <grpc++/impl/service_type.h>
+#include <grpc++/status.h>
+#include <grpc/support/log.h>
+
+namespace grpc {
+template <class R>
+class ClientAsyncResponseReader final {
+ public:
+  ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
+                    const RpcMethod& method, ClientContext* context,
+                    const google::protobuf::Message& request, void* tag)
+      : context_(context),
+        call_(channel->CreateCall(method, context, cq)) {
+    init_buf_.Reset(tag);
+    init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_);
+    init_buf_.AddSendMessage(request);
+    init_buf_.AddClientSendClose();
+    call_.PerformOps(&init_buf_);
+  }
+
+  void ReadInitialMetadata(void* tag) {
+    GPR_ASSERT(!context_->initial_metadata_received_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddRecvInitialMetadata(context_);
+    call_.PerformOps(&meta_buf_);
+  }
+
+  void Finish(R* msg, Status* status, void* tag) {
+    finish_buf_.Reset(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_buf_.AddRecvInitialMetadata(context_);
+    }
+    finish_buf_.AddRecvMessage(msg);
+    finish_buf_.AddClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_buf_);
+  }
+
+
+ private:
+  ClientContext* context_ = nullptr;
+  Call call_;
+  CallOpBuffer init_buf_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer finish_buf_;
+};
+
+template <class W>
+class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface {
+ public:
+  explicit ServerAsyncResponseWriter(ServerContext* ctx)
+      : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+  void SendInitialMetadata(void* tag) {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_buf_);
+  }
+
+  void Finish(const W& msg, const Status& status, void* tag) {
+    finish_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    // The response is dropped if the status is not OK.
+    if (status.IsOk()) {
+      finish_buf_.AddSendMessage(msg);
+    }
+    finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_buf_);
+  }
+
+  void FinishWithError(const Status& status, void* tag) {
+    GPR_ASSERT(!status.IsOk());
+    finish_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_buf_);
+  }
+
+ private:
+  void BindCall(Call* call) override { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer finish_buf_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_ASYNC_UNARY_CALL_H__
diff --git a/include/grpc++/channel_arguments.h b/include/grpc++/channel_arguments.h
index e4881b782872fe96c232369e3310111ccee798e2..75c3cf45b49add73f05f3d2c55770aa999c42626 100644
--- a/include/grpc++/channel_arguments.h
+++ b/include/grpc++/channel_arguments.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/channel_interface.h b/include/grpc++/channel_interface.h
index 9ed35422b85fe5155dac7212b0b8d271c24f49aa..890fd04d82448b2d8e0c7bb8911c30e6c1d2a7cd 100644
--- a/include/grpc++/channel_interface.h
+++ b/include/grpc++/channel_interface.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,32 +35,30 @@
 #define __GRPCPP_CHANNEL_INTERFACE_H__
 
 #include <grpc++/status.h>
+#include <grpc++/impl/call.h>
 
 namespace google {
 namespace protobuf {
 class Message;
-}
-}
+}  // namespace protobuf
+}  // namespace google
 
-namespace grpc {
+struct grpc_call;
 
+namespace grpc {
+class Call;
+class CallOpBuffer;
 class ClientContext;
+class CompletionQueue;
 class RpcMethod;
-class StreamContextInterface;
+class CallInterface;
 
-class ChannelInterface {
+class ChannelInterface : public CallHook {
  public:
   virtual ~ChannelInterface() {}
 
-  virtual Status StartBlockingRpc(const RpcMethod& method,
-                                  ClientContext* context,
-                                  const google::protobuf::Message& request,
-                                  google::protobuf::Message* result) = 0;
-
-  virtual StreamContextInterface* CreateStream(
-      const RpcMethod& method, ClientContext* context,
-      const google::protobuf::Message* request,
-      google::protobuf::Message* result) = 0;
+  virtual Call CreateCall(const RpcMethod &method, ClientContext *context,
+                          CompletionQueue *cq) = 0;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 0cf6bdc647e7e8c48ff2faf723e5100a8bc1a5f6..1e7e6bfad7c5119cdf3793b0be8058bd75424498 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,8 +35,8 @@
 #define __GRPCPP_CLIENT_CONTEXT_H__
 
 #include <chrono>
+#include <map>
 #include <string>
-#include <vector>
 
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
@@ -47,8 +47,34 @@ using std::chrono::system_clock;
 struct grpc_call;
 struct grpc_completion_queue;
 
+namespace google {
+namespace protobuf {
+class Message;
+}  // namespace protobuf
+}  // namespace google
+
 namespace grpc {
 
+class CallOpBuffer;
+class ChannelInterface;
+class CompletionQueue;
+class RpcMethod;
+class Status;
+template <class R>
+class ClientReader;
+template <class W>
+class ClientWriter;
+template <class R, class W>
+class ClientReaderWriter;
+template <class R>
+class ClientAsyncReader;
+template <class W>
+class ClientAsyncWriter;
+template <class R, class W>
+class ClientAsyncReaderWriter;
+template <class R>
+class ClientAsyncResponseReader;
+
 class ClientContext {
  public:
   ClientContext();
@@ -57,18 +83,46 @@ class ClientContext {
   void AddMetadata(const grpc::string &meta_key,
                    const grpc::string &meta_value);
 
+  const std::multimap<grpc::string, grpc::string>& GetServerInitialMetadata() {
+    GPR_ASSERT(initial_metadata_received_);
+    return recv_initial_metadata_;
+  }
+
+  const std::multimap<grpc::string, grpc::string>& GetServerTrailingMetadata() {
+    // TODO(yangg) check finished
+    return trailing_metadata_;
+  }
+
   void set_absolute_deadline(const system_clock::time_point &deadline);
   system_clock::time_point absolute_deadline();
 
-  void StartCancel();
+  void set_authority(const grpc::string& authority) {
+    authority_ = authority;
+  }
+
+  void TryCancel();
 
  private:
   // Disallow copy and assign.
   ClientContext(const ClientContext &);
   ClientContext &operator=(const ClientContext &);
 
+  friend class CallOpBuffer;
   friend class Channel;
-  friend class StreamContext;
+  template <class R>
+  friend class ::grpc::ClientReader;
+  template <class W>
+  friend class ::grpc::ClientWriter;
+  template <class R, class W>
+  friend class ::grpc::ClientReaderWriter;
+  template <class R>
+  friend class ::grpc::ClientAsyncReader;
+  template <class W>
+  friend class ::grpc::ClientAsyncWriter;
+  template <class R, class W>
+  friend class ::grpc::ClientAsyncReaderWriter;
+  template <class R>
+  friend class ::grpc::ClientAsyncResponseReader;
 
   grpc_call *call() { return call_; }
   void set_call(grpc_call *call) {
@@ -81,10 +135,18 @@ class ClientContext {
 
   gpr_timespec RawDeadline() { return absolute_deadline_; }
 
+  grpc::string authority() {
+    return authority_;
+  }
+
+  bool initial_metadata_received_ = false;
   grpc_call *call_;
   grpc_completion_queue *cq_;
   gpr_timespec absolute_deadline_;
-  std::vector<std::pair<grpc::string, grpc::string> > metadata_;
+  grpc::string authority_;
+  std::multimap<grpc::string, grpc::string> send_initial_metadata_;
+  std::multimap<grpc::string, grpc::string> recv_initial_metadata_;
+  std::multimap<grpc::string, grpc::string> trailing_metadata_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index 72f6253f8e8eea423187a12270880028331a1794..0075482d71799cc79d9b39f419890440123b179a 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,52 +34,89 @@
 #ifndef __GRPCPP_COMPLETION_QUEUE_H__
 #define __GRPCPP_COMPLETION_QUEUE_H__
 
+#include <grpc++/impl/client_unary_call.h>
+
 struct grpc_completion_queue;
 
 namespace grpc {
 
+template <class R>
+class ClientReader;
+template <class W>
+class ClientWriter;
+template <class R, class W>
+class ClientReaderWriter;
+template <class R>
+class ServerReader;
+template <class W>
+class ServerWriter;
+template <class R, class W>
+class ServerReaderWriter;
+
+class CompletionQueue;
+class Server;
+class ServerContext;
+
+class CompletionQueueTag {
+ public:
+  virtual ~CompletionQueueTag() {}
+  // Called prior to returning from Next(), return value
+  // is the status of the operation (return status is the default thing
+  // to do)
+  // If this function returns false, the tag is dropped and not returned
+  // from the completion queue
+  virtual bool FinalizeResult(void **tag, bool *status) = 0;
+};
+
 // grpc_completion_queue wrapper class
 class CompletionQueue {
  public:
   CompletionQueue();
+  explicit CompletionQueue(grpc_completion_queue *take);
   ~CompletionQueue();
 
-  enum CompletionType {
-    QUEUE_CLOSED = 0,       // Shutting down.
-    RPC_END = 1,            // An RPC finished. Either at client or server.
-    CLIENT_READ_OK = 2,     // A client-side read has finished successfully.
-    CLIENT_READ_ERROR = 3,  // A client-side read has finished with error.
-    CLIENT_WRITE_OK = 4,
-    CLIENT_WRITE_ERROR = 5,
-    SERVER_RPC_NEW = 6,     // A new RPC just arrived at the server.
-    SERVER_READ_OK = 7,     // A server-side read has finished successfully.
-    SERVER_READ_ERROR = 8,  // A server-side read has finished with error.
-    SERVER_WRITE_OK = 9,
-    SERVER_WRITE_ERROR = 10,
-    // Client or server has sent half close successfully.
-    HALFCLOSE_OK = 11,
-    // New CompletionTypes may be added in the future, so user code should
-    // always
-    // handle the default case of a CompletionType that appears after such code
-    // was
-    // written.
-    DO_NOT_USE = 20,
-  };
-
   // Blocking read from queue.
-  // For QUEUE_CLOSED, *tag is not changed.
-  // For SERVER_RPC_NEW, *tag will be a newly allocated AsyncServerContext.
-  // For others, *tag will be the AsyncServerContext of this rpc.
-  CompletionType Next(void** tag);
+  // Returns true if an event was received, false if the queue is ready
+  // for destruction.
+  bool Next(void **tag, bool *ok);
 
   // Shutdown has to be called, and the CompletionQueue can only be
-  // destructed when the QUEUE_CLOSED message has been read with Next().
+  // destructed when false is returned from Next().
   void Shutdown();
 
-  grpc_completion_queue* cq() { return cq_; }
+  grpc_completion_queue *cq() { return cq_; }
 
  private:
-  grpc_completion_queue* cq_;  // owned
+  // Friend synchronous wrappers so that they can access Pluck(), which is
+  // a semi-private API geared towards the synchronous implementation.
+  template <class R>
+  friend class ::grpc::ClientReader;
+  template <class W>
+  friend class ::grpc::ClientWriter;
+  template <class R, class W>
+  friend class ::grpc::ClientReaderWriter;
+  template <class R>
+  friend class ::grpc::ServerReader;
+  template <class W>
+  friend class ::grpc::ServerWriter;
+  template <class R, class W>
+  friend class ::grpc::ServerReaderWriter;
+  friend class ::grpc::Server;
+  friend class ::grpc::ServerContext;
+  friend Status BlockingUnaryCall(ChannelInterface *channel,
+                                  const RpcMethod &method,
+                                  ClientContext *context,
+                                  const google::protobuf::Message &request,
+                                  google::protobuf::Message *result);
+
+  // Wraps grpc_completion_queue_pluck.
+  // Cannot be mixed with calls to Next().
+  bool Pluck(CompletionQueueTag *tag);
+
+  // Does a single polling pluck on tag
+  void TryPluck(CompletionQueueTag *tag);
+
+  grpc_completion_queue *cq_;  // owned
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/config.h b/include/grpc++/config.h
index 52913fbf0f9b607c538dec63ee969a77873c2cee..2dced12e37908578d64c0ce191f6de45b38e9cb5 100644
--- a/include/grpc++/config.h
+++ b/include/grpc++/config.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
 namespace grpc {
 
 typedef std::string string;
-}
+
+}  // namespace grpc
 
 #endif  // __GRPCPP_CONFIG_H__
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index a8ce8b8ec845458bbace90e62c46d41167b42bf7..eadabda3596638c9cc253bc4ee9be742d10f9124 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h
index 52304d7f369cd7a62ad8b2c6b7ddda6668ad4a45..ac6f394847d06ab0eded9b97314cc3a02431f706 100644
--- a/include/grpc++/credentials.h
+++ b/include/grpc++/credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
new file mode 100644
index 0000000000000000000000000000000000000000..341710f7a2e57b7e6a76b7b0c7d01b274dd5901b
--- /dev/null
+++ b/include/grpc++/impl/call.h
@@ -0,0 +1,145 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_CALL_H__
+#define __GRPCPP_CALL_H__
+
+#include <grpc/grpc.h>
+#include <grpc++/status.h>
+#include <grpc++/completion_queue.h>
+
+#include <memory>
+#include <map>
+
+namespace google {
+namespace protobuf {
+class Message;
+}  // namespace protobuf
+}  // namespace google
+
+struct grpc_call;
+struct grpc_op;
+
+namespace grpc {
+
+class Call;
+
+class CallOpBuffer : public CompletionQueueTag {
+ public:
+  CallOpBuffer() : return_tag_(this) {}
+  ~CallOpBuffer();
+
+  void Reset(void *next_return_tag);
+
+  // Does not take ownership.
+  void AddSendInitialMetadata(
+      std::multimap<grpc::string, grpc::string> *metadata);
+  void AddSendInitialMetadata(ClientContext *ctx);
+  void AddRecvInitialMetadata(ClientContext *ctx);
+  void AddSendMessage(const google::protobuf::Message &message);
+  void AddRecvMessage(google::protobuf::Message *message);
+  void AddClientSendClose();
+  void AddClientRecvStatus(ClientContext *ctx, Status *status);
+  void AddServerSendStatus(std::multimap<grpc::string, grpc::string> *metadata,
+                           const Status &status);
+  void AddServerRecvClose(bool *cancelled);
+
+  // INTERNAL API:
+
+  // Convert to an array of grpc_op elements
+  void FillOps(grpc_op *ops, size_t *nops);
+
+  // Called by completion queue just prior to returning from Next() or Pluck()
+  bool FinalizeResult(void **tag, bool *status) override;
+
+  bool got_message = false;
+
+ private:
+  void *return_tag_ = nullptr;
+  // Send initial metadata
+  bool send_initial_metadata_ = false;
+  size_t initial_metadata_count_ = 0;
+  grpc_metadata *initial_metadata_ = nullptr;
+  // Recv initial metadta
+  std::multimap<grpc::string, grpc::string> *recv_initial_metadata_ = nullptr;
+  grpc_metadata_array recv_initial_metadata_arr_ = {0, 0, nullptr};
+  // Send message
+  const google::protobuf::Message *send_message_ = nullptr;
+  grpc_byte_buffer *send_message_buf_ = nullptr;
+  // Recv message
+  google::protobuf::Message *recv_message_ = nullptr;
+  grpc_byte_buffer *recv_message_buf_ = nullptr;
+  // Client send close
+  bool client_send_close_ = false;
+  // Client recv status
+  std::multimap<grpc::string, grpc::string> *recv_trailing_metadata_ = nullptr;
+  Status *recv_status_ = nullptr;
+  grpc_metadata_array recv_trailing_metadata_arr_ = {0, 0, nullptr};
+  grpc_status_code status_code_ = GRPC_STATUS_OK;
+  char *status_details_ = nullptr;
+  size_t status_details_capacity_ = 0;
+  // Server send status
+  const Status *send_status_ = nullptr;
+  size_t trailing_metadata_count_ = 0;
+  grpc_metadata *trailing_metadata_ = nullptr;
+  int cancelled_buf_;
+  bool *recv_closed_ = nullptr;
+};
+
+// Channel and Server implement this to allow them to hook performing ops
+class CallHook {
+ public:
+  virtual ~CallHook() {}
+  virtual void PerformOpsOnCall(CallOpBuffer *ops, Call *call) = 0;
+};
+
+// Straightforward wrapping of the C call object
+class Call final {
+ public:
+  /* call is owned by the caller */
+  Call(grpc_call *call, CallHook *call_hook_, CompletionQueue *cq);
+
+  void PerformOps(CallOpBuffer *buffer);
+
+  grpc_call *call() { return call_; }
+  CompletionQueue *cq() { return cq_; }
+
+ private:
+  CallHook *call_hook_;
+  CompletionQueue *cq_;
+  grpc_call *call_;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_CALL_INTERFACE_H__
diff --git a/include/grpc++/async_server.h b/include/grpc++/impl/client_unary_call.h
similarity index 72%
rename from include/grpc++/async_server.h
rename to include/grpc++/impl/client_unary_call.h
index fe2c5d936782b474f62489ec9d07e98c7bfe5538..f25ded7a249f89ec8f08585ccccf528ee934f167 100644
--- a/include/grpc++/async_server.h
+++ b/include/grpc++/impl/client_unary_call.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,40 +31,29 @@
  *
  */
 
-#ifndef __GRPCPP_ASYNC_SERVER_H__
-#define __GRPCPP_ASYNC_SERVER_H__
+#ifndef __GRPCPP_CLIENT_UNARY_CALL_H__
+#define __GRPCPP_CLIENT_UNARY_CALL_H__
 
-#include <mutex>
-
-#include <grpc++/config.h>
-
-struct grpc_server;
+namespace google {
+namespace protobuf {
+class Message;
+}  // namespace protobuf
+}  // namespace google
 
 namespace grpc {
-class CompletionQueue;
-
-class AsyncServer {
- public:
-  explicit AsyncServer(CompletionQueue* cc);
-  ~AsyncServer();
 
-  void AddPort(const grpc::string& addr);
-
-  void Start();
-
-  // The user has to call this to get one new rpc on the completion
-  // queue.
-  void RequestOneRpc();
-
-  void Shutdown();
+class ChannelInterface;
+class ClientContext;
+class CompletionQueue;
+class RpcMethod;
+class Status;
 
- private:
-  bool started_;
-  std::mutex shutdown_mu_;
-  bool shutdown_;
-  grpc_server* server_;
-};
+// Wrapper that performs a blocking unary call
+Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method,
+                         ClientContext *context,
+                         const google::protobuf::Message &request,
+                         google::protobuf::Message *result);
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_ASYNC_SERVER_H__
+#endif
diff --git a/include/grpc++/impl/internal_stub.h b/include/grpc++/impl/internal_stub.h
index b32fb3a27c00cce6611121400833460b6b8c97af..25290121cdfad6d076fc85c18d2ef3628d900e2e 100644
--- a/include/grpc++/impl/internal_stub.h
+++ b/include/grpc++/impl/internal_stub.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/impl/rpc_method.h b/include/grpc++/impl/rpc_method.h
index 75fec356dd47dd0645ea472f741e856f6c47bd7f..0236b1182a078a9656f213a06c80cd587f6e62a6 100644
--- a/include/grpc++/impl/rpc_method.h
+++ b/include/grpc++/impl/rpc_method.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,8 @@
 namespace google {
 namespace protobuf {
 class Message;
-}
-}
+}  // namespace protobuf
+}  // namespace google
 
 namespace grpc {
 
diff --git a/include/grpc++/impl/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h
index 620de5e67fb469f6a067b3ab7359f839b823036d..ffd5c34ef6dfffe7ed405ec30a41eaefa0fc269a 100644
--- a/include/grpc++/impl/rpc_service_method.h
+++ b/include/grpc++/impl/rpc_service_method.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,25 +55,14 @@ class MethodHandler {
  public:
   virtual ~MethodHandler() {}
   struct HandlerParameter {
-    HandlerParameter(ServerContext* context,
+    HandlerParameter(Call* c, ServerContext* context,
                      const google::protobuf::Message* req,
                      google::protobuf::Message* resp)
-        : server_context(context),
-          request(req),
-          response(resp),
-          stream_context(nullptr) {}
-    HandlerParameter(ServerContext* context,
-                     const google::protobuf::Message* req,
-                     google::protobuf::Message* resp,
-                     StreamContextInterface* stream)
-        : server_context(context),
-          request(req),
-          response(resp),
-          stream_context(stream) {}
+        : call(c), server_context(context), request(req), response(resp) {}
+    Call* call;
     ServerContext* server_context;
     const google::protobuf::Message* request;
     google::protobuf::Message* response;
-    StreamContextInterface* stream_context;
   };
   virtual Status RunHandler(const HandlerParameter& param) = 0;
 };
@@ -114,7 +103,7 @@ class ClientStreamingHandler : public MethodHandler {
       : func_(func), service_(service) {}
 
   Status RunHandler(const HandlerParameter& param) final {
-    ServerReader<RequestType> reader(param.stream_context);
+    ServerReader<RequestType> reader(param.call, param.server_context);
     return func_(service_, param.server_context, &reader,
                  dynamic_cast<ResponseType*>(param.response));
   }
@@ -136,7 +125,7 @@ class ServerStreamingHandler : public MethodHandler {
       : func_(func), service_(service) {}
 
   Status RunHandler(const HandlerParameter& param) final {
-    ServerWriter<ResponseType> writer(param.stream_context);
+    ServerWriter<ResponseType> writer(param.call, param.server_context);
     return func_(service_, param.server_context,
                  dynamic_cast<const RequestType*>(param.request), &writer);
   }
@@ -159,7 +148,8 @@ class BidiStreamingHandler : public MethodHandler {
       : func_(func), service_(service) {}
 
   Status RunHandler(const HandlerParameter& param) final {
-    ServerReaderWriter<ResponseType, RequestType> stream(param.stream_context);
+    ServerReaderWriter<ResponseType, RequestType> stream(param.call,
+                                                         param.server_context);
     return func_(service_, param.server_context, &stream);
   }
 
@@ -202,9 +192,7 @@ class RpcServiceMethod : public RpcMethod {
 class RpcService {
  public:
   // Takes ownership.
-  void AddMethod(RpcServiceMethod* method) {
-    methods_.push_back(std::unique_ptr<RpcServiceMethod>(method));
-  }
+  void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
 
   RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
   int GetMethodCount() const { return methods_.size(); }
diff --git a/include/grpc++/impl/service_type.h b/include/grpc++/impl/service_type.h
new file mode 100644
index 0000000000000000000000000000000000000000..cafa2696ab219fda21c5a1bafc277bbd9d2b5848
--- /dev/null
+++ b/include/grpc++/impl/service_type.h
@@ -0,0 +1,127 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPCPP_IMPL_SERVICE_TYPE_H__
+#define __GRPCPP_IMPL_SERVICE_TYPE_H__
+
+namespace google {
+namespace protobuf {
+class Message;
+}  // namespace protobuf
+}  // namespace google
+
+namespace grpc {
+
+class Call;
+class RpcService;
+class Server;
+class ServerContext;
+class Status;
+
+class SynchronousService {
+ public:
+  virtual ~SynchronousService() {}
+  virtual RpcService* service() = 0;
+};
+
+class ServerAsyncStreamingInterface {
+ public:
+  virtual ~ServerAsyncStreamingInterface() {}
+
+  virtual void SendInitialMetadata(void* tag) = 0;
+
+ private:
+  friend class Server;
+  virtual void BindCall(Call* call) = 0;
+};
+
+class AsynchronousService {
+ public:
+  // this is Server, but in disguise to avoid a link dependency
+  class DispatchImpl {
+   public:
+    virtual void RequestAsyncCall(void* registered_method,
+                                  ServerContext* context,
+                                  ::google::protobuf::Message* request,
+                                  ServerAsyncStreamingInterface* stream,
+                                  CompletionQueue* cq, void* tag) = 0;
+  };
+
+  AsynchronousService(CompletionQueue* cq, const char** method_names,
+                      size_t method_count)
+      : cq_(cq), method_names_(method_names), method_count_(method_count) {}
+
+  ~AsynchronousService() { delete[] request_args_; }
+
+  CompletionQueue* completion_queue() const { return cq_; }
+
+ protected:
+  void RequestAsyncUnary(int index, ServerContext* context,
+                         ::google::protobuf::Message* request,
+                         ServerAsyncStreamingInterface* stream,
+                         CompletionQueue* cq, void* tag) {
+    dispatch_impl_->RequestAsyncCall(request_args_[index], context, request,
+                                     stream, cq, tag);
+  }
+  void RequestClientStreaming(int index, ServerContext* context,
+                              ServerAsyncStreamingInterface* stream,
+                              CompletionQueue* cq, void* tag) {
+    dispatch_impl_->RequestAsyncCall(request_args_[index], context, nullptr,
+                                     stream, cq, tag);
+  }
+  void RequestServerStreaming(int index, ServerContext* context,
+                              ::google::protobuf::Message* request,
+                              ServerAsyncStreamingInterface* stream,
+                              CompletionQueue* cq, void* tag) {
+    dispatch_impl_->RequestAsyncCall(request_args_[index], context, request,
+                                     stream, cq, tag);
+  }
+  void RequestBidiStreaming(int index, ServerContext* context,
+                            ServerAsyncStreamingInterface* stream,
+                            CompletionQueue* cq, void* tag) {
+    dispatch_impl_->RequestAsyncCall(request_args_[index], context, nullptr,
+                                     stream, cq, tag);
+  }
+
+ private:
+  friend class Server;
+  CompletionQueue* const cq_;
+  DispatchImpl* dispatch_impl_ = nullptr;
+  const char** const method_names_;
+  size_t method_count_;
+  void** request_args_ = nullptr;
+};
+
+}  // namespace grpc
+
+#endif  // __GRPCPP_IMPL_SERVICE_TYPE_H__
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 5fa371ba626ccd0f87c3630d7d73f20de76fd8cc..26d18d1bbe4be0c49600d1268eeb2c2d323e6646 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,12 +35,14 @@
 #define __GRPCPP_SERVER_H__
 
 #include <condition_variable>
-#include <map>
+#include <list>
 #include <memory>
 #include <mutex>
 
 #include <grpc++/completion_queue.h>
 #include <grpc++/config.h>
+#include <grpc++/impl/call.h>
+#include <grpc++/impl/service_type.h>
 #include <grpc++/status.h>
 
 struct grpc_server;
@@ -48,18 +50,19 @@ struct grpc_server;
 namespace google {
 namespace protobuf {
 class Message;
-}
-}
+}  // namespace protobuf
+}  // namespace google
 
 namespace grpc {
-class AsyncServerContext;
+class AsynchronousService;
 class RpcService;
 class RpcServiceMethod;
 class ServerCredentials;
 class ThreadPoolInterface;
 
 // Currently it only supports handling rpcs in a single thread.
-class Server {
+class Server final : private CallHook,
+                     private AsynchronousService::DispatchImpl {
  public:
   ~Server();
 
@@ -69,22 +72,34 @@ class Server {
  private:
   friend class ServerBuilder;
 
+  class SyncRequest;
+  class AsyncRequest;
+
   // ServerBuilder use only
-  Server(ThreadPoolInterface* thread_pool, ServerCredentials* creds);
+  Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
+         ServerCredentials* creds);
   Server();
   // Register a service. This call does not take ownership of the service.
   // The service must exist for the lifetime of the Server instance.
-  void RegisterService(RpcService* service);
+  bool RegisterService(RpcService* service);
+  bool RegisterAsyncService(AsynchronousService* service);
   // Add a listening port. Can be called multiple times.
-  void AddPort(const grpc::string& addr);
+  int AddPort(const grpc::string& addr);
   // Start the server.
-  void Start();
+  bool Start();
 
-  void AllowOneRpc();
   void HandleQueueClosed();
   void RunRpc();
   void ScheduleCallback();
 
+  void PerformOpsOnCall(CallOpBuffer* ops, Call* call) override;
+
+  // DispatchImpl
+  void RequestAsyncCall(void* registered_method, ServerContext* context,
+                        ::google::protobuf::Message* request,
+                        ServerAsyncStreamingInterface* stream,
+                        CompletionQueue* cq, void* tag);
+
   // Completion queue.
   CompletionQueue cq_;
 
@@ -96,12 +111,11 @@ class Server {
   int num_running_cb_;
   std::condition_variable callback_cv_;
 
+  std::list<SyncRequest> sync_methods_;
+
   // Pointer to the c grpc server.
   grpc_server* server_;
 
-  // A map for all method information.
-  std::map<grpc::string, RpcServiceMethod*> method_map_;
-
   ThreadPoolInterface* thread_pool_;
   // Whether the thread pool is created and owned by the server.
   bool thread_pool_owned_;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index cf274520107a49b1298e3febcd6b16e8a74a7466..4545c413d25f1d07e7dc09daabd1438c995c1f5d 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,9 +41,12 @@
 
 namespace grpc {
 
+class AsynchronousService;
+class CompletionQueue;
 class RpcService;
 class Server;
 class ServerCredentials;
+class SynchronousService;
 class ThreadPoolInterface;
 
 class ServerBuilder {
@@ -53,7 +56,13 @@ class ServerBuilder {
   // Register a service. This call does not take ownership of the service.
   // The service must exist for the lifetime of the Server instance returned by
   // BuildAndStart().
-  void RegisterService(RpcService* service);
+  void RegisterService(SynchronousService* service);
+
+  // Register an asynchronous service. New calls will be delevered to cq.
+  // This call does not take ownership of the service or completion queue.
+  // The service and completion queuemust exist for the lifetime of the Server
+  // instance returned by BuildAndStart().
+  void RegisterAsyncService(AsynchronousService* service);
 
   // Add a listening port. Can be called multiple times.
   void AddPort(const grpc::string& addr);
@@ -71,9 +80,10 @@ class ServerBuilder {
 
  private:
   std::vector<RpcService*> services_;
+  std::vector<AsynchronousService*> async_services_;
   std::vector<grpc::string> ports_;
   std::shared_ptr<ServerCredentials> creds_;
-  ThreadPoolInterface* thread_pool_;
+  ThreadPoolInterface* thread_pool_ = nullptr;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index 47fd6cf1c85911f16fb7bf8bf3df1264c29fef0f..d327d8b41e59a1061542bab6b6efcc33c68bb0ba 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,15 +35,88 @@
 #define __GRPCPP_SERVER_CONTEXT_H_
 
 #include <chrono>
+#include <map>
+
+#include "config.h"
+
+struct gpr_timespec;
+struct grpc_metadata;
+struct grpc_call;
 
 namespace grpc {
 
+template <class W, class R>
+class ServerAsyncReader;
+template <class W>
+class ServerAsyncWriter;
+template <class W>
+class ServerAsyncResponseWriter;
+template <class R, class W>
+class ServerAsyncReaderWriter;
+template <class R>
+class ServerReader;
+template <class W>
+class ServerWriter;
+template <class R, class W>
+class ServerReaderWriter;
+
+class Call;
+class CallOpBuffer;
+class CompletionQueue;
+class Server;
+
 // Interface of server side rpc context.
-class ServerContext {
+class ServerContext final {
  public:
-  virtual ~ServerContext() {}
+  ServerContext();  // for async calls
+  ~ServerContext();
+
+  std::chrono::system_clock::time_point absolute_deadline() {
+    return deadline_;
+  }
+
+  void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
+  void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
+
+  bool IsCancelled();
+
+  const std::multimap<grpc::string, grpc::string>& client_metadata() {
+    return client_metadata_;
+  }
+
+ private:
+  friend class ::grpc::Server;
+  template <class W, class R>
+  friend class ::grpc::ServerAsyncReader;
+  template <class W>
+  friend class ::grpc::ServerAsyncWriter;
+  template <class W>
+  friend class ::grpc::ServerAsyncResponseWriter;
+  template <class R, class W>
+  friend class ::grpc::ServerAsyncReaderWriter;
+  template <class R>
+  friend class ::grpc::ServerReader;
+  template <class W>
+  friend class ::grpc::ServerWriter;
+  template <class R, class W>
+  friend class ::grpc::ServerReaderWriter;
+
+  class CompletionOp;
+
+  void BeginCompletionOp(Call* call);
+
+  ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
+                size_t metadata_count);
+
+  CompletionOp* completion_op_ = nullptr;
 
-  virtual std::chrono::system_clock::time_point absolute_deadline() const = 0;
+  std::chrono::system_clock::time_point deadline_;
+  grpc_call* call_ = nullptr;
+  CompletionQueue* cq_ = nullptr;
+  bool sent_initial_metadata_ = false;
+  std::multimap<grpc::string, grpc::string> client_metadata_;
+  std::multimap<grpc::string, grpc::string> initial_metadata_;
+  std::multimap<grpc::string, grpc::string> trailing_metadata_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/server_credentials.h b/include/grpc++/server_credentials.h
index b12d1390451242c22ba091ed0d38d2ac733bb010..5c6787a07705d13ef9e12c7581695f4a4d45868a 100644
--- a/include/grpc++/server_credentials.h
+++ b/include/grpc++/server_credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/status.h b/include/grpc++/status.h
index 432158a989ad3b0df3d1d89d06c88361cf8c7c18..1dfb0c997ca5f608dbadeb875dc384612c84e4c7 100644
--- a/include/grpc++/status.h
+++ b/include/grpc++/status.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/status_code_enum.h b/include/grpc++/status_code_enum.h
index 4e0fda13db634d0e333ed8f62565b394f212b0fc..0ec0a976d2253247db4829ed51c6de49f3f50512 100644
--- a/include/grpc++/status_code_enum.h
+++ b/include/grpc++/status_code_enum.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc++/stream.h b/include/grpc++/stream.h
index b8982f4d93de22d670c3221d2f32b54ae8dbec4b..cd95ff7c92f78e6b06d06bbaec52c665262e6feb 100644
--- a/include/grpc++/stream.h
+++ b/include/grpc++/stream.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,12 @@
 #ifndef __GRPCPP_STREAM_H__
 #define __GRPCPP_STREAM_H__
 
-#include <grpc++/stream_context_interface.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/completion_queue.h>
+#include <grpc++/server_context.h>
+#include <grpc++/impl/call.h>
+#include <grpc++/impl/service_type.h>
 #include <grpc++/status.h>
 #include <grpc/support/log.h>
 
@@ -45,16 +50,12 @@ class ClientStreamingInterface {
  public:
   virtual ~ClientStreamingInterface() {}
 
-  // Try to cancel the stream. Wait() still needs to be called to get the final
-  // status. Cancelling after the stream has finished has no effects.
-  virtual void Cancel() = 0;
-
   // Wait until the stream finishes, and return the final status. When the
   // client side declares it has no more message to send, either implicitly or
   // by calling WritesDone, it needs to make sure there is no more message to
   // be received from the server, either implicitly or by getting a false from
   // a Read(). Otherwise, this implicitly cancels the stream.
-  virtual const Status& Wait() = 0;
+  virtual Status Finish() = 0;
 };
 
 // An interface that yields a sequence of R messages.
@@ -82,147 +83,629 @@ class WriterInterface {
 };
 
 template <class R>
-class ClientReader : public ClientStreamingInterface,
-                     public ReaderInterface<R> {
+class ClientReader final : public ClientStreamingInterface,
+                           public ReaderInterface<R> {
  public:
   // Blocking create a stream and write the first request out.
-  explicit ClientReader(StreamContextInterface* context) : context_(context) {
-    GPR_ASSERT(context_);
-    context_->Start(true);
-    context_->Write(context_->request(), true);
+  ClientReader(ChannelInterface* channel, const RpcMethod& method,
+               ClientContext* context, const google::protobuf::Message& request)
+      : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
+    CallOpBuffer buf;
+    buf.AddSendInitialMetadata(&context->send_initial_metadata_);
+    buf.AddSendMessage(request);
+    buf.AddClientSendClose();
+    call_.PerformOps(&buf);
+    cq_.Pluck(&buf);
   }
 
-  ~ClientReader() { delete context_; }
-
-  virtual bool Read(R* msg) { return context_->Read(msg); }
+  // Blocking wait for initial metadata from server. The received metadata
+  // can only be accessed after this call returns. Should only be called before
+  // the first read. Calling this method is optional, and if it is not called
+  // the metadata will be available in ClientContext after the first read.
+  void WaitForInitialMetadata() {
+    GPR_ASSERT(!context_->initial_metadata_received_);
+
+    CallOpBuffer buf;
+    buf.AddRecvInitialMetadata(context_);
+    call_.PerformOps(&buf);
+    GPR_ASSERT(cq_.Pluck(&buf));
+  }
 
-  virtual void Cancel() { context_->Cancel(); }
+  virtual bool Read(R* msg) override {
+    CallOpBuffer buf;
+    if (!context_->initial_metadata_received_) {
+      buf.AddRecvInitialMetadata(context_);
+    }
+    buf.AddRecvMessage(msg);
+    call_.PerformOps(&buf);
+    return cq_.Pluck(&buf) && buf.got_message;
+  }
 
-  virtual const Status& Wait() { return context_->Wait(); }
+  virtual Status Finish() override {
+    CallOpBuffer buf;
+    Status status;
+    buf.AddClientRecvStatus(context_, &status);
+    call_.PerformOps(&buf);
+    GPR_ASSERT(cq_.Pluck(&buf));
+    return status;
+  }
 
  private:
-  StreamContextInterface* const context_;
+  ClientContext* context_;
+  CompletionQueue cq_;
+  Call call_;
 };
 
 template <class W>
-class ClientWriter : public ClientStreamingInterface,
-                     public WriterInterface<W> {
+class ClientWriter final : public ClientStreamingInterface,
+                           public WriterInterface<W> {
  public:
   // Blocking create a stream.
-  explicit ClientWriter(StreamContextInterface* context) : context_(context) {
-    GPR_ASSERT(context_);
-    context_->Start(false);
+  ClientWriter(ChannelInterface* channel, const RpcMethod& method,
+               ClientContext* context, google::protobuf::Message* response)
+      : context_(context),
+        response_(response),
+        call_(channel->CreateCall(method, context, &cq_)) {
+    CallOpBuffer buf;
+    buf.AddSendInitialMetadata(&context->send_initial_metadata_);
+    call_.PerformOps(&buf);
+    cq_.Pluck(&buf);
   }
 
-  ~ClientWriter() { delete context_; }
-
-  virtual bool Write(const W& msg) {
-    return context_->Write(const_cast<W*>(&msg), false);
+  virtual bool Write(const W& msg) override {
+    CallOpBuffer buf;
+    buf.AddSendMessage(msg);
+    call_.PerformOps(&buf);
+    return cq_.Pluck(&buf);
   }
 
-  virtual void WritesDone() { context_->Write(nullptr, true); }
-
-  virtual void Cancel() { context_->Cancel(); }
+  virtual bool WritesDone() {
+    CallOpBuffer buf;
+    buf.AddClientSendClose();
+    call_.PerformOps(&buf);
+    return cq_.Pluck(&buf);
+  }
 
   // Read the final response and wait for the final status.
-  virtual const Status& Wait() {
-    bool success = context_->Read(context_->response());
-    if (!success) {
-      Cancel();
-    } else {
-      success = context_->Read(nullptr);
-      if (success) {
-        Cancel();
-      }
-    }
-    return context_->Wait();
+  virtual Status Finish() override {
+    CallOpBuffer buf;
+    Status status;
+    buf.AddRecvMessage(response_);
+    buf.AddClientRecvStatus(context_, &status);
+    call_.PerformOps(&buf);
+    GPR_ASSERT(cq_.Pluck(&buf) && buf.got_message);
+    return status;
   }
 
  private:
-  StreamContextInterface* const context_;
+  ClientContext* context_;
+  google::protobuf::Message* const response_;
+  CompletionQueue cq_;
+  Call call_;
 };
 
 // Client-side interface for bi-directional streaming.
 template <class W, class R>
-class ClientReaderWriter : public ClientStreamingInterface,
-                           public WriterInterface<W>,
-                           public ReaderInterface<R> {
+class ClientReaderWriter final : public ClientStreamingInterface,
+                                 public WriterInterface<W>,
+                                 public ReaderInterface<R> {
  public:
   // Blocking create a stream.
-  explicit ClientReaderWriter(StreamContextInterface* context)
-      : context_(context) {
-    GPR_ASSERT(context_);
-    context_->Start(false);
+  ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
+                     ClientContext* context)
+      : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
+    CallOpBuffer buf;
+    buf.AddSendInitialMetadata(&context->send_initial_metadata_);
+    call_.PerformOps(&buf);
+    GPR_ASSERT(cq_.Pluck(&buf));
+  }
+
+  // Blocking wait for initial metadata from server. The received metadata
+  // can only be accessed after this call returns. Should only be called before
+  // the first read. Calling this method is optional, and if it is not called
+  // the metadata will be available in ClientContext after the first read.
+  void WaitForInitialMetadata() {
+    GPR_ASSERT(!context_->initial_metadata_received_);
+
+    CallOpBuffer buf;
+    buf.AddRecvInitialMetadata(context_);
+    call_.PerformOps(&buf);
+    GPR_ASSERT(cq_.Pluck(&buf));
+  }
+
+  virtual bool Read(R* msg) override {
+    CallOpBuffer buf;
+    if (!context_->initial_metadata_received_) {
+      buf.AddRecvInitialMetadata(context_);
+    }
+    buf.AddRecvMessage(msg);
+    call_.PerformOps(&buf);
+    return cq_.Pluck(&buf) && buf.got_message;
+  }
+
+  virtual bool Write(const W& msg) override {
+    CallOpBuffer buf;
+    buf.AddSendMessage(msg);
+    call_.PerformOps(&buf);
+    return cq_.Pluck(&buf);
   }
 
-  ~ClientReaderWriter() { delete context_; }
+  virtual bool WritesDone() {
+    CallOpBuffer buf;
+    buf.AddClientSendClose();
+    call_.PerformOps(&buf);
+    return cq_.Pluck(&buf);
+  }
+
+  virtual Status Finish() override {
+    CallOpBuffer buf;
+    Status status;
+    buf.AddClientRecvStatus(context_, &status);
+    call_.PerformOps(&buf);
+    GPR_ASSERT(cq_.Pluck(&buf));
+    return status;
+  }
+
+ private:
+  ClientContext* context_;
+  CompletionQueue cq_;
+  Call call_;
+};
+
+template <class R>
+class ServerReader final : public ReaderInterface<R> {
+ public:
+  ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
+
+  void SendInitialMetadata() {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+    CallOpBuffer buf;
+    buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_->PerformOps(&buf);
+    call_->cq()->Pluck(&buf);
+  }
+
+  virtual bool Read(R* msg) override {
+    CallOpBuffer buf;
+    buf.AddRecvMessage(msg);
+    call_->PerformOps(&buf);
+    return call_->cq()->Pluck(&buf) && buf.got_message;
+  }
+
+ private:
+  Call* const call_;
+  ServerContext* const ctx_;
+};
+
+template <class W>
+class ServerWriter final : public WriterInterface<W> {
+ public:
+  ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
+
+  void SendInitialMetadata() {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
 
-  virtual bool Read(R* msg) { return context_->Read(msg); }
+    CallOpBuffer buf;
+    buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_->PerformOps(&buf);
+    call_->cq()->Pluck(&buf);
+  }
 
-  virtual bool Write(const W& msg) {
-    return context_->Write(const_cast<W*>(&msg), false);
+  virtual bool Write(const W& msg) override {
+    CallOpBuffer buf;
+    if (!ctx_->sent_initial_metadata_) {
+      buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    buf.AddSendMessage(msg);
+    call_->PerformOps(&buf);
+    return call_->cq()->Pluck(&buf);
   }
 
-  virtual void WritesDone() { context_->Write(nullptr, true); }
+ private:
+  Call* const call_;
+  ServerContext* const ctx_;
+};
 
-  virtual void Cancel() { context_->Cancel(); }
+// Server-side interface for bi-directional streaming.
+template <class W, class R>
+class ServerReaderWriter final : public WriterInterface<W>,
+                                 public ReaderInterface<R> {
+ public:
+  ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
-  virtual const Status& Wait() { return context_->Wait(); }
+  void SendInitialMetadata() {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+    CallOpBuffer buf;
+    buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_->PerformOps(&buf);
+    call_->cq()->Pluck(&buf);
+  }
+
+  virtual bool Read(R* msg) override {
+    CallOpBuffer buf;
+    buf.AddRecvMessage(msg);
+    call_->PerformOps(&buf);
+    return call_->cq()->Pluck(&buf) && buf.got_message;
+  }
+
+  virtual bool Write(const W& msg) override {
+    CallOpBuffer buf;
+    if (!ctx_->sent_initial_metadata_) {
+      buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    buf.AddSendMessage(msg);
+    call_->PerformOps(&buf);
+    return call_->cq()->Pluck(&buf);
+  }
 
  private:
-  StreamContextInterface* const context_;
+  Call* const call_;
+  ServerContext* const ctx_;
+};
+
+// Async interfaces
+// Common interface for all client side streaming.
+class ClientAsyncStreamingInterface {
+ public:
+  virtual ~ClientAsyncStreamingInterface() {}
+
+  virtual void ReadInitialMetadata(void* tag) = 0;
+
+  virtual void Finish(Status* status, void* tag) = 0;
 };
 
+// An interface that yields a sequence of R messages.
 template <class R>
-class ServerReader : public ReaderInterface<R> {
+class AsyncReaderInterface {
+ public:
+  virtual ~AsyncReaderInterface() {}
+
+  virtual void Read(R* msg, void* tag) = 0;
+};
+
+// An interface that can be fed a sequence of W messages.
+template <class W>
+class AsyncWriterInterface {
+ public:
+  virtual ~AsyncWriterInterface() {}
+
+  virtual void Write(const W& msg, void* tag) = 0;
+};
+
+template <class R>
+class ClientAsyncReader final : public ClientAsyncStreamingInterface,
+                                public AsyncReaderInterface<R> {
+ public:
+  // Create a stream and write the first request out.
+  ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
+                    const RpcMethod& method, ClientContext* context,
+                    const google::protobuf::Message& request, void* tag)
+      : context_(context), call_(channel->CreateCall(method, context, cq)) {
+    init_buf_.Reset(tag);
+    init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_);
+    init_buf_.AddSendMessage(request);
+    init_buf_.AddClientSendClose();
+    call_.PerformOps(&init_buf_);
+  }
+
+  void ReadInitialMetadata(void* tag) override {
+    GPR_ASSERT(!context_->initial_metadata_received_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddRecvInitialMetadata(context_);
+    call_.PerformOps(&meta_buf_);
+  }
+
+  void Read(R* msg, void* tag) override {
+    read_buf_.Reset(tag);
+    if (!context_->initial_metadata_received_) {
+      read_buf_.AddRecvInitialMetadata(context_);
+    }
+    read_buf_.AddRecvMessage(msg);
+    call_.PerformOps(&read_buf_);
+  }
+
+  void Finish(Status* status, void* tag) override {
+    finish_buf_.Reset(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_buf_.AddRecvInitialMetadata(context_);
+    }
+    finish_buf_.AddClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_buf_);
+  }
+
+ private:
+  ClientContext* context_ = nullptr;
+  Call call_;
+  CallOpBuffer init_buf_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer read_buf_;
+  CallOpBuffer finish_buf_;
+};
+
+template <class W>
+class ClientAsyncWriter final : public ClientAsyncStreamingInterface,
+                                public AsyncWriterInterface<W> {
+ public:
+  ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
+                    const RpcMethod& method, ClientContext* context,
+                    google::protobuf::Message* response, void* tag)
+      : context_(context),
+        response_(response),
+        call_(channel->CreateCall(method, context, cq)) {
+    init_buf_.Reset(tag);
+    init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_);
+    call_.PerformOps(&init_buf_);
+  }
+
+  void ReadInitialMetadata(void* tag) override {
+    GPR_ASSERT(!context_->initial_metadata_received_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddRecvInitialMetadata(context_);
+    call_.PerformOps(&meta_buf_);
+  }
+
+  void Write(const W& msg, void* tag) override {
+    write_buf_.Reset(tag);
+    write_buf_.AddSendMessage(msg);
+    call_.PerformOps(&write_buf_);
+  }
+
+  void WritesDone(void* tag) {
+    writes_done_buf_.Reset(tag);
+    writes_done_buf_.AddClientSendClose();
+    call_.PerformOps(&writes_done_buf_);
+  }
+
+  void Finish(Status* status, void* tag) override {
+    finish_buf_.Reset(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_buf_.AddRecvInitialMetadata(context_);
+    }
+    finish_buf_.AddRecvMessage(response_);
+    finish_buf_.AddClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_buf_);
+  }
+
+ private:
+  ClientContext* context_ = nullptr;
+  google::protobuf::Message* const response_;
+  Call call_;
+  CallOpBuffer init_buf_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer write_buf_;
+  CallOpBuffer writes_done_buf_;
+  CallOpBuffer finish_buf_;
+};
+
+// Client-side interface for bi-directional streaming.
+template <class W, class R>
+class ClientAsyncReaderWriter final : public ClientAsyncStreamingInterface,
+                                      public AsyncWriterInterface<W>,
+                                      public AsyncReaderInterface<R> {
+ public:
+  ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
+                          const RpcMethod& method, ClientContext* context,
+                          void* tag)
+      : context_(context), call_(channel->CreateCall(method, context, cq)) {
+    init_buf_.Reset(tag);
+    init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_);
+    call_.PerformOps(&init_buf_);
+  }
+
+  void ReadInitialMetadata(void* tag) override {
+    GPR_ASSERT(!context_->initial_metadata_received_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddRecvInitialMetadata(context_);
+    call_.PerformOps(&meta_buf_);
+  }
+
+  void Read(R* msg, void* tag) override {
+    read_buf_.Reset(tag);
+    if (!context_->initial_metadata_received_) {
+      read_buf_.AddRecvInitialMetadata(context_);
+    }
+    read_buf_.AddRecvMessage(msg);
+    call_.PerformOps(&read_buf_);
+  }
+
+  void Write(const W& msg, void* tag) override {
+    write_buf_.Reset(tag);
+    write_buf_.AddSendMessage(msg);
+    call_.PerformOps(&write_buf_);
+  }
+
+  void WritesDone(void* tag) {
+    writes_done_buf_.Reset(tag);
+    writes_done_buf_.AddClientSendClose();
+    call_.PerformOps(&writes_done_buf_);
+  }
+
+  void Finish(Status* status, void* tag) override {
+    finish_buf_.Reset(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_buf_.AddRecvInitialMetadata(context_);
+    }
+    finish_buf_.AddClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_buf_);
+  }
+
+ private:
+  ClientContext* context_ = nullptr;
+  Call call_;
+  CallOpBuffer init_buf_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer read_buf_;
+  CallOpBuffer write_buf_;
+  CallOpBuffer writes_done_buf_;
+  CallOpBuffer finish_buf_;
+};
+
+template <class W, class R>
+class ServerAsyncReader : public ServerAsyncStreamingInterface,
+                          public AsyncReaderInterface<R> {
  public:
-  explicit ServerReader(StreamContextInterface* context) : context_(context) {
-    GPR_ASSERT(context_);
-    context_->Start(true);
+  explicit ServerAsyncReader(ServerContext* ctx)
+      : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+  void SendInitialMetadata(void* tag) override {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_buf_);
+  }
+
+  void Read(R* msg, void* tag) override {
+    read_buf_.Reset(tag);
+    read_buf_.AddRecvMessage(msg);
+    call_.PerformOps(&read_buf_);
+  }
+
+  void Finish(const W& msg, const Status& status, void* tag) {
+    finish_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    // The response is dropped if the status is not OK.
+    if (status.IsOk()) {
+      finish_buf_.AddSendMessage(msg);
+    }
+    finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_buf_);
   }
 
-  virtual bool Read(R* msg) { return context_->Read(msg); }
+  void FinishWithError(const Status& status, void* tag) {
+    GPR_ASSERT(!status.IsOk());
+    finish_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_buf_);
+  }
 
  private:
-  StreamContextInterface* const context_;  // not owned
+  void BindCall(Call* call) override { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer read_buf_;
+  CallOpBuffer finish_buf_;
 };
 
 template <class W>
-class ServerWriter : public WriterInterface<W> {
+class ServerAsyncWriter : public ServerAsyncStreamingInterface,
+                          public AsyncWriterInterface<W> {
  public:
-  explicit ServerWriter(StreamContextInterface* context) : context_(context) {
-    GPR_ASSERT(context_);
-    context_->Start(true);
-    context_->Read(context_->request());
+  explicit ServerAsyncWriter(ServerContext* ctx)
+      : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+  void SendInitialMetadata(void* tag) override {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_buf_);
   }
 
-  virtual bool Write(const W& msg) {
-    return context_->Write(const_cast<W*>(&msg), false);
+  void Write(const W& msg, void* tag) override {
+    write_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      write_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    write_buf_.AddSendMessage(msg);
+    call_.PerformOps(&write_buf_);
+  }
+
+  void Finish(const Status& status, void* tag) {
+    finish_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_buf_);
   }
 
  private:
-  StreamContextInterface* const context_;  // not owned
+  void BindCall(Call* call) override { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer write_buf_;
+  CallOpBuffer finish_buf_;
 };
 
 // Server-side interface for bi-directional streaming.
 template <class W, class R>
-class ServerReaderWriter : public WriterInterface<W>,
-                           public ReaderInterface<R> {
+class ServerAsyncReaderWriter : public ServerAsyncStreamingInterface,
+                                public AsyncWriterInterface<W>,
+                                public AsyncReaderInterface<R> {
  public:
-  explicit ServerReaderWriter(StreamContextInterface* context)
-      : context_(context) {
-    GPR_ASSERT(context_);
-    context_->Start(true);
+  explicit ServerAsyncReaderWriter(ServerContext* ctx)
+      : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+  void SendInitialMetadata(void* tag) override {
+    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_buf_.Reset(tag);
+    meta_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_buf_);
   }
 
-  virtual bool Read(R* msg) { return context_->Read(msg); }
+  virtual void Read(R* msg, void* tag) override {
+    read_buf_.Reset(tag);
+    read_buf_.AddRecvMessage(msg);
+    call_.PerformOps(&read_buf_);
+  }
 
-  virtual bool Write(const W& msg) {
-    return context_->Write(const_cast<W*>(&msg), false);
+  virtual void Write(const W& msg, void* tag) override {
+    write_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      write_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    write_buf_.AddSendMessage(msg);
+    call_.PerformOps(&write_buf_);
+  }
+
+  void Finish(const Status& status, void* tag) {
+    finish_buf_.Reset(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_buf_);
   }
 
  private:
-  StreamContextInterface* const context_;  // not owned
+  void BindCall(Call* call) override { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpBuffer meta_buf_;
+  CallOpBuffer read_buf_;
+  CallOpBuffer write_buf_;
+  CallOpBuffer finish_buf_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/thread_pool_interface.h b/include/grpc++/thread_pool_interface.h
index a8eacb037fdb19772ad8830fd02ee8abaa29a159..c83924932416cf8d6b7e67afd0e1bb66b878f78d 100644
--- a/include/grpc++/thread_pool_interface.h
+++ b/include/grpc++/thread_pool_interface.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/byte_buffer.h b/include/grpc/byte_buffer.h
index 094d3016e1efdd6de00e014bfb96c147d8e396fa..89d8557edff676ab5a73673b45adfaccb199cb6b 100644
--- a/include/grpc/byte_buffer.h
+++ b/include/grpc/byte_buffer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/byte_buffer_reader.h b/include/grpc/byte_buffer_reader.h
index a9cbb7752becd1a4b9c80e13cdb73e870c867cbd..4446e0c6b393914066898912faaaf91d4d71d8f7 100644
--- a/include/grpc/byte_buffer_reader.h
+++ b/include/grpc/byte_buffer_reader.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 904853d984e094216370bddadb3b24b77704ab8c..4a720d11f85b4035b7d284d6c9443bbeb16daf02 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -92,7 +92,12 @@ typedef struct {
   } value;
 } grpc_arg;
 
-/* An array of arguments that can be passed around */
+/* An array of arguments that can be passed around.
+   Used to set optional channel-level configuration.
+   These configuration options are modelled as key-value pairs as defined
+   by grpc_arg; keys are strings to allow easy backwards-compatible extension
+   by arbitrary parties.
+   All evaluation is performed at channel creation time. */
 typedef struct {
   size_t num_args;
   grpc_arg *args;
@@ -255,15 +260,18 @@ void grpc_call_details_init(grpc_call_details *details);
 void grpc_call_details_destroy(grpc_call_details *details);
 
 typedef enum {
-  /* Send initial metadata: one and only one instance MUST be sent for each call,
+  /* Send initial metadata: one and only one instance MUST be sent for each
+     call,
      unless the call was cancelled - in which case this can be skipped */
   GRPC_OP_SEND_INITIAL_METADATA = 0,
   /* Send a message: 0 or more of these operations can occur for each call */
   GRPC_OP_SEND_MESSAGE,
-  /* Send a close from the server: one and only one instance MUST be sent from the client,
+  /* Send a close from the server: one and only one instance MUST be sent from
+     the client,
      unless the call was cancelled - in which case this can be skipped */
   GRPC_OP_SEND_CLOSE_FROM_CLIENT,
-  /* Send status from the server: one and only one instance MUST be sent from the server
+  /* Send status from the server: one and only one instance MUST be sent from
+     the server
      unless the call was cancelled - in which case this can be skipped */
   GRPC_OP_SEND_STATUS_FROM_SERVER,
   /* Receive initial metadata: one and only one MUST be made on the client, must
@@ -271,13 +279,16 @@ typedef enum {
   GRPC_OP_RECV_INITIAL_METADATA,
   /* Receive a message: 0 or more of these operations can occur for each call */
   GRPC_OP_RECV_MESSAGE,
-  /* Receive status on the client: one and only one must be made on the client */
+  /* Receive status on the client: one and only one must be made on the client
+     */
   GRPC_OP_RECV_STATUS_ON_CLIENT,
-  /* Receive status on the server: one and only one must be made on the server */
+  /* Receive status on the server: one and only one must be made on the server
+     */
   GRPC_OP_RECV_CLOSE_ON_SERVER
 } grpc_op_type;
 
-/* Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT which has
+/* Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT
+   which has
    no arguments) */
 typedef struct grpc_op {
   grpc_op_type op;
@@ -301,29 +312,33 @@ typedef struct grpc_op {
     grpc_metadata_array *recv_initial_metadata;
     grpc_byte_buffer **recv_message;
     struct {
-      /* ownership of the array is with the caller, but ownership of the elements
+      /* ownership of the array is with the caller, but ownership of the
+         elements
          stays with the call object (ie key, value members are owned by the call
          object, trailing_metadata->array is owned by the caller).
          After the operation completes, call grpc_metadata_array_destroy on this
          value, or reuse it in a future op. */
       grpc_metadata_array *trailing_metadata;
       grpc_status_code *status;
-      /* status_details is a buffer owned by the application before the op completes
-         and after the op has completed. During the operation status_details may be
-         reallocated to a size larger than *status_details_capacity, in which case
+      /* status_details is a buffer owned by the application before the op
+         completes
+         and after the op has completed. During the operation status_details may
+         be
+         reallocated to a size larger than *status_details_capacity, in which
+         case
          *status_details_capacity will be updated with the new array capacity.
 
          Pre-allocating space:
          size_t my_capacity = 8;
          char *my_details = gpr_malloc(my_capacity);
          x.status_details = &my_details;
-         x.status_details_capacity = &my_capacity; 
+         x.status_details_capacity = &my_capacity;
 
          Not pre-allocating space:
          size_t my_capacity = 0;
          char *my_details = NULL;
          x.status_details = &my_details;
-         x.status_details_capacity = &my_capacity; 
+         x.status_details_capacity = &my_capacity;
 
          After the call:
          gpr_free(my_details); */
@@ -331,17 +346,26 @@ typedef struct grpc_op {
       size_t *status_details_capacity;
     } recv_status_on_client;
     struct {
-      /* out argument, set to 1 if the call failed in any way (seen as a cancellation
+      /* out argument, set to 1 if the call failed in any way (seen as a
+         cancellation
          on the server), or 0 if the call succeeded */
       int *cancelled;
     } recv_close_on_server;
   } data;
 } grpc_op;
 
-/* Initialize the grpc library */
+/* Initialize the grpc library.
+   It is not safe to call any other grpc functions before calling this.
+   (To avoid overhead, little checking is done, and some things may work. We
+   do not warrant that they will continue to do so in future revisions of this
+   library). */
 void grpc_init(void);
 
-/* Shut down the grpc library */
+/* Shut down the grpc library. 
+   No memory is used by grpc after this call returns, nor are any instructions
+   executing within the grpc library.
+   Prior to calling, all application owned grpc objects must have been
+   destroyed. */
 void grpc_shutdown(void);
 
 grpc_completion_queue *grpc_completion_queue_create(void);
@@ -370,7 +394,12 @@ grpc_event *grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
 void grpc_event_finish(grpc_event *event);
 
 /* Begin destruction of a completion queue. Once all possible events are
-   drained it's safe to call grpc_completion_queue_destroy. */
+   drained then grpc_completion_queue_next will start to produce
+   GRPC_QUEUE_SHUTDOWN events only. At that point it's safe to call 
+   grpc_completion_queue_destroy. 
+   
+   After calling this function applications should ensure that no
+   NEW work is added to be published on this completion queue. */
 void grpc_completion_queue_shutdown(grpc_completion_queue *cq);
 
 /* Destroy a completion queue. The caller must ensure that the queue is
@@ -393,14 +422,17 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
                                     gpr_timespec deadline);
 
 /* Start a batch of operations defined in the array ops; when complete, post a
-   completion of type 'tag' to the completion queue bound to the call. 
+   completion of type 'tag' to the completion queue bound to the call.
    The order of ops specified in the batch has no significance.
    Only one operation of each type can be active at once in any given
    batch. */
 grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
                                       size_t nops, void *tag);
 
-/* Create a client channel */
+/* Create a client channel to 'target'. Additional channel level configuration
+   MAY be provided by grpc_channel_args, though the expectation is that most
+   clients will want to simply pass NULL. See grpc_channel_args definition
+   for more on this. */
 grpc_channel *grpc_channel_create(const char *target,
                                   const grpc_channel_args *args);
 
@@ -540,12 +572,34 @@ void grpc_call_destroy(grpc_call *call);
 grpc_call_error grpc_server_request_call_old(grpc_server *server,
                                              void *tag_new);
 
+/* Request notification of a new call */
 grpc_call_error grpc_server_request_call(
     grpc_server *server, grpc_call **call, grpc_call_details *details,
     grpc_metadata_array *request_metadata,
-    grpc_completion_queue *completion_queue, void *tag_new);
-
-/* Create a server */
+    grpc_completion_queue *cq_bound_to_call,
+    void *tag_new);
+
+/* Registers a method in the server.
+   Methods to this (host, method) pair will not be reported by
+   grpc_server_request_call, but instead be reported by
+   grpc_server_request_registered_call when passed the appropriate
+   registered_method (as returned by this function).
+   Must be called before grpc_server_start.
+   Returns NULL on failure. */
+void *grpc_server_register_method(grpc_server *server, const char *method,
+                                  const char *host,
+                                  grpc_completion_queue *new_call_cq);
+
+/* Request notification of a new pre-registered call */
+grpc_call_error grpc_server_request_registered_call(
+    grpc_server *server, void *registered_method, grpc_call **call,
+    gpr_timespec *deadline, grpc_metadata_array *request_metadata,
+    grpc_byte_buffer **optional_payload,
+    grpc_completion_queue *cq_bound_to_call, void *tag_new);
+
+/* Create a server. Additional configuration for each incoming channel can
+   be specified with args. If no additional configuration is needed, args can
+   be NULL. See grpc_channel_args for more. */
 grpc_server *grpc_server_create(grpc_completion_queue *cq,
                                 const grpc_channel_args *args);
 
diff --git a/include/grpc/grpc_http.h b/include/grpc/grpc_http.h
index b2ae5340a56223080f18379020dc85bf20360fd3..757f53f9df12ab56d328590ff1f863ee9047b93b 100644
--- a/include/grpc/grpc_http.h
+++ b/include/grpc/grpc_http.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index a43d998d0294b84ac9ca516b8275b2b3f2d5cb32..f03ac8004dad373438e4accd21aae7a8bb0f1710 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/status.h b/include/grpc/status.h
index 630b7769fd59243c79de6442d8b7be5984515ae3..76a71ed26fcc7e9b711ae1b39538cc518bd39f81 100644
--- a/include/grpc/status.h
+++ b/include/grpc/status.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index fa9cc4bf7c789aa6c746203c8fc06349ea39ac45..c7580655761e1a51e0788c52a68904735c68d565 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/atm.h b/include/grpc/support/atm.h
index 5e613f1ba983e89fff1f9dba5da4bc0b39790b6c..0cac9bf5865464bd806752e92baf428f2a3b39d9 100644
--- a/include/grpc/support/atm.h
+++ b/include/grpc/support/atm.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/atm_gcc_atomic.h b/include/grpc/support/atm_gcc_atomic.h
index 896dd842ec20719fd58a13d807f891cdd588227b..2ae24aec06d72418fa652646134db8e04ae87bab 100644
--- a/include/grpc/support/atm_gcc_atomic.h
+++ b/include/grpc/support/atm_gcc_atomic.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/atm_gcc_sync.h b/include/grpc/support/atm_gcc_sync.h
index 1a3a10c911bd5b76f8015e9dd24a3ea664e28285..cec62e1a20d16949009c16f0d9803048799b31ac 100644
--- a/include/grpc/support/atm_gcc_sync.h
+++ b/include/grpc/support/atm_gcc_sync.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/atm_win32.h b/include/grpc/support/atm_win32.h
index 19881e83ad84c4a8da5b1bbceb9f66dfedd0b48c..acacf12013ce8af949df318463a944def1bdd8ec 100644
--- a/include/grpc/support/atm_win32.h
+++ b/include/grpc/support/atm_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/cancellable_platform.h b/include/grpc/support/cancellable_platform.h
index db099b83818dfc48bf8f66ae714112a32e819917..e77f9f15777f343e377e820f66cf3f59d756e86d 100644
--- a/include/grpc/support/cancellable_platform.h
+++ b/include/grpc/support/cancellable_platform.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/cmdline.h b/include/grpc/support/cmdline.h
index ba3ffe42cc03e07f780a5bde1b1ad203ddd554e3..20de12242c72b4151e8883248d43e3282099b5b6 100644
--- a/include/grpc/support/cmdline.h
+++ b/include/grpc/support/cmdline.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/cpu.h b/include/grpc/support/cpu.h
similarity index 94%
rename from src/core/support/cpu.h
rename to include/grpc/support/cpu.h
index f8ec2c65220f2007f5fa50a6567073b8f593e166..580f12dad729b7e8e43ef3fed12e0983a7b07d38 100644
--- a/src/core/support/cpu.h
+++ b/include/grpc/support/cpu.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,10 @@
 #ifndef __GRPC_INTERNAL_SUPPORT_CPU_H__
 #define __GRPC_INTERNAL_SUPPORT_CPU_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Interface providing CPU information for currently running system */
 
 /* Return the number of CPU cores on the current system. Will return 0 if
@@ -46,4 +50,8 @@ unsigned gpr_cpu_num_cores(void);
    [0, gpr_cpu_num_cores() - 1] */
 unsigned gpr_cpu_current_cpu(void);
 
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
 #endif /* __GRPC_INTERNAL_SUPPORT_CPU_H__ */
diff --git a/include/grpc/support/histogram.h b/include/grpc/support/histogram.h
index e67323d5d3dbba5a68ab89a6205147ab49fcd76a..fb9d3d1691efce39e2a4e8f7ead1d758888024fb 100644
--- a/include/grpc/support/histogram.h
+++ b/include/grpc/support/histogram.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/host_port.h b/include/grpc/support/host_port.h
index 9495bfea40a73016b826dcaf5ba52f3e088ecf86..362046cb95d266a4f2ff2121d2c25cb182685d08 100644
--- a/include/grpc/support/host_port.h
+++ b/include/grpc/support/host_port.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index 1c2857dad38dee03cb451c5878d6ac2603de8802..c142949f770ff23869611d6b7d4647881e01f31b 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/log_win32.h b/include/grpc/support/log_win32.h
index 0350056d26e853fa158aae7858389877ade37491..52d6a703189a4ecb0f6025702685a5ade476ba68 100644
--- a/include/grpc/support/log_win32.h
+++ b/include/grpc/support/log_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index 5b9b3c47a6b99b79ca7c6e80d4b1db7b64d3485e..27efa2944855926728c9977d9e79e1a8584d5dea 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/slice.h b/include/grpc/support/slice.h
index 7828ccdd13c305b00eb7255add9ed8516e55a33e..261e3baabee0bd1b26d1b98ba9201cccc1c8f24c 100644
--- a/include/grpc/support/slice.h
+++ b/include/grpc/support/slice.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h
index 80c13e064a9c70edcf3dfde0a2ebe3c72c69b3a2..8b57f9f0b9230f58f429a6c22c2fa87bbe16e3c7 100644
--- a/include/grpc/support/slice_buffer.h
+++ b/include/grpc/support/slice_buffer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index 6f0f684ae7a04b8215a9188c471751491a41d808..4437375db72fba005bafe68e16ac742747ec981f 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/sync_generic.h b/include/grpc/support/sync_generic.h
index 9ad56f7b64e6bd0053d6cf04abac0619058272c0..3bae222cb00afc88cfed3502b3f8f48798ff637c 100644
--- a/include/grpc/support/sync_generic.h
+++ b/include/grpc/support/sync_generic.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/sync_posix.h b/include/grpc/support/sync_posix.h
index d51c268dc98d55d34eca14956cef268533332d5c..413226a9e8f5e781fe60dbf2a3d5ee0d7fc3e9d2 100644
--- a/include/grpc/support/sync_posix.h
+++ b/include/grpc/support/sync_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/sync_win32.h b/include/grpc/support/sync_win32.h
index 6e256663501926a680ddf8b96c7d2332bdbd86eb..5a48b52a2dc0beb3f2cc1ef06d118cbc147eb9ea 100644
--- a/include/grpc/support/sync_win32.h
+++ b/include/grpc/support/sync_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/thd.h b/include/grpc/support/thd.h
index 92d40b4475240219f1335d694d7bb6c08761e315..a81e6cd3ba900c24326c9a1c825cb9f303324ee8 100644
--- a/include/grpc/support/thd.h
+++ b/include/grpc/support/thd.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index 9fb1d0bc97b52544552f84682c02588e7d89b4cf..ebc18c91e94953049b3a7cf28270716b8637cefd 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/include/grpc/support/useful.h b/include/grpc/support/useful.h
index c451e9cc83df7af8e9cf7cf2a8ee168da105b553..8d756c37c31416b4030ff59e75502095867b98f5 100644
--- a/include/grpc/support/useful.h
+++ b/include/grpc/support/useful.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 8724f97e8be496435a5ec235dd2e9fa85facb776..f10824e6b0735c018d33dcef7747e25657bf9f11 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,10 +41,18 @@
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <sstream>
 
 namespace grpc_cpp_generator {
 namespace {
 
+template <class T>
+std::string as_string(T x) {
+  std::ostringstream out;
+  out << x;
+  return out.str();
+}
+
 bool NoStreaming(const google::protobuf::MethodDescriptor *method) {
   return !method->client_streaming() && !method->server_streaming();
 }
@@ -61,6 +69,17 @@ bool BidiStreaming(const google::protobuf::MethodDescriptor *method) {
   return method->client_streaming() && method->server_streaming();
 }
 
+bool HasUnaryCalls(const google::protobuf::FileDescriptor *file) {
+  for (int i = 0; i < file->service_count(); i++) {
+    for (int j = 0; j < file->service(i)->method_count(); j++) {
+      if (NoStreaming(file->service(i)->method(j))) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor *file) {
   for (int i = 0; i < file->service_count(); i++) {
     for (int j = 0; j < file->service(i)->method_count(); j++) {
@@ -97,20 +116,32 @@ bool HasBidiStreaming(const google::protobuf::FileDescriptor *file) {
 
 std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file) {
   std::string temp =
-      "#include \"grpc++/impl/internal_stub.h\"\n"
-      "#include \"grpc++/status.h\"\n"
+      "#include <grpc++/impl/internal_stub.h>\n"
+      "#include <grpc++/impl/service_type.h>\n"
+      "#include <grpc++/status.h>\n"
       "\n"
       "namespace grpc {\n"
+      "class CompletionQueue;\n"
       "class ChannelInterface;\n"
       "class RpcService;\n"
       "class ServerContext;\n";
+  if (HasUnaryCalls(file)) {
+    temp.append(
+        "template <class OutMessage> class ClientAsyncResponseReader;\n");
+    temp.append(
+        "template <class OutMessage> class ServerAsyncResponseWriter;\n");
+  }
   if (HasClientOnlyStreaming(file)) {
     temp.append("template <class OutMessage> class ClientWriter;\n");
     temp.append("template <class InMessage> class ServerReader;\n");
+    temp.append("template <class OutMessage> class ClientAsyncWriter;\n");
+    temp.append("template <class OutMessage, class InMessage> class ServerAsyncReader;\n");
   }
   if (HasServerOnlyStreaming(file)) {
     temp.append("template <class InMessage> class ClientReader;\n");
     temp.append("template <class OutMessage> class ServerWriter;\n");
+    temp.append("template <class OutMessage> class ClientAsyncReader;\n");
+    temp.append("template <class InMessage> class ServerAsyncWriter;\n");
   }
   if (HasBidiStreaming(file)) {
     temp.append(
@@ -119,16 +150,25 @@ std::string GetHeaderIncludes(const google::protobuf::FileDescriptor *file) {
     temp.append(
         "template <class OutMessage, class InMessage>\n"
         "class ServerReaderWriter;\n");
+    temp.append(
+        "template <class OutMessage, class InMessage>\n"
+        "class ClientAsyncReaderWriter;\n");
+    temp.append(
+        "template <class OutMessage, class InMessage>\n"
+        "class ServerAsyncReaderWriter;\n");
   }
   temp.append("}  // namespace grpc\n");
   return temp;
 }
 
 std::string GetSourceIncludes() {
-  return "#include \"grpc++/channel_interface.h\"\n"
-         "#include \"grpc++/impl/rpc_method.h\"\n"
-         "#include \"grpc++/impl/rpc_service_method.h\"\n"
-         "#include \"grpc++/stream.h\"\n";
+  return "#include <grpc++/async_unary_call.h>\n"
+         "#include <grpc++/channel_interface.h>\n"
+         "#include <grpc++/impl/client_unary_call.h>\n"
+         "#include <grpc++/impl/rpc_method.h>\n"
+         "#include <grpc++/impl/rpc_service_method.h>\n"
+         "#include <grpc++/impl/service_type.h>\n"
+         "#include <grpc++/stream.h>\n";
 }
 
 void PrintHeaderClientMethod(google::protobuf::io::Printer *printer,
@@ -142,27 +182,44 @@ void PrintHeaderClientMethod(google::protobuf::io::Printer *printer,
   if (NoStreaming(method)) {
     printer->Print(*vars,
                    "::grpc::Status $Method$(::grpc::ClientContext* context, "
-                   "const $Request$& request, $Response$* response);\n\n");
+                   "const $Request$& request, $Response$* response);\n");
+    printer->Print(*vars,
+                   "::grpc::ClientAsyncResponseReader< $Response$>* "
+                   "$Method$(::grpc::ClientContext* context, "
+                   "const $Request$& request, "
+                   "::grpc::CompletionQueue* cq, void* tag);\n");
   } else if (ClientOnlyStreaming(method)) {
-    printer->Print(
-        *vars,
-        "::grpc::ClientWriter< $Request$>* $Method$("
-        "::grpc::ClientContext* context, $Response$* response);\n\n");
+    printer->Print(*vars,
+                   "::grpc::ClientWriter< $Request$>* $Method$("
+                   "::grpc::ClientContext* context, $Response$* response);\n");
+    printer->Print(*vars,
+                   "::grpc::ClientAsyncWriter< $Request$>* $Method$("
+                   "::grpc::ClientContext* context, $Response$* response, "
+                   "::grpc::CompletionQueue* cq, void* tag);\n");
   } else if (ServerOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "::grpc::ClientReader< $Response$>* $Method$("
-        "::grpc::ClientContext* context, const $Request$* request);\n\n");
+        "::grpc::ClientContext* context, const $Request$& request);\n");
+    printer->Print(*vars,
+                   "::grpc::ClientAsyncReader< $Response$>* $Method$("
+                   "::grpc::ClientContext* context, const $Request$& request, "
+                   "::grpc::CompletionQueue* cq, void* tag);\n");
   } else if (BidiStreaming(method)) {
     printer->Print(*vars,
                    "::grpc::ClientReaderWriter< $Request$, $Response$>* "
-                   "$Method$(::grpc::ClientContext* context);\n\n");
+                   "$Method$(::grpc::ClientContext* context);\n");
+    printer->Print(*vars,
+                   "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+                   "$Method$(::grpc::ClientContext* context, "
+                   "::grpc::CompletionQueue* cq, void* tag);\n");
   }
 }
 
-void PrintHeaderServerMethod(google::protobuf::io::Printer *printer,
-                             const google::protobuf::MethodDescriptor *method,
-                             std::map<std::string, std::string> *vars) {
+void PrintHeaderServerMethodSync(
+    google::protobuf::io::Printer *printer,
+    const google::protobuf::MethodDescriptor *method,
+    std::map<std::string, std::string> *vars) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] =
       grpc_cpp_generator::ClassName(method->input_type(), true);
@@ -194,19 +251,56 @@ void PrintHeaderServerMethod(google::protobuf::io::Printer *printer,
   }
 }
 
+void PrintHeaderServerMethodAsync(
+    google::protobuf::io::Printer *printer,
+    const google::protobuf::MethodDescriptor *method,
+    std::map<std::string, std::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] =
+      grpc_cpp_generator::ClassName(method->input_type(), true);
+  (*vars)["Response"] =
+      grpc_cpp_generator::ClassName(method->output_type(), true);
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+                   "void Request$Method$("
+                   "::grpc::ServerContext* context, $Request$* request, "
+                   "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
+                   "::grpc::CompletionQueue* cq, void *tag);\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "void Request$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
+                   "::grpc::CompletionQueue* cq, void *tag);\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "void Request$Method$("
+                   "::grpc::ServerContext* context, $Request$* request, "
+                   "::grpc::ServerAsyncWriter< $Response$>* writer, "
+                   "::grpc::CompletionQueue* cq, void *tag);\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(
+        *vars,
+        "void Request$Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
+        "::grpc::CompletionQueue* cq, void *tag);\n");
+  }
+}
+
 void PrintHeaderService(google::protobuf::io::Printer *printer,
                         const google::protobuf::ServiceDescriptor *service,
                         std::map<std::string, std::string> *vars) {
   (*vars)["Service"] = service->name();
 
   printer->Print(*vars,
-                 "class $Service$ {\n"
+                 "class $Service$ final {\n"
                  " public:\n");
   printer->Indent();
 
   // Client side
   printer->Print(
-      "class Stub : public ::grpc::InternalStub {\n"
+      "class Stub final : public ::grpc::InternalStub {\n"
       " public:\n");
   printer->Indent();
   for (int i = 0; i < service->method_count(); ++i) {
@@ -220,23 +314,37 @@ void PrintHeaderService(google::protobuf::io::Printer *printer,
 
   printer->Print("\n");
 
-  // Server side
+  // Server side - Synchronous
   printer->Print(
-      "class Service {\n"
+      "class Service : public ::grpc::SynchronousService {\n"
       " public:\n");
   printer->Indent();
   printer->Print("Service() : service_(nullptr) {}\n");
   printer->Print("virtual ~Service();\n");
   for (int i = 0; i < service->method_count(); ++i) {
-    PrintHeaderServerMethod(printer, service->method(i), vars);
+    PrintHeaderServerMethodSync(printer, service->method(i), vars);
   }
-  printer->Print("::grpc::RpcService* service();\n");
+  printer->Print("::grpc::RpcService* service() override final;\n");
   printer->Outdent();
   printer->Print(
       " private:\n"
       "  ::grpc::RpcService* service_;\n");
   printer->Print("};\n");
 
+  // Server side - Asynchronous
+  printer->Print(
+      "class AsyncService final : public ::grpc::AsynchronousService {\n"
+      " public:\n");
+  printer->Indent();
+  (*vars)["MethodCount"] = as_string(service->method_count());
+  printer->Print("explicit AsyncService(::grpc::CompletionQueue* cq);\n");
+  printer->Print("~AsyncService() {};\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderServerMethodAsync(printer, service->method(i), vars);
+  }
+  printer->Outdent();
+  printer->Print("};\n");
+
   printer->Outdent();
   printer->Print("};\n");
 }
@@ -268,10 +376,21 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
                    "::grpc::ClientContext* context, "
                    "const $Request$& request, $Response$* response) {\n");
     printer->Print(*vars,
-                   "  return channel()->StartBlockingRpc("
-                   "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\"), "
+                   "  return ::grpc::BlockingUnaryCall(channel(),"
+                   "::grpc::RpcMethod($Service$_method_names[$Idx$]), "
                    "context, request, response);\n"
                    "}\n\n");
+    printer->Print(*vars,
+                   "::grpc::ClientAsyncResponseReader< $Response$>* "
+                   "$Service$::Stub::$Method$(::grpc::ClientContext* context, "
+                   "const $Request$& request, "
+                   "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(*vars,
+                   "  return new ::grpc::ClientAsyncResponseReader< $Response$>("
+                   "channel(), cq, "
+                   "::grpc::RpcMethod($Service$_method_names[$Idx$]), "
+                   "context, request, tag);\n"
+                   "}\n\n");
   } else if (ClientOnlyStreaming(method)) {
     printer->Print(
         *vars,
@@ -279,22 +398,46 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
         "::grpc::ClientContext* context, $Response$* response) {\n");
     printer->Print(*vars,
                    "  return new ::grpc::ClientWriter< $Request$>("
-                   "channel()->CreateStream("
-                   "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
+                   "channel(),"
+                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
-                   "context, nullptr, response));\n"
+                   "context, response);\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "::grpc::ClientAsyncWriter< $Request$>* $Service$::Stub::$Method$("
+        "::grpc::ClientContext* context, $Response$* response, "
+        "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(*vars,
+                   "  return new ::grpc::ClientAsyncWriter< $Request$>("
+                   "channel(), cq, "
+                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
+                   "context, response, tag);\n"
                    "}\n\n");
   } else if (ServerOnlyStreaming(method)) {
     printer->Print(
         *vars,
         "::grpc::ClientReader< $Response$>* $Service$::Stub::$Method$("
-        "::grpc::ClientContext* context, const $Request$* request) {\n");
+        "::grpc::ClientContext* context, const $Request$& request) {\n");
     printer->Print(*vars,
                    "  return new ::grpc::ClientReader< $Response$>("
-                   "channel()->CreateStream("
-                   "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
+                   "channel(),"
+                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+                   "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
+                   "context, request);\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "::grpc::ClientAsyncReader< $Response$>* $Service$::Stub::$Method$("
+        "::grpc::ClientContext* context, const $Request$& request, "
+        "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(*vars,
+                   "  return new ::grpc::ClientAsyncReader< $Response$>("
+                   "channel(), cq, "
+                   "::grpc::RpcMethod($Service$_method_names[$Idx$], "
                    "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
-                   "context, request, nullptr));\n"
+                   "context, request, tag);\n"
                    "}\n\n");
   } else if (BidiStreaming(method)) {
     printer->Print(
@@ -304,10 +447,23 @@ void PrintSourceClientMethod(google::protobuf::io::Printer *printer,
     printer->Print(
         *vars,
         "  return new ::grpc::ClientReaderWriter< $Request$, $Response$>("
-        "channel()->CreateStream("
-        "::grpc::RpcMethod(\"/$Package$$Service$/$Method$\", "
+        "channel(),"
+        "::grpc::RpcMethod($Service$_method_names[$Idx$], "
+        "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
+        "context);\n"
+        "}\n\n");
+    printer->Print(
+        *vars,
+        "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+        "$Service$::Stub::$Method$(::grpc::ClientContext* context, "
+        "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(
+        *vars,
+        "  return new ::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
+        "channel(), cq, "
+        "::grpc::RpcMethod($Service$_method_names[$Idx$], "
         "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
-        "context, nullptr, nullptr));\n"
+        "context, tag);\n"
         "}\n\n");
   }
 }
@@ -362,10 +518,73 @@ void PrintSourceServerMethod(google::protobuf::io::Printer *printer,
   }
 }
 
+void PrintSourceServerAsyncMethod(
+    google::protobuf::io::Printer *printer,
+    const google::protobuf::MethodDescriptor *method,
+    std::map<std::string, std::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] =
+      grpc_cpp_generator::ClassName(method->input_type(), true);
+  (*vars)["Response"] =
+      grpc_cpp_generator::ClassName(method->output_type(), true);
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+                   "void $Service$::AsyncService::Request$Method$("
+                   "::grpc::ServerContext* context, "
+                   "$Request$* request, "
+                   "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
+                   "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(
+        *vars,
+        "  AsynchronousService::RequestAsyncUnary($Idx$, context, request, response, cq, tag);\n");
+    printer->Print("}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "void $Service$::AsyncService::Request$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
+                   "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(
+        *vars,
+        "  AsynchronousService::RequestClientStreaming($Idx$, context, reader, cq, tag);\n");
+    printer->Print("}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "void $Service$::AsyncService::Request$Method$("
+                   "::grpc::ServerContext* context, "
+                   "$Request$* request, "
+                   "::grpc::ServerAsyncWriter< $Response$>* writer, "
+                   "::grpc::CompletionQueue* cq, void* tag) {\n");
+    printer->Print(
+        *vars,
+        "  AsynchronousService::RequestServerStreaming($Idx$, context, request, writer, cq, tag);\n");
+    printer->Print("}\n\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(
+        *vars,
+        "void $Service$::AsyncService::Request$Method$("
+        "::grpc::ServerContext* context, "
+        "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
+        "::grpc::CompletionQueue* cq, void *tag) {\n");
+    printer->Print(
+        *vars,
+        "  AsynchronousService::RequestBidiStreaming($Idx$, context, stream, cq, tag);\n");
+    printer->Print("}\n\n");
+  }
+}
+
 void PrintSourceService(google::protobuf::io::Printer *printer,
                         const google::protobuf::ServiceDescriptor *service,
                         std::map<std::string, std::string> *vars) {
   (*vars)["Service"] = service->name();
+
+  printer->Print(*vars, "static const char* $Service$_method_names[] = {\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Method"] = service->method(i)->name();
+    printer->Print(*vars, "  \"/$Package$$Service$/$Method$\",\n");
+  }
+  printer->Print(*vars, "};\n\n");
+
   printer->Print(
       *vars,
       "$Service$::Stub* $Service$::NewStub("
@@ -375,15 +594,25 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
       "  return stub;\n"
       "};\n\n");
   for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
     PrintSourceClientMethod(printer, service->method(i), vars);
   }
 
+  (*vars)["MethodCount"] = as_string(service->method_count());
+  printer->Print(
+      *vars,
+      "$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : "
+      "::grpc::AsynchronousService(cq, $Service$_method_names, $MethodCount$) "
+      "{}\n\n");
+
   printer->Print(*vars,
                  "$Service$::Service::~Service() {\n"
                  "  delete service_;\n"
                  "}\n\n");
   for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
     PrintSourceServerMethod(printer, service->method(i), vars);
+    PrintSourceServerAsyncMethod(printer, service->method(i), vars);
   }
   printer->Print(*vars,
                  "::grpc::RpcService* $Service$::Service::service() {\n");
@@ -395,6 +624,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
   printer->Print("service_ = new ::grpc::RpcService();\n");
   for (int i = 0; i < service->method_count(); ++i) {
     const google::protobuf::MethodDescriptor *method = service->method(i);
+    (*vars)["Idx"] = as_string(i);
     (*vars)["Method"] = method->name();
     (*vars)["Request"] =
         grpc_cpp_generator::ClassName(method->input_type(), true);
@@ -404,7 +634,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    \"/$Package$$Service$/$Method$\",\n"
+          "    $Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::NORMAL_RPC,\n"
           "    new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, "
           "$Response$>(\n"
@@ -416,7 +646,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    \"/$Package$$Service$/$Method$\",\n"
+          "    $Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::CLIENT_STREAMING,\n"
           "    new ::grpc::ClientStreamingHandler< "
           "$Service$::Service, $Request$, $Response$>(\n"
@@ -429,7 +659,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    \"/$Package$$Service$/$Method$\",\n"
+          "    $Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::SERVER_STREAMING,\n"
           "    new ::grpc::ServerStreamingHandler< "
           "$Service$::Service, $Request$, $Response$>(\n"
@@ -442,7 +672,7 @@ void PrintSourceService(google::protobuf::io::Printer *printer,
       printer->Print(
           *vars,
           "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
-          "    \"/$Package$$Service$/$Method$\",\n"
+          "    $Service$_method_names[$Idx$],\n"
           "    ::grpc::RpcMethod::BIDI_STREAMING,\n"
           "    new ::grpc::BidiStreamingHandler< "
           "$Service$::Service, $Request$, $Response$>(\n"
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index fe84d08b4c8a9a7453df6b587cf84db4053e84e4..f5b1ad23eee19d3cbfe524434cbde85a1cd63f54 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/cpp_generator_helpers.h b/src/compiler/cpp_generator_helpers.h
index 54c343866fc6bc25853ac7e6bc8ee0e541a2be45..e3c76e029127e7c06c97b1a18599b2df6e2614ba 100644
--- a/src/compiler/cpp_generator_helpers.h
+++ b/src/compiler/cpp_generator_helpers.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index a7fdb1f093f01c1ba5c978a301a2bcf26cb5877f..a421e51b78d94e88dc8f3e4fa1309910882c5afa 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cdd3d8a98a5c023cbdc811445d4061c5cc50607a
--- /dev/null
+++ b/src/compiler/python_generator.cc
@@ -0,0 +1,330 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <cassert>
+#include <cctype>
+#include <map>
+#include <ostream>
+#include <sstream>
+
+#include "src/compiler/python_generator.h"
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+
+using google::protobuf::FileDescriptor;
+using google::protobuf::ServiceDescriptor;
+using google::protobuf::MethodDescriptor;
+using google::protobuf::io::Printer;
+using google::protobuf::io::StringOutputStream;
+using std::initializer_list;
+using std::map;
+using std::string;
+
+namespace grpc_python_generator {
+namespace {
+//////////////////////////////////
+// BEGIN FORMATTING BOILERPLATE //
+//////////////////////////////////
+
+// Converts an initializer list of the form { key0, value0, key1, value1, ... }
+// into a map of key* to value*. Is merely a readability helper for later code.
+map<string, string> ListToDict(const initializer_list<string>& values) {
+  assert(values.size() % 2 == 0);
+  map<string, string> value_map;
+  auto value_iter = values.begin();
+  for (unsigned i = 0; i < values.size()/2; ++i) {
+    string key = *value_iter;
+    ++value_iter;
+    string value = *value_iter;
+    value_map[key] = value;
+    ++value_iter;
+  }
+  return value_map;
+}
+
+// Provides RAII indentation handling. Use as:
+// {
+//   IndentScope raii_my_indent_var_name_here(my_py_printer);
+//   // constructor indented my_py_printer
+//   ...
+//   // destructor called at end of scope, un-indenting my_py_printer
+// }
+class IndentScope {
+ public:
+  explicit IndentScope(Printer* printer) : printer_(printer) {
+    printer_->Indent();
+  }
+
+  ~IndentScope() {
+    printer_->Outdent();
+  }
+
+ private:
+  Printer* printer_;
+};
+
+////////////////////////////////
+// END FORMATTING BOILERPLATE //
+////////////////////////////////
+
+void PrintService(const ServiceDescriptor* service,
+                  Printer* out) {
+  string doc = "<fill me in later!>";
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+        "Documentation", doc,
+      });
+  out->Print(dict, "class $Service$Service(object):\n");
+  {
+    IndentScope raii_class_indent(out);
+    out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+    out->Print("def __init__(self):\n");
+    {
+      IndentScope raii_method_indent(out);
+      out->Print("pass\n");
+    }
+  }
+}
+
+void PrintServicer(const ServiceDescriptor* service,
+                   Printer* out) {
+  string doc = "<fill me in later!>";
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+        "Documentation", doc,
+      });
+  out->Print(dict, "class $Service$Servicer(object):\n");
+  {
+    IndentScope raii_class_indent(out);
+    out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+    for (int i = 0; i < service->method_count(); ++i) {
+      auto meth = service->method(i);
+      out->Print("def $Method$(self, arg):\n", "Method", meth->name());
+      {
+        IndentScope raii_method_indent(out);
+        out->Print("raise NotImplementedError()\n");
+      }
+    }
+  }
+}
+
+void PrintStub(const ServiceDescriptor* service,
+               Printer* out) {
+  string doc = "<fill me in later!>";
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+        "Documentation", doc,
+      });
+  out->Print(dict, "class $Service$Stub(object):\n");
+  {
+    IndentScope raii_class_indent(out);
+    out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+    for (int i = 0; i < service->method_count(); ++i) {
+      const MethodDescriptor* meth = service->method(i);
+      auto methdict = ListToDict({"Method", meth->name()});
+      out->Print(methdict, "def $Method$(self, arg):\n");
+      {
+        IndentScope raii_method_indent(out);
+        out->Print("raise NotImplementedError()\n");
+      }
+      out->Print(methdict, "$Method$.async = None\n");
+    }
+  }
+}
+
+void PrintStubImpl(const ServiceDescriptor* service,
+                   Printer* out) {
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+      });
+  out->Print(dict, "class _$Service$Stub($Service$Stub):\n");
+  {
+    IndentScope raii_class_indent(out);
+    out->Print("def __init__(self, face_stub, default_timeout):\n");
+    {
+      IndentScope raii_method_indent(out);
+      out->Print("self._face_stub = face_stub\n"
+                 "self._default_timeout = default_timeout\n"
+                 "stub_self = self\n");
+
+      for (int i = 0; i < service->method_count(); ++i) {
+        const MethodDescriptor* meth = service->method(i);
+        bool server_streaming = meth->server_streaming();
+        bool client_streaming = meth->client_streaming();
+        std::string blocking_call, future_call;
+        if (server_streaming) {
+          if (client_streaming) {
+            blocking_call = "stub_self._face_stub.inline_stream_in_stream_out";
+            future_call = blocking_call;
+          } else {
+            blocking_call = "stub_self._face_stub.inline_value_in_stream_out";
+            future_call = blocking_call;
+          }
+        } else {
+          if (client_streaming) {
+            blocking_call = "stub_self._face_stub.blocking_stream_in_value_out";
+            future_call = "stub_self._face_stub.future_stream_in_value_out";
+          } else {
+            blocking_call = "stub_self._face_stub.blocking_value_in_value_out";
+            future_call = "stub_self._face_stub.future_value_in_value_out";
+          }
+        }
+        // TODO(atash): use the solution described at
+        // http://stackoverflow.com/a/2982 to bind 'async' attribute
+        // functions to def'd functions instead of using callable attributes.
+        auto methdict = ListToDict({
+          "Method", meth->name(),
+          "BlockingCall", blocking_call,
+          "FutureCall", future_call
+        });
+        out->Print(methdict, "class $Method$(object):\n");
+        {
+          IndentScope raii_callable_indent(out);
+          out->Print("def __call__(self, arg):\n");
+          {
+            IndentScope raii_callable_call_indent(out);
+            out->Print(methdict,
+                       "return $BlockingCall$(\"$Method$\", arg, "
+                       "stub_self._default_timeout)\n");
+          }
+          out->Print("def async(self, arg):\n");
+          {
+            IndentScope raii_callable_async_indent(out);
+            out->Print(methdict,
+                       "return $FutureCall$(\"$Method$\", arg, "
+                       "stub_self._default_timeout)\n");
+          }
+        }
+        out->Print(methdict, "self.$Method$ = $Method$()\n");
+      }
+    }
+  }
+}
+
+void PrintStubGenerators(const ServiceDescriptor* service, Printer* out) {
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+      });
+  // Write out a generator of linked pairs of Server/Stub
+  out->Print(dict, "def mock_$Service$(servicer, default_timeout):\n");
+  {
+    IndentScope raii_mock_indent(out);
+    out->Print("value_in_value_out = {}\n"
+               "value_in_stream_out = {}\n"
+               "stream_in_value_out = {}\n"
+               "stream_in_stream_out = {}\n");
+    for (int i = 0; i < service->method_count(); ++i) {
+      const MethodDescriptor* meth = service->method(i);
+      std::string super_interface, meth_dict;
+      bool server_streaming = meth->server_streaming();
+      bool client_streaming = meth->client_streaming();
+      if (server_streaming) {
+        if (client_streaming) {
+          super_interface = "InlineStreamInStreamOutMethod";
+          meth_dict = "stream_in_stream_out";
+        } else {
+          super_interface = "InlineValueInStreamOutMethod";
+          meth_dict = "value_in_stream_out";
+        }
+      } else {
+        if (client_streaming) {
+          super_interface = "InlineStreamInValueOutMethod";
+          meth_dict = "stream_in_value_out";
+        } else {
+          super_interface = "InlineValueInValueOutMethod";
+          meth_dict = "value_in_value_out";
+        }
+      }
+      map<string, string> methdict = ListToDict({
+            "Method", meth->name(),
+            "SuperInterface", super_interface,
+            "MethodDict", meth_dict
+          });
+      out->Print(
+          methdict, "class $Method$(_face_interfaces.$SuperInterface$):\n");
+      {
+        IndentScope raii_inline_class_indent(out);
+        out->Print("def service(self, request, context):\n");
+        {
+          IndentScope raii_inline_class_fn_indent(out);
+          out->Print(methdict, "return servicer.$Method$(request)\n");
+        }
+      }
+      out->Print(methdict, "$MethodDict$['$Method$'] = $Method$()\n");
+    }
+    out->Print(
+         "face_linked_pair = _face_testing.server_and_stub(default_timeout,"
+         "inline_value_in_value_out_methods=value_in_value_out,"
+         "inline_value_in_stream_out_methods=value_in_stream_out,"
+         "inline_stream_in_value_out_methods=stream_in_value_out,"
+         "inline_stream_in_stream_out_methods=stream_in_stream_out)\n");
+    out->Print("class LinkedPair(object):\n");
+    {
+      IndentScope raii_linked_pair(out);
+      out->Print("def __init__(self, server, stub):\n");
+      {
+        IndentScope raii_linked_pair_init(out);
+        out->Print("self.server = server\n"
+                   "self.stub = stub\n");
+      }
+    }
+    out->Print(
+        dict,
+        "stub = _$Service$Stub(face_linked_pair.stub, default_timeout)\n");
+    out->Print("return LinkedPair(None, stub)\n");
+  }
+}
+
+}  // namespace
+
+string GetServices(const FileDescriptor* file) {
+  string output;
+  StringOutputStream output_stream(&output);
+  Printer out(&output_stream, '$');
+  out.Print("from grpc.framework.face import demonstration as _face_testing\n");
+  out.Print("from grpc.framework.face import interfaces as _face_interfaces\n");
+
+  for (int i = 0; i < file->service_count(); ++i) {
+    auto service = file->service(i);
+    PrintService(service, &out);
+    PrintServicer(service, &out);
+    PrintStub(service, &out);
+    PrintStubImpl(service, &out);
+    PrintStubGenerators(service, &out);
+  }
+  return output;
+}
+
+}  // namespace grpc_python_generator
diff --git a/include/grpc++/stream_context_interface.h b/src/compiler/python_generator.h
similarity index 68%
rename from include/grpc++/stream_context_interface.h
rename to src/compiler/python_generator.h
index a84119800b77f2d2558e8501d55815230464f79c..673ef7b23b30730b1365038e11b8f08334031fe5 100644
--- a/include/grpc++/stream_context_interface.h
+++ b/src/compiler/python_generator.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,34 +31,21 @@
  *
  */
 
-#ifndef __GRPCPP_STREAM_CONTEXT_INTERFACE_H__
-#define __GRPCPP_STREAM_CONTEXT_INTERFACE_H__
+#ifndef __GRPC_COMPILER_PYTHON_GENERATOR_H__
+#define __GRPC_COMPILER_PYTHON_GENERATOR_H__
+
+#include <string>
 
 namespace google {
 namespace protobuf {
-class Message;
-}
-}
-
-namespace grpc {
-class Status;
-
-// An interface to avoid dependency on internal implementation.
-class StreamContextInterface {
- public:
-  virtual ~StreamContextInterface() {}
-
-  virtual void Start(bool buffered) = 0;
+class FileDescriptor;
+}  // namespace protobuf
+}  // namespace google
 
-  virtual bool Read(google::protobuf::Message* msg) = 0;
-  virtual bool Write(const google::protobuf::Message* msg, bool is_last) = 0;
-  virtual const Status& Wait() = 0;
-  virtual void Cancel() = 0;
+namespace grpc_python_generator {
 
-  virtual google::protobuf::Message* request() = 0;
-  virtual google::protobuf::Message* response() = 0;
-};
+std::string GetServices(const google::protobuf::FileDescriptor* file);
 
-}  // namespace grpc
+}  // namespace grpc_python_generator
 
-#endif  // __GRPCPP_STREAM_CONTEXT_INTERFACE_H__
+#endif  // __GRPC_COMPILER_PYTHON_GENERATOR_H__
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ebe3660619b42b546e3ca7d81d39805f65f3922e
--- /dev/null
+++ b/src/compiler/python_plugin.cc
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// Generates a Python gRPC service interface out of Protobuf IDL.
+
+#include <memory>
+#include <string>
+
+#include "src/compiler/python_generator.h"
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/plugin.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.h>
+
+using google::protobuf::FileDescriptor;
+using google::protobuf::compiler::CodeGenerator;
+using google::protobuf::compiler::GeneratorContext;
+using google::protobuf::compiler::PluginMain;
+using google::protobuf::io::CodedOutputStream;
+using google::protobuf::io::ZeroCopyOutputStream;
+using std::string;
+
+class PythonGrpcGenerator : public CodeGenerator {
+ public:
+  PythonGrpcGenerator() {}
+  ~PythonGrpcGenerator() override {}
+
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                GeneratorContext* context,
+                string* error) const override {
+    // Get output file name.
+    string file_name;
+    static const int proto_suffix_length = 6;  // length of ".proto"
+    if (file->name().size() > proto_suffix_length &&
+        file->name().find_last_of(".proto") == file->name().size() - 1) {
+      file_name = file->name().substr(
+          0, file->name().size() - proto_suffix_length) + "_pb2.py";
+    } else {
+      *error = "Invalid proto file name. Proto file must end with .proto";
+      return false;
+    }
+
+    std::unique_ptr<ZeroCopyOutputStream> output(
+        context->OpenForInsert(file_name, "module_scope"));
+    CodedOutputStream coded_out(output.get());
+    string code = grpc_python_generator::GetServices(file);
+    coded_out.WriteRaw(code.data(), code.size());
+    return true;
+  }
+};
+
+int main(int argc, char* argv[]) {
+  PythonGrpcGenerator generator;
+  return PluginMain(argc, argv, &generator);
+}
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index 8196589a5c4a941abb581e3eb9fbd31b6515e195..32b6a8d8e4a0537db5b62583e6040c4b4cbece36 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/ruby_generator.h b/src/compiler/ruby_generator.h
index 89d7a0b92a9f5c9942660a4a68b12bb69490bc61..d0c568fad0f1677416ab1caa54b31e310410ef22 100644
--- a/src/compiler/ruby_generator.h
+++ b/src/compiler/ruby_generator.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h
index 0034f5ef569bd9d64f22cfb17496606e10728ad3..61d887b41cd560c49e5a90b00dcb34d068e31e71 100644
--- a/src/compiler/ruby_generator_helpers-inl.h
+++ b/src/compiler/ruby_generator_helpers-inl.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/ruby_generator_map-inl.h b/src/compiler/ruby_generator_map-inl.h
index fea9c2e2fac616c40c0ae2e96d46ebc90eb719f2..345e4c13706a7df64bd52cdf1484c7a784fef182 100644
--- a/src/compiler/ruby_generator_map-inl.h
+++ b/src/compiler/ruby_generator_map-inl.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index d24a61b9f5f976c20d3feb9416c9f815d148c33d..7c2e4e5d9d4ad9db9116c9afe540317defc6154a 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/compiler/ruby_plugin.cc b/src/compiler/ruby_plugin.cc
index 9397452f55ea60f037933e70da77395c68f28d81..6580e5ab5bec861f25288d6f6572e1dc9d1dd05e 100644
--- a/src/compiler/ruby_plugin.cc
+++ b/src/compiler/ruby_plugin.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/README.md b/src/core/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..407dc4f70191b5aae336c2cb079238cb35327768
--- /dev/null
+++ b/src/core/README.md
@@ -0,0 +1,9 @@
+#Overview
+
+This directory contains source code for shared C library. Libraries in other languages in this repository (C++, Ruby,
+Python, PHP, NodeJS, Objective-C) are layered on top of this library.
+
+#Status
+
+Alpha : Ready for early adopters
+
diff --git a/src/core/channel/call_op_string.c b/src/core/channel/call_op_string.c
index 127ea707bf52e5c8906c9be64e2faab1fe3bd4a0..08f2e95deb643f57e466411b50cf3ebcdba3dad7 100644
--- a/src/core/channel/call_op_string.c
+++ b/src/core/channel/call_op_string.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c
index 3447e9dde455fa17c5fe492e262c14f6e802b5ca..ba7b7ba59caa6293138ce42aa95ba004492bfb55 100644
--- a/src/core/channel/census_filter.c
+++ b/src/core/channel/census_filter.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/census_filter.h b/src/core/channel/census_filter.h
index 5b2c01ca9ba40514baccc505616af70367c686ed..6acf9695f47a6bd302595bd8ebbb5afbed560f48 100644
--- a/src/core/channel/census_filter.h
+++ b/src/core/channel/census_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c
index f48415e63466d078fa9d255502f2783b00d7040b..509ae0df8968ad73ca6b6c2e2fcad5b01a96c4f7 100644
--- a/src/core/channel/channel_args.c
+++ b/src/core/channel/channel_args.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h
index 92280450a145739a656379ab95ce8e0040694e38..640bbd85a5f28ca2fcc2ac112702cb1ebbe819f5 100644
--- a/src/core/channel/channel_args.h
+++ b/src/core/channel/channel_args.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c
index d9e722c4f1e35de544570efd07bed99c9d073383..0382a7a2f3038b7ae6d44919ff8f9d51c85e8a82 100644
--- a/src/core/channel/channel_stack.c
+++ b/src/core/channel/channel_stack.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
index ec9ecf3d15a3da34a723f6309397293d6f493ee6..98d095fccf1624f463e09b8c334c847a22ce2910 100644
--- a/src/core/channel/channel_stack.h
+++ b/src/core/channel/channel_stack.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/child_channel.c b/src/core/channel/child_channel.c
index a7f06bcdc02625a1e7cd8c8409a83eab0d17ab69..2cb03829c7903589a80227b185670bd03189d8bb 100644
--- a/src/core/channel/child_channel.c
+++ b/src/core/channel/child_channel.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/child_channel.h b/src/core/channel/child_channel.h
index ece0ff99a925de34526241a7d10c115a01f80a36..84a11062cbe3689234828520e1348e39648ba4e9 100644
--- a/src/core/channel/child_channel.h
+++ b/src/core/channel/child_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 8e8f95fdb357d3a8235c2adbc3321b81bd49d7cb..9791f98be88de31f17a345d0a6695711ff64b9c6 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h
index 6b8a7d95a8a8508f63835d50e1ddea067aa2fd77..7da4fc925804ce80a6eadec235e87785fefeb450 100644
--- a/src/core/channel/client_channel.h
+++ b/src/core/channel/client_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/client_setup.c b/src/core/channel/client_setup.c
index ebaf816902b8a945223ae356803cec9f10fb736d..6d892d6c924fe01078d931641ab6c85d1064ddfb 100644
--- a/src/core/channel/client_setup.c
+++ b/src/core/channel/client_setup.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -49,8 +49,11 @@ struct grpc_client_setup {
   grpc_alarm backoff_alarm;
   gpr_timespec current_backoff_interval;
   int in_alarm;
+  int in_cb;
+  int cancelled;
 
   gpr_mu mu;
+  gpr_cv cv;
   grpc_client_setup_request *active_request;
   int refs;
 };
@@ -67,6 +70,7 @@ gpr_timespec grpc_client_setup_request_deadline(grpc_client_setup_request *r) {
 
 static void destroy_setup(grpc_client_setup *s) {
   gpr_mu_destroy(&s->mu);
+  gpr_cv_destroy(&s->cv);
   s->done(s->user_data);
   grpc_channel_args_destroy(s->args);
   gpr_free(s);
@@ -111,6 +115,10 @@ static void setup_cancel(grpc_transport_setup *sp) {
   int cancel_alarm = 0;
 
   gpr_mu_lock(&s->mu);
+  s->cancelled = 1;
+  while (s->in_cb) {
+    gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
+  }
 
   GPR_ASSERT(s->refs > 0);
   /* effectively cancels the current request (if any) */
@@ -129,6 +137,24 @@ static void setup_cancel(grpc_transport_setup *sp) {
   }
 }
 
+int grpc_client_setup_cb_begin(grpc_client_setup_request *r) {
+  gpr_mu_lock(&r->setup->mu);
+  if (r->setup->cancelled) {
+    gpr_mu_unlock(&r->setup->mu);
+    return 0;
+  }
+  r->setup->in_cb++;
+  gpr_mu_unlock(&r->setup->mu);
+  return 1;
+}
+
+void grpc_client_setup_cb_end(grpc_client_setup_request *r) {
+  gpr_mu_lock(&r->setup->mu);
+  r->setup->in_cb--;
+  if (r->setup->cancelled) gpr_cv_signal(&r->setup->cv);
+  gpr_mu_unlock(&r->setup->mu);
+}
+
 /* vtable for transport setup */
 static const grpc_transport_setup_vtable setup_vtable = {setup_initiate,
                                                          setup_cancel};
@@ -142,6 +168,7 @@ void grpc_client_setup_create_and_attach(
 
   s->base.vtable = &setup_vtable;
   gpr_mu_init(&s->mu);
+  gpr_cv_init(&s->cv);
   s->refs = 1;
   s->mdctx = mdctx;
   s->initiate = initiate;
@@ -151,6 +178,8 @@ void grpc_client_setup_create_and_attach(
   s->args = grpc_channel_args_copy(args);
   s->current_backoff_interval = gpr_time_from_micros(1000000);
   s->in_alarm = 0;
+  s->in_cb = 0;
+  s->cancelled = 0;
 
   grpc_client_channel_set_transport_setup(newly_minted_channel, &s->base);
 }
diff --git a/src/core/channel/client_setup.h b/src/core/channel/client_setup.h
index 155a9a5b1a7c04bb7d0f2e7b438a75b5bf5d813b..f2b64265bc333c55b9d404938319259f2720ad6c 100644
--- a/src/core/channel/client_setup.h
+++ b/src/core/channel/client_setup.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,12 @@ void grpc_client_setup_request_finish(grpc_client_setup_request *r,
 const grpc_channel_args *grpc_client_setup_get_channel_args(
     grpc_client_setup_request *r);
 
+/* Call before calling back into the setup listener, and call only if
+   this function returns 1. If it returns 1, also promise to call
+   grpc_client_setup_cb_end */
+int grpc_client_setup_cb_begin(grpc_client_setup_request *r);
+void grpc_client_setup_cb_end(grpc_client_setup_request *r);
+
 /* Get the deadline for a request passed in to initiate. Implementations should
    make a best effort to honor this deadline. */
 gpr_timespec grpc_client_setup_request_deadline(grpc_client_setup_request *r);
diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c
index 2d61d389e42302facc5d9fde6d72d56fdd0a5fbf..fa186551648e3a1839504b43d929ae1c7dc8bf48 100644
--- a/src/core/channel/connected_channel.c
+++ b/src/core/channel/connected_channel.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h
index 9d143fc1359b31b749732deafef5af57e9d0fb25..e19de62ca9418f0a292d79ce5bdcc5379720d65b 100644
--- a/src/core/channel/connected_channel.h
+++ b/src/core/channel/connected_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index a2b5f48f60887df2a5e54ed1d82ba6f58799eee5..3ccc39b717fa4ef836e20a438c4b64aee4c8beac 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/http_client_filter.h b/src/core/channel/http_client_filter.h
index 21cde4877ba2afe734639111ede420fae182725d..5882f8fe0574ea22a3290cba4bb0f824b58c66b4 100644
--- a/src/core/channel/http_client_filter.h
+++ b/src/core/channel/http_client_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/http_filter.c b/src/core/channel/http_filter.c
index eaa746ef20818fc0b2331e0c539106e33b5f1de9..453a0422d85a48064518fa324b3b9c724cdf886d 100644
--- a/src/core/channel/http_filter.c
+++ b/src/core/channel/http_filter.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/http_filter.h b/src/core/channel/http_filter.h
index 89ad482d358ae7a2b92d1bff640f90da01ebad30..b85cd3956ebae4106acc2c5f5617fe02364e66d2 100644
--- a/src/core/channel/http_filter.h
+++ b/src/core/channel/http_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index b70af434a7981055687fbc822003f174dbef98f1..d1616a3450dc0953d3afcb7cf9480da4a166a339 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/http_server_filter.h b/src/core/channel/http_server_filter.h
index 5b475432aa27390c0b77b73f92b2174110e3ab82..0643c7be83c1db4c91961a9b1d35a2deb2275d2d 100644
--- a/src/core/channel/http_server_filter.h
+++ b/src/core/channel/http_server_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/metadata_buffer.c b/src/core/channel/metadata_buffer.c
index a21a37ea7dc4faf379c13723fc5c4cfbaf115a8e..da66a028c4d972802587efa3568a065e88b513fd 100644
--- a/src/core/channel/metadata_buffer.c
+++ b/src/core/channel/metadata_buffer.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/metadata_buffer.h b/src/core/channel/metadata_buffer.h
index 011dabed1b11b445bd3b122c8a16a9e323fcbdb3..701d69df7c58c305dfc9d3a727112d22a45e2075 100644
--- a/src/core/channel/metadata_buffer.h
+++ b/src/core/channel/metadata_buffer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/noop_filter.c b/src/core/channel/noop_filter.c
index d5615f7ae685b09dbed9204c6400c6e9e35282f5..d987fa2bc10febe63bb5cfd428bdadbc1211d37c 100644
--- a/src/core/channel/noop_filter.c
+++ b/src/core/channel/noop_filter.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/channel/noop_filter.h b/src/core/channel/noop_filter.h
index 269214f893fa7d6e0ea287f1bd884aa0aa940afd..93c2bff9b02812e09818998bf7fb6f1d0473959d 100644
--- a/src/core/channel/noop_filter.h
+++ b/src/core/channel/noop_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/compression/algorithm.c b/src/core/compression/algorithm.c
index 0b5576f70a66fbb577304fbb12737c213131236a..ca07002ff94337e1f3535cea7750b2cdc562db88 100644
--- a/src/core/compression/algorithm.c
+++ b/src/core/compression/algorithm.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/compression/algorithm.h b/src/core/compression/algorithm.h
index c5ec6d21b68f954bbf5665b156eb6baaadf5b3d8..e398ae34b4cb80bbd3cbb46093d759226a2b05c9 100644
--- a/src/core/compression/algorithm.h
+++ b/src/core/compression/algorithm.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/compression/message_compress.c b/src/core/compression/message_compress.c
index 1787ccd7d8f666d550b5b6e5aa7672a4a76668f7..9b8100a3d6c2ae66e2297025296b9fc8fa598e3b 100644
--- a/src/core/compression/message_compress.c
+++ b/src/core/compression/message_compress.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/compression/message_compress.h b/src/core/compression/message_compress.h
index 564ca69a8779457852eb44793d07047572720ac1..666da2ed0d655d88e0a90c1dde86fe5f4dd61918 100644
--- a/src/core/compression/message_compress.h
+++ b/src/core/compression/message_compress.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/format_request.c b/src/core/httpcli/format_request.c
index 5d1a04ef826418fdc947ad367d149b8299c436ab..af2521908472c3606bd41772b28d4ce9ba75a365 100644
--- a/src/core/httpcli/format_request.c
+++ b/src/core/httpcli/format_request.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/format_request.h b/src/core/httpcli/format_request.h
index a82130cb93afc0ba46654746fc6cb91e60ce6196..e06b632990304a4d9c06ae2506d65d2e2d3b96d6 100644
--- a/src/core/httpcli/format_request.h
+++ b/src/core/httpcli/format_request.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
index acd9fa7b55bb7d8ea2142aa2e23b2fabd2a91e22..8a1c04b631ede4d19ff7ac42777a4ab78006900c 100644
--- a/src/core/httpcli/httpcli.c
+++ b/src/core/httpcli/httpcli.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index 90f89a93664d56983aa21e1a3b003a6190dace8b..f62098776801b51e10dd6042df214e11ab1f6b85 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/httpcli_security_context.c b/src/core/httpcli/httpcli_security_context.c
index 53e887ccd145947751aca39b54630e9492be89eb..e97752bbe192238018605192b20331408b70f3f0 100644
--- a/src/core/httpcli/httpcli_security_context.c
+++ b/src/core/httpcli/httpcli_security_context.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/httpcli_security_context.h b/src/core/httpcli/httpcli_security_context.h
index a73ecca0b373bfa6a577a012a214bb8e032e08a8..5a1311e7a41f145cec49585b5c79c44866663a0d 100644
--- a/src/core/httpcli/httpcli_security_context.h
+++ b/src/core/httpcli/httpcli_security_context.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c
index 1f0c5167de7a0c9236cebfc87cb6e231e85dd85a..f4decda98a97a9c73329abb03965c977f4833a06 100644
--- a/src/core/httpcli/parser.c
+++ b/src/core/httpcli/parser.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/httpcli/parser.h b/src/core/httpcli/parser.h
index 520b16fd020d26d0d1a6a73e17ebafc4f84cdee2..db1fa0a33c8bff2720a89906cc033cad3eb0450f 100644
--- a/src/core/httpcli/parser.h
+++ b/src/core/httpcli/parser.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/alarm.c b/src/core/iomgr/alarm.c
index 7884b21a1e28c8783c661a61b49610a14e31a6f4..5860834de3f32b317cc8dbd0308e755fe7869155 100644
--- a/src/core/iomgr/alarm.c
+++ b/src/core/iomgr/alarm.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/alarm.h b/src/core/iomgr/alarm.h
index f94dcec6e9981971edc9e96590bb0178b3e7c230..6dcc63a6d58b2a58726169fc72ac4e2bc0eb647b 100644
--- a/src/core/iomgr/alarm.h
+++ b/src/core/iomgr/alarm.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/alarm_heap.c b/src/core/iomgr/alarm_heap.c
index 2b6198336fea0825f61bc4fc92d9b5c17b686960..d912178fda34d044d44f8944f4ba9f670f76a3f9 100644
--- a/src/core/iomgr/alarm_heap.c
+++ b/src/core/iomgr/alarm_heap.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/alarm_heap.h b/src/core/iomgr/alarm_heap.h
index e51f96dd440c00d4d731939742c39367ec82a82d..bb6e5e3a899830a6420cdb9d4348431c21eeb870 100644
--- a/src/core/iomgr/alarm_heap.h
+++ b/src/core/iomgr/alarm_heap.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/alarm_internal.h b/src/core/iomgr/alarm_internal.h
index 8503292fd1adfe7e3dc961445a14dc6419c7551d..cbd8fa9421f2b2c7bcccf2d5b0748be54764a46f 100644
--- a/src/core/iomgr/alarm_internal.h
+++ b/src/core/iomgr/alarm_internal.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@
 
 /* iomgr internal api for dealing with alarms */
 
-/* Check for alarms to be run, and run them. 
+/* Check for alarms to be run, and run them.
    Return non zero if alarm callbacks were executed.
    Drops drop_mu if it is non-null before executing callbacks.
    If next is non-null, TRY to update *next with the next running alarm
diff --git a/src/core/iomgr/endpoint.c b/src/core/iomgr/endpoint.c
index 9e5d56389d2d90e026d92b344787d283bacde72f..96487958a7133245bc6d55b25ed3feb93d22b9f5 100644
--- a/src/core/iomgr/endpoint.c
+++ b/src/core/iomgr/endpoint.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/endpoint.h b/src/core/iomgr/endpoint.h
index ec86d9a14606594d313ea22799a27813fe7ac821..e89cf6691c08eff7c3029f616905b1a798f354c9 100644
--- a/src/core/iomgr/endpoint.h
+++ b/src/core/iomgr/endpoint.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/endpoint_pair.h b/src/core/iomgr/endpoint_pair.h
index 55678b5ddb1d696b6480fe118977c519f460934c..2e46aab2283bcd81df0a3a5aae7ad96152956ffa 100644
--- a/src/core/iomgr/endpoint_pair.h
+++ b/src/core/iomgr/endpoint_pair.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/endpoint_pair_posix.c b/src/core/iomgr/endpoint_pair_posix.c
index 3f53402cf3c5ffd6144ded9d9f9b9dabe02ebefc..ac511b97b2618fbcd7a14341afd1def1cc1a2b74 100644
--- a/src/core/iomgr/endpoint_pair_posix.c
+++ b/src/core/iomgr/endpoint_pair_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index cc5783055138ce8a9635937dce04bbaac45a9d4a..4f52339bc14d719a4486ae83d38866acb6105fb6 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -295,6 +295,8 @@ gpr_uint32 grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
                               grpc_fd_watcher *watcher) {
   /* keep track of pollers that have requested our events, in case they change
    */
+  grpc_fd_ref(fd);
+
   gpr_mu_lock(&fd->watcher_mu);
   watcher->next = &fd->watcher_root;
   watcher->prev = watcher->next->prev;
@@ -312,6 +314,8 @@ void grpc_fd_end_poll(grpc_fd_watcher *watcher) {
   watcher->next->prev = watcher->prev;
   watcher->prev->next = watcher->next;
   gpr_mu_unlock(&watcher->fd->watcher_mu);
+
+  grpc_fd_unref(watcher->fd);
 }
 
 void grpc_fd_become_readable(grpc_fd *fd, int allow_synchronous_callback) {
diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h
index 9a675087e593a85359490cc1b0eb78a42c1c1d9b..370ab1345a04e10ee2c2dfed8f06073aa0cf6e98 100644
--- a/src/core/iomgr/fd_posix.h
+++ b/src/core/iomgr/fd_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c
index 729b11b78dce153714c70df066e21016f9cfc5cc..8b019e804961c398d73cbb140763184cd1030309 100644
--- a/src/core/iomgr/iocp_windows.c
+++ b/src/core/iomgr/iocp_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h
index bf5b90978ef12556b24d62a74162edaa62fd5125..d0231702a16968cf4a9115029cd2119d5f65e69e 100644
--- a/src/core/iomgr/iocp_windows.h
+++ b/src/core/iomgr/iocp_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 3d6114ca18eec5275261b7b9aff14273b1644817..058685b295d0090bc2bd644761514d1f9bf969b2 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iomgr.h b/src/core/iomgr/iomgr.h
index 06dc2e5dbfaaab4f2b34d5ccdb401f2b9b0450a5..18a7d151fc7b91d4fdc24098c83645ca2ff04a1e 100644
--- a/src/core/iomgr/iomgr.h
+++ b/src/core/iomgr/iomgr.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h
index e9962a0f66beb4739963fd4c3a583c770352d296..7f29f44f7f98b638d7eaddd49b7e6826254f8a79 100644
--- a/src/core/iomgr/iomgr_internal.h
+++ b/src/core/iomgr/iomgr_internal.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iomgr_posix.c b/src/core/iomgr/iomgr_posix.c
index bbf8cfc4190d6dc06833827d3b06d9828fb8f516..14e3d182f666edb8915ccaf86fd1f17af181dfaa 100644
--- a/src/core/iomgr/iomgr_posix.c
+++ b/src/core/iomgr/iomgr_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iomgr_posix.h b/src/core/iomgr/iomgr_posix.h
index 86973a050dc1883b03bad3ca26c8245c982fc2e4..f9e9b3d6ee4ca4cc6f825f507a100a015fb358cf 100644
--- a/src/core/iomgr/iomgr_posix.h
+++ b/src/core/iomgr/iomgr_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/iomgr_windows.c b/src/core/iomgr/iomgr_windows.c
index a3a255eaed225598f646811e4799a3fbc960a239..f130ab9a078ead0ef81fd3ef68b2ef53d2b4eee0 100644
--- a/src/core/iomgr/iomgr_windows.c
+++ b/src/core/iomgr/iomgr_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h
index b9fcf45ea689e1503f3fed0165382460a662a2ac..9d04b014ba7074603da3fad9941fbfcc82345651 100644
--- a/src/core/iomgr/pollset.h
+++ b/src/core/iomgr/pollset.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/pollset_multipoller_with_epoll.c b/src/core/iomgr/pollset_multipoller_with_epoll.c
index 9fb28195062925e9de24d5829befd01519a6b08d..a1c3938a33ce7eb89dfa3101993533c8173e1df4 100644
--- a/src/core/iomgr/pollset_multipoller_with_epoll.c
+++ b/src/core/iomgr/pollset_multipoller_with_epoll.c
@@ -93,7 +93,7 @@ static int multipoll_with_epoll_pollset_maybe_work(
 
   /* If you want to ignore epoll's ability to sanely handle parallel pollers,
    * for a more apples-to-apples performance comparison with poll, add a
-   * if (pollset->counter == 0) { return 0 }
+   * if (pollset->counter != 0) { return 0; }
    * here.
    */
 
diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
index c136ee0b5286450801df577fe47d33d8ce1d9c8a..fbacad1e99813bcfa7d6100f39e9f90755e42f54 100644
--- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c
+++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 1245d22ddee8dde8a117f2cbcb8a3abc32ad0808..05b78adeb61dc9c13d1ca00a622e43f5ab8dbc2f 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h
index b1a82fccfe73ba562436110b5fe59989e2b862b9..03b4c775b7fc48f1ae1297edb47e5bd70b7bb1d4 100644
--- a/src/core/iomgr/pollset_posix.h
+++ b/src/core/iomgr/pollset_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index b81d23e57c2fb7d1ae95806860b4fecc99635f39..d21072b2832b9c08c6e51a780df01de5117d0ce4 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/pollset_windows.h b/src/core/iomgr/pollset_windows.h
index 1a5e31f627b4a1d1cfc71c4e839e577d65601097..41c193fcad01eb1a88907bd90f308928126bf254 100644
--- a/src/core/iomgr/pollset_windows.h
+++ b/src/core/iomgr/pollset_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/resolve_address.c b/src/core/iomgr/resolve_address.c
index e17bcdba0f45fe30d89d1e0e4fd364787b0b2c96..6d748c86981421c314a9f8007e3fece91be5fae4 100644
--- a/src/core/iomgr/resolve_address.c
+++ b/src/core/iomgr/resolve_address.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/resolve_address.h b/src/core/iomgr/resolve_address.h
index 7b537b1767470b785bb495dfea55c0eb84af8caf..65432ec61aaf27cd7de2521ae3815aab9e20822f 100644
--- a/src/core/iomgr/resolve_address.h
+++ b/src/core/iomgr/resolve_address.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/sockaddr.h b/src/core/iomgr/sockaddr.h
index b980b3029fa6a384cb2ca81e6f0af4b918ab702c..a5f7c546ecfb56bfd4e01d30ee6335cd2f3a171c 100644
--- a/src/core/iomgr/sockaddr.h
+++ b/src/core/iomgr/sockaddr.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/sockaddr_posix.h b/src/core/iomgr/sockaddr_posix.h
index 53c80386d435c0086436be687416cc04ff93513e..00115e253687489127226cdaf69c826eaa2efc11 100644
--- a/src/core/iomgr/sockaddr_posix.h
+++ b/src/core/iomgr/sockaddr_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c
index f7942417769ed85adfca76357e24235dcb3089e2..740bbe716ecbb458fcafc00747871d6c389b9ff2 100644
--- a/src/core/iomgr/sockaddr_utils.c
+++ b/src/core/iomgr/sockaddr_utils.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/sockaddr_utils.h b/src/core/iomgr/sockaddr_utils.h
index b49cc50491cf0fa61a45096b1a8f3d12a7ded308..d3a25ad373bb067451a89655b0345a33c1c7e5d6 100644
--- a/src/core/iomgr/sockaddr_utils.h
+++ b/src/core/iomgr/sockaddr_utils.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h
index 08be0e54f8ee5d46dfb56a0931fda1fcaefb0677..6ed164ced1deba2160488318123370149293f9b8 100644
--- a/src/core/iomgr/sockaddr_win32.h
+++ b/src/core/iomgr/sockaddr_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/socket_utils_common_posix.c b/src/core/iomgr/socket_utils_common_posix.c
index 1854285b5a433bf3e2f69ed7bc815e7eaccdfd0e..3c8cafa31521fadd1706724b93925b3aa71ee446 100644
--- a/src/core/iomgr/socket_utils_common_posix.c
+++ b/src/core/iomgr/socket_utils_common_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/socket_utils_linux.c b/src/core/iomgr/socket_utils_linux.c
index f3c22187d73c5cc1ca71987290d6162ca9509cde..a87625262b26d554044ea899f4aad6e155d51bdc 100644
--- a/src/core/iomgr/socket_utils_linux.c
+++ b/src/core/iomgr/socket_utils_linux.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/socket_utils_posix.c b/src/core/iomgr/socket_utils_posix.c
index 9184b2a47cfd130a2fb7a18671def021ba4d00e7..3c56b4674431fbcc898bc9fb7d265ef1f1cc3678 100644
--- a/src/core/iomgr/socket_utils_posix.c
+++ b/src/core/iomgr/socket_utils_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/socket_utils_posix.h b/src/core/iomgr/socket_utils_posix.h
index a84457f01de9751ba40bf4c494532483342d1faf..b35fe785f1ac622027f7aeaca678dabc0c8f4320 100644
--- a/src/core/iomgr/socket_utils_posix.h
+++ b/src/core/iomgr/socket_utils_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c
index 3639798dbcdae6f809cd0885bd526382eee9a520..99f38b0e032b43d193db424fa7870f880ca7f6c2 100644
--- a/src/core/iomgr/socket_windows.c
+++ b/src/core/iomgr/socket_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h
index 990b520c6dab74925703587ee9610361e0986197..de80e97e7f661a2c156de8c4802e6643c1bce079 100644
--- a/src/core/iomgr/socket_windows.h
+++ b/src/core/iomgr/socket_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_client.h b/src/core/iomgr/tcp_client.h
index ef2c4faf473a197663eca505695f64b9a4ba8f7a..c919c02440fd4326b1ed699a3ff530f928c898ee 100644
--- a/src/core/iomgr/tcp_client.h
+++ b/src/core/iomgr/tcp_client.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index 6dc7997833d436843165db76862139ddd514fdbd..137aa99c7b101f9d165b712b7e9544e40483386e 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c
index 2ed5f39b390b1fc4304b9b6de41cb63395d2b13c..2bd93c6af2c60ea23470dc31b7d8c26f581912a1 100644
--- a/src/core/iomgr/tcp_client_windows.c
+++ b/src/core/iomgr/tcp_client_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c
index a9b59df8854e47f246d5d2861793484a356b86b1..150a907cb105fe9b13b4b523ce96a3fc4837a749 100644
--- a/src/core/iomgr/tcp_posix.c
+++ b/src/core/iomgr/tcp_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h
index c3eef1b4b73c97eb89e02b6474d385971d4f7c28..6ff87704efb7e845b3b31eda0b280cb6cd152a93 100644
--- a/src/core/iomgr/tcp_posix.h
+++ b/src/core/iomgr/tcp_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index 2558a1eb9f9dd45963d4f45e5d226765e82a7a34..c1e5f45208dae14711541f2f67d06f3ec0769f8c 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,8 +46,9 @@ typedef void (*grpc_tcp_server_cb)(void *arg, grpc_endpoint *ep);
 grpc_tcp_server *grpc_tcp_server_create(void);
 
 /* Start listening to bound ports */
-void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset *pollset,
-                           grpc_tcp_server_cb cb, void *cb_arg);
+void grpc_tcp_server_start(grpc_tcp_server *server, grpc_pollset **pollsets,
+                           size_t pollset_count, grpc_tcp_server_cb cb,
+                           void *cb_arg);
 
 /* Add a port to the server, returning port number on success, or negative
    on failure.
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 9e5076efc717da472a82fa7f315c6680453b54b6..b7a06259497f20780f9a05e03022c881c96bd1d8 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -379,9 +379,10 @@ int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index) {
   return (index < s->nports) ? s->ports[index].fd : -1;
 }
 
-void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset *pollset,
-                           grpc_tcp_server_cb cb, void *cb_arg) {
-  size_t i;
+void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset **pollsets,
+                           size_t pollset_count, grpc_tcp_server_cb cb,
+                           void *cb_arg) {
+  size_t i, j;
   GPR_ASSERT(cb);
   gpr_mu_lock(&s->mu);
   GPR_ASSERT(!s->cb);
@@ -389,8 +390,8 @@ void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset *pollset,
   s->cb = cb;
   s->cb_arg = cb_arg;
   for (i = 0; i < s->nports; i++) {
-    if (pollset) {
-      grpc_pollset_add_fd(pollset, s->ports[i].emfd);
+    for (j = 0; j < pollset_count; j++) {
+      grpc_pollset_add_fd(pollsets[j], s->ports[i].emfd);
     }
     grpc_fd_notify_on_read(s->ports[i].emfd, on_read, &s->ports[i]);
     s->active_ports++;
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index e6161eb1e86abfd48d93ca843b7c4977cbf81afe..c6864efdc53682e815f71765eee5296972c4d62f 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_windows.c b/src/core/iomgr/tcp_windows.c
index 94d84f92b5901138b24c0e07ec9223536a0179a3..3efd69a71b9985f0d2f40cf4a3a054a25530a106 100644
--- a/src/core/iomgr/tcp_windows.c
+++ b/src/core/iomgr/tcp_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/tcp_windows.h b/src/core/iomgr/tcp_windows.h
index cbe60801b4955b80a7d8a3c7ac5e0f0120ac95ce..565d42e5b2964bfefeba4236dffb515635687d4b 100644
--- a/src/core/iomgr/tcp_windows.h
+++ b/src/core/iomgr/tcp_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/time_averaged_stats.c b/src/core/iomgr/time_averaged_stats.c
index 7624cd91d3c71e152295bb23fcfeabca68a32bd5..f881dde9fc2b05b1b9be9b39c24a6df8204a3c28 100644
--- a/src/core/iomgr/time_averaged_stats.c
+++ b/src/core/iomgr/time_averaged_stats.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/iomgr/time_averaged_stats.h b/src/core/iomgr/time_averaged_stats.h
index be75bd1448972531c35fe9bb96ef04d4c9096a68..e901f3c33b3b079dfdb307717ce0719118fc6fd3 100644
--- a/src/core/iomgr/time_averaged_stats.h
+++ b/src/core/iomgr/time_averaged_stats.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json.c b/src/core/json/json.c
index 1cff4fa19514bbdab2e6587b2a061450995841e9..df7108a94de696b4ac6d0be54132f18ca673912a 100644
--- a/src/core/json/json.c
+++ b/src/core/json/json.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json.h b/src/core/json/json.h
index 6676744ff7ee81fdd2b6597f2dae6f38b40d8d54..dc519e9d5ec96b6b0ec1d725cc2c4180643288a2 100644
--- a/src/core/json/json.h
+++ b/src/core/json/json.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json_common.h b/src/core/json/json_common.h
index 88a8155a42ff20b6758311cb28c0c6b22b4ecccd..60763cc72ea80b021d843614fd03370c55c00c29 100644
--- a/src/core/json/json_common.h
+++ b/src/core/json/json_common.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json_reader.c b/src/core/json/json_reader.c
index 75aa87eb03c749a6a44cdff512e31d16d8bdd69e..774faa5f239bdfbaf42faadb1d3f475984ba7c6f 100644
--- a/src/core/json/json_reader.c
+++ b/src/core/json/json_reader.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json_reader.h b/src/core/json/json_reader.h
index 388ee3633fb4812daf76e848502fd9e7baeaf366..f7f59127f9374daf59075778bf87633305d7cf3e 100644
--- a/src/core/json/json_reader.h
+++ b/src/core/json/json_reader.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json_string.c b/src/core/json/json_string.c
index d29e9e30e8211dfb0bbf28e46dea294ec5221f52..13f816995b240f6cd44a4294168e3c9611bf00c9 100644
--- a/src/core/json/json_string.c
+++ b/src/core/json/json_string.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json_writer.c b/src/core/json/json_writer.c
index 5605694fde57954ad921229ca0ecb8f3e153d26d..4c0bf30780dcd102a1466953e2f9734deaf13be0 100644
--- a/src/core/json/json_writer.c
+++ b/src/core/json/json_writer.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/json/json_writer.h b/src/core/json/json_writer.h
index 0568401590181631c6aee132aa97ac4833922aa6..5d5d0891a3c887b0d19c4d114c889a7cb6a4317e 100644
--- a/src/core/json/json_writer.h
+++ b/src/core/json/json_writer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 18c32f90f40b77b3a98e55ea7a60adb71dffb577..58679a87aa5509b653f08d4503fd37d34e7a7d97 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/auth.h b/src/core/security/auth.h
index 94fa2aba7db95138aba70a6c39482e975c5de812..fee75c40e1c8083f5b8f4201959dcecba2f1e112 100644
--- a/src/core/security/auth.h
+++ b/src/core/security/auth.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/base64.c b/src/core/security/base64.c
index 63467944ddeea5a2bb32283db276201121e34c52..3b8fea8f7371afff8a3bd027be1c3bbc83db48e4 100644
--- a/src/core/security/base64.c
+++ b/src/core/security/base64.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/base64.h b/src/core/security/base64.h
index 7bfb89b0715b26a3828b2f3fad0f6ed3db253435..0eb69d0ccb35c921c8a81e42e548e5ee2445749e 100644
--- a/src/core/security/base64.h
+++ b/src/core/security/base64.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 6f0d72c0c3d9e2f173f77892afe8e108a10395e5..a21c27bff946bef47ae9a2291fd7e8de9da8a8af 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -313,7 +313,7 @@ static void oauth2_token_fetcher_destroy(grpc_credentials *creds) {
     grpc_mdelem_unref(c->access_token_md);
   }
   gpr_mu_destroy(&c->mu);
-  grpc_mdctx_orphan(c->md_ctx);
+  grpc_mdctx_unref(c->md_ctx);
   gpr_free(c);
 }
 
@@ -336,6 +336,12 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
   grpc_credentials_status status = GRPC_CREDENTIALS_OK;
   grpc_json *json = NULL;
 
+  if (response == NULL) {
+    gpr_log(GPR_ERROR, "Received NULL response.");
+    status = GRPC_CREDENTIALS_ERROR;
+    goto end;
+  }
+
   if (response->body_length > 0) {
     null_terminated_body = gpr_malloc(response->body_length + 1);
     null_terminated_body[response->body_length] = '\0';
@@ -587,7 +593,7 @@ static void fake_oauth2_destroy(grpc_credentials *creds) {
   if (c->access_token_md != NULL) {
     grpc_mdelem_unref(c->access_token_md);
   }
-  grpc_mdctx_orphan(c->md_ctx);
+  grpc_mdctx_unref(c->md_ctx);
   gpr_free(c);
 }
 
@@ -897,7 +903,7 @@ static void iam_destroy(grpc_credentials *creds) {
   grpc_iam_credentials *c = (grpc_iam_credentials *)creds;
   grpc_mdelem_unref(c->token_md);
   grpc_mdelem_unref(c->authority_selector_md);
-  grpc_mdctx_orphan(c->md_ctx);
+  grpc_mdctx_unref(c->md_ctx);
   gpr_free(c);
 }
 
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 3ec874681a7b233379db4be2f92196ccd2785e72..614db96ad7ac705617e513f4307a42c7cd040742 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/factories.c b/src/core/security/factories.c
index d89c692989c0fbd7fd5edff13768d231311eb79e..c9701b9080db47e6e5a8bf2e9daa9310f49318fd 100644
--- a/src/core/security/factories.c
+++ b/src/core/security/factories.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/google_root_certs.c b/src/core/security/google_root_certs.c
index 669d637ddfa4189acea79e73dcb3672351e6697d..1a44058a29e24c2e43ed659b079170c7dd026ae5 100644
--- a/src/core/security/google_root_certs.c
+++ b/src/core/security/google_root_certs.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/google_root_certs.h b/src/core/security/google_root_certs.h
index 30ed16c03bc5728839419c0c43ea810a2862e301..914e756171801d44fe2fefbb1f48e54c9faa89ff 100644
--- a/src/core/security/google_root_certs.h
+++ b/src/core/security/google_root_certs.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 8e48686288fb68aae9df0d2d2d81a6db968853fe..20d62e2b438f4f2cce653c1cad128b98db55d597 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -206,15 +206,14 @@ static char *encoded_jwt_claim(const grpc_auth_json_key *json_key,
   char *result = NULL;
   gpr_timespec now = gpr_now();
   gpr_timespec expiration = gpr_time_add(now, token_lifetime);
-  /* log10(2^64) ~= 20 */
-  char now_str[24];
-  char expiration_str[24];
+  char now_str[GPR_LTOA_MIN_BUFSIZE];
+  char expiration_str[GPR_LTOA_MIN_BUFSIZE];
   if (gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime) > 0) {
     gpr_log(GPR_INFO, "Cropping token lifetime to maximum allowed value.");
     expiration = gpr_time_add(now, grpc_max_auth_token_lifetime);
   }
-  sprintf(now_str, "%ld", now.tv_sec);
-  sprintf(expiration_str, "%ld", expiration.tv_sec);
+  gpr_ltoa(now.tv_sec, now_str);
+  gpr_ltoa(expiration.tv_sec, expiration_str);
 
   child = create_child(NULL, json, "iss", json_key->client_email,
                        GRPC_JSON_STRING);
diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h
index 3ef9f1bfc0bc74f2c00bac80d3604e92c6c7980d..5a9b2dab4b3df82f48f153be865a5e23d5b6f64d 100644
--- a/src/core/security/json_token.h
+++ b/src/core/security/json_token.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/secure_endpoint.c b/src/core/security/secure_endpoint.c
index 31138d694f171660e7535996e0ff2fda4d7e00d6..031f23dc79d109782c8104b7a50b05501f0d2919 100644
--- a/src/core/security/secure_endpoint.c
+++ b/src/core/security/secure_endpoint.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h
index 20143150e07a04b52b565469356a85160cd4012f..82ba4082e3268a91b68d0f7ebd3488adffc8ac2f 100644
--- a/src/core/security/secure_endpoint.h
+++ b/src/core/security/secure_endpoint.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
index 59789a7e4deb4d3ab7448bd0eca4fed3376cd745..f57d22109cec0843b50b42f62b2de37d33629994 100644
--- a/src/core/security/secure_transport_setup.c
+++ b/src/core/security/secure_transport_setup.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h
index b13d065fbfffbde27631f1ce8fc0229b12647374..21f41fd682255f31d3726f1555c9c50687f517de 100644
--- a/src/core/security/secure_transport_setup.h
+++ b/src/core/security/secure_transport_setup.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 1909617614d29349b08257680d0c592aa93c31a3..f9fb2407cf996168ee54d1067ac32cc145ff506b 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 25d467d717156919af90359602f20b08f54a4765..e3d91139678a24dd8337706099aea1c85a6e6827 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 480c8827943ca340022c8b2098d074721110b6d8..c88f0726bb7a8d17efd05f2022f58a0766b0408a 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,9 +76,10 @@ static void on_accept(void *server, grpc_endpoint *tcp) {
 /* Note: the following code is the same with server_chttp2.c */
 
 /* Server callback: start listening on our ports */
-static void start(grpc_server *server, void *tcpp, grpc_pollset *pollset) {
+static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets,
+                  size_t pollset_count) {
   grpc_tcp_server *tcp = tcpp;
-  grpc_tcp_server_start(tcp, pollset, on_accept, server);
+  grpc_tcp_server_start(tcp, pollsets, pollset_count, on_accept, server);
 }
 
 /* Server callback: destroy the tcp listener (so we don't generate further
diff --git a/src/core/statistics/census_init.c b/src/core/statistics/census_init.c
index cbf2089f3fa81d404b924aab1322be55736751c0..820d75f795eb87b8215910ce0cb5b103c3e09a17 100644
--- a/src/core/statistics/census_init.c
+++ b/src/core/statistics/census_init.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/census_interface.h b/src/core/statistics/census_interface.h
index 8e586382f7896b8d519e3a56f7ae84942ca1cd1a..0bb0a9f328dc7358fb1f8f3e338ac4891e9ad891 100644
--- a/src/core/statistics/census_interface.h
+++ b/src/core/statistics/census_interface.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/census_log.c b/src/core/statistics/census_log.c
index aea0a33bad75af1261521becfb10258845456d64..24e46876d25a0613a9bb18862d1dcbdc321567c6 100644
--- a/src/core/statistics/census_log.c
+++ b/src/core/statistics/census_log.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,9 +91,9 @@
 */
 #include "src/core/statistics/census_log.h"
 #include <string.h>
-#include "src/core/support/cpu.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/atm.h>
+#include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/sync.h>
diff --git a/src/core/statistics/census_log.h b/src/core/statistics/census_log.h
index 0d89df79929d6402d99241c9a9a6876580ce1aac..01fd63aca39d05f8b3bd0db663eeb08c0149abb1 100644
--- a/src/core/statistics/census_log.h
+++ b/src/core/statistics/census_log.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c
index fc66cb951fef77bca35adde2f538ecff503753dc..388ce4fe2c8c4334a3268a3d7850cfd058a55ec7 100644
--- a/src/core/statistics/census_rpc_stats.c
+++ b/src/core/statistics/census_rpc_stats.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h
index 81466907fdcf825c86307dd300f44065fe0accd8..942de81b888de076dcf382287d3a7e25658bd11a 100644
--- a/src/core/statistics/census_rpc_stats.h
+++ b/src/core/statistics/census_rpc_stats.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c
index 8b98323e64cd8566de2066e010f4abee051fe699..adfcbecb4c8f82136f0a4a6242c455084bbfcfad 100644
--- a/src/core/statistics/census_tracing.c
+++ b/src/core/statistics/census_tracing.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/census_tracing.h b/src/core/statistics/census_tracing.h
index 88a06a4a5248c951ed8dd785f24438ea3c8697cc..51aa578c0c16e6f30a53ba2cdefcf1dafdceeeb4 100644
--- a/src/core/statistics/census_tracing.h
+++ b/src/core/statistics/census_tracing.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c
index 1f7c242c72ed9df50bbc373e2db3f75fd9e6af09..56bdcc2ffff6dd71e999d84a3cef51c4d94c7c6b 100644
--- a/src/core/statistics/hash_table.c
+++ b/src/core/statistics/hash_table.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/hash_table.h b/src/core/statistics/hash_table.h
index 5c9a3fa0b481ac1d1788e308329a001d60ddd805..2c2386d1ab1babca231bf24de22c07cc0f5c0fab 100644
--- a/src/core/statistics/hash_table.h
+++ b/src/core/statistics/hash_table.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/window_stats.c b/src/core/statistics/window_stats.c
index 42ff02071ba5094025145af3259ad2fe66180925..a64e0805652c5dff91515bf8118f4295cbd483f1 100644
--- a/src/core/statistics/window_stats.c
+++ b/src/core/statistics/window_stats.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/statistics/window_stats.h b/src/core/statistics/window_stats.h
index 677f40031ef0ffb0cf4676b996ef02f7f5931738..98f8dac55959127abd5193aaf6aaa2afc12506ae 100644
--- a/src/core/statistics/window_stats.h
+++ b/src/core/statistics/window_stats.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/alloc.c b/src/core/support/alloc.c
index ddf6789773234f630384b7381af79ff758ef2858..44f343b4f400445d1f39dd203069dd18b04c4043 100644
--- a/src/core/support/alloc.c
+++ b/src/core/support/alloc.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/cancellable.c b/src/core/support/cancellable.c
index 5596413fba395029bd1f9b6e72335ee05388b4c2..5a4d488dd3cf1c0c97bab5f17091c95e6d1d78d9 100644
--- a/src/core/support/cancellable.c
+++ b/src/core/support/cancellable.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/cmdline.c b/src/core/support/cmdline.c
index a55da9dd1888db7bd1f6629ecbb373c6f100525a..72f46c1bd72e4edb6f2c4fb1a2d5adcf6e42427e 100644
--- a/src/core/support/cmdline.c
+++ b/src/core/support/cmdline.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/cpu_linux.c b/src/core/support/cpu_linux.c
index ad82174894b574b1f08c4e35ab6adaae34081905..ef6bf9ca09641146485c9144ff6293aedbda7767 100644
--- a/src/core/support/cpu_linux.c
+++ b/src/core/support/cpu_linux.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@
 
 #ifdef GPR_CPU_LINUX
 
-#include "src/core/support/cpu.h"
+#include <grpc/support/cpu.h>
 
 #include <sched.h>
 #include <errno.h>
diff --git a/src/core/support/cpu_posix.c b/src/core/support/cpu_posix.c
index 68e8cb9b12f280ef40a021575b0494fd02cefb3b..91ce80c364e788f9d1658be8eda037971aac43a0 100644
--- a/src/core/support/cpu_posix.c
+++ b/src/core/support/cpu_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,8 +35,6 @@
 
 #ifdef GPR_CPU_POSIX
 
-#include "src/core/support/cpu.h"
-
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
diff --git a/src/core/support/env.h b/src/core/support/env.h
index 81dda7d838aa74b1ee9f8790dadd53df65d22f2f..0c6091b84b8a3a47793e2e6cc9a2cec826d0853f 100644
--- a/src/core/support/env.h
+++ b/src/core/support/env.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/env_linux.c b/src/core/support/env_linux.c
index 28e3d1450f9d6a4eddfc482e7b2258f753c54eb9..bdadfb6ca4c41ecec10d9613145637027432cdb9 100644
--- a/src/core/support/env_linux.c
+++ b/src/core/support/env_linux.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/env_posix.c b/src/core/support/env_posix.c
index bcbff9a1770b1e73919ed311800c38be9bca7781..45f89b673790512a7f1adc7822f551702dbb7c2c 100644
--- a/src/core/support/env_posix.c
+++ b/src/core/support/env_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/env_win32.c b/src/core/support/env_win32.c
index 3159c20f7d7a164e504c3908db640b5a385647fc..177cc36a30a00b4dc0254ccf0f0a7a9d30ef489d 100644
--- a/src/core/support/env_win32.c
+++ b/src/core/support/env_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/file.c b/src/core/support/file.c
index c0bb1b66a066d705f5c2c2c5008cb6fbcfc5bd02..70100b7e9b568707169acada30b9277fefe15f54 100644
--- a/src/core/support/file.c
+++ b/src/core/support/file.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/file.h b/src/core/support/file.h
index 92f420e7ceb3a64cb27a0d51ddc534cb9c0579c6..600850e03d4f88aa57eaad2ea73ece2b962672df 100644
--- a/src/core/support/file.h
+++ b/src/core/support/file.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/file_posix.c b/src/core/support/file_posix.c
index e1765666dbe299ed59130d3d55089ca2ecdfd116..11a459ad364b99f1174eac112f8f719bd7c3cd0a 100644
--- a/src/core/support/file_posix.c
+++ b/src/core/support/file_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/file_win32.c b/src/core/support/file_win32.c
index 7749d4553f7bbd67969b8601a72fbd39c3179903..fe209af9b2dc5c0e978ec788c0cb40beb55b6fb5 100644
--- a/src/core/support/file_win32.c
+++ b/src/core/support/file_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/histogram.c b/src/core/support/histogram.c
index cd360c5a225f5cc03f89b9ab34e7118c8d653853..eacb77082f971fcbf75ebd552fb67efaf7734c34 100644
--- a/src/core/support/histogram.c
+++ b/src/core/support/histogram.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/host_port.c b/src/core/support/host_port.c
index 446c11ebec31c4a2c65d3dbea469c2717f48e7d8..379d30b045628aec4fc106eef7aa9f2b2a136718 100644
--- a/src/core/support/host_port.c
+++ b/src/core/support/host_port.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/log.c b/src/core/support/log.c
index 7f102efea8277de4f3e32e1f64db3352e8c22e62..f52c2035b9c21066f5c6fce8ac73f8805f3fa28b 100644
--- a/src/core/support/log.c
+++ b/src/core/support/log.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c
index 53c8153593ab91550d8865c030ab2ac2bda3cb34..5d0c7d820d82d227b2f660d01868694b43bb0967 100644
--- a/src/core/support/log_android.c
+++ b/src/core/support/log_android.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c
index a64faa98bd93956da9f8012a333996a85b52c304..48349d2c8316e6ab789a232ae5a75c1f084ad4ca 100644
--- a/src/core/support/log_linux.c
+++ b/src/core/support/log_linux.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
index 36479baeed2d1386e0bab6b6331c33ccb8ce564d..8f85791466db369f32e5ffa98f03da986f067791 100644
--- a/src/core/support/log_posix.c
+++ b/src/core/support/log_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
index 840f24f68aa6a77b01c243aff719d0a6db268516..cff130ae18d4ba82bc8db6a03d1e60ce55c10ad6 100644
--- a/src/core/support/log_win32.c
+++ b/src/core/support/log_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/murmur_hash.c b/src/core/support/murmur_hash.c
index 892e360968f2ea64eca024248a1d56999ef97f6e..cc84691508fec8d2f80ec3458d06d9c23fc382c3 100644
--- a/src/core/support/murmur_hash.c
+++ b/src/core/support/murmur_hash.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/murmur_hash.h b/src/core/support/murmur_hash.h
index 2ebf3e57b1f27aab21ac9d0a15f102dc8f0f829e..06c0c5607972a72f85aaafe7c7f3647b3348954b 100644
--- a/src/core/support/murmur_hash.h
+++ b/src/core/support/murmur_hash.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/slice.c b/src/core/support/slice.c
index 836a5a6c2a7c8a9285f639e4bfed98b72795fe88..4cff029286c82d4453f9fd29cf5a58089fa7aa9e 100644
--- a/src/core/support/slice.c
+++ b/src/core/support/slice.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c
index 22bda966597c899c642385b1fdc1120c2d8af6ea..6cd51f925c3b46b083dddc19ad4d8a3b360b14e5 100644
--- a/src/core/support/slice_buffer.c
+++ b/src/core/support/slice_buffer.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/string.c b/src/core/support/string.c
index 97bce60f94cef99ded9f1945c410f090b00dd265..f3d26b45acf8edc2d1cb0fb819485ad2db814a29 100644
--- a/src/core/support/string.c
+++ b/src/core/support/string.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -14,7 +14,7 @@
  * 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 
+ * 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
diff --git a/src/core/support/string.h b/src/core/support/string.h
index 64e06d3b6aaccb3e04975f5baa78490a93460563..eaa182643927e1b27d694aec389db649121d89d9 100644
--- a/src/core/support/string.h
+++ b/src/core/support/string.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/string_posix.c b/src/core/support/string_posix.c
index b6f0cd4af0c16306d962a4ad04adb6e00df59714..8a678b3103d0e951e6d60a16643550cba37164c6 100644
--- a/src/core/support/string_posix.c
+++ b/src/core/support/string_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/string_win32.c b/src/core/support/string_win32.c
index 02e1c74d9cefcd81919c44a7cf1c8e620cf6b06a..583abd27d82f587e41eda2dae451bf5431670371 100644
--- a/src/core/support/string_win32.c
+++ b/src/core/support/string_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/string_win32.h b/src/core/support/string_win32.h
index 9102d98256964dff3a5027510aec357015b4c88a..5dbb40dbc3b5afc13f1d2901cd0aeaa7345e14b5 100644
--- a/src/core/support/string_win32.h
+++ b/src/core/support/string_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/sync.c b/src/core/support/sync.c
index 40e5465e5db3cd3589944c72c17056d1389d3c90..1a5cf57c4f28f7f2018370f127c65d89160a709b 100644
--- a/src/core/support/sync.c
+++ b/src/core/support/sync.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/sync_posix.c b/src/core/support/sync_posix.c
index 94fc1b0bec362ad5f83d593caefab0574c389da5..0ccbd4923f8cb7f858ab6b72dc87d1b5c7ab7202 100644
--- a/src/core/support/sync_posix.c
+++ b/src/core/support/sync_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/sync_win32.c b/src/core/support/sync_win32.c
index 8df26bccb9bac8878b00d71f1da2cd0d3d0788c9..c9a977cc80eed9f757f19274ed28d3dc7919204a 100644
--- a/src/core/support/sync_win32.c
+++ b/src/core/support/sync_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/thd_internal.h b/src/core/support/thd_internal.h
index 190d4e366816e85fb4a5834ea4dff4e1b2c4a5b6..0fb1447e488013945618d5a9de6d46b914a0a8ec 100644
--- a/src/core/support/thd_internal.h
+++ b/src/core/support/thd_internal.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c
index 74ca9424bbcca1fcb3128487a37e4b4c2abc7370..f50ea583357169bb78841295dc8a86070f2ce2b4 100644
--- a/src/core/support/thd_posix.c
+++ b/src/core/support/thd_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c
index 2ee14170484dde260345f6ec8a272e8a24408155..347cad57e3ad1abcd653dbedb1029997e42c6070 100644
--- a/src/core/support/thd_win32.c
+++ b/src/core/support/thd_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/time.c b/src/core/support/time.c
index 268a43c6775cfb5deb3e50e7d55dcfafaaea85fd..67f76656502982daa308c017894d602d01619f60 100644
--- a/src/core/support/time.c
+++ b/src/core/support/time.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c
index 4af537d974bb7b55a95a985845c922a1f1e31770..3675f1eb229dfc85eb1ecfc7fb940bc6e6aa298c 100644
--- a/src/core/support/time_posix.c
+++ b/src/core/support/time_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c
index b9fe5123350528ea66b5d21926c061e5b05ef377..8256849655814d86a5bce846aec325a2211837bc 100644
--- a/src/core/support/time_win32.c
+++ b/src/core/support/time_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/byte_buffer.c b/src/core/surface/byte_buffer.c
index 09e2aa5b872ab3fa5c2a681a717da16260b5d238..12244f6644ed10364d087b4120fddd841052c44e 100644
--- a/src/core/surface/byte_buffer.c
+++ b/src/core/surface/byte_buffer.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/byte_buffer_queue.c b/src/core/surface/byte_buffer_queue.c
index aab7fd2ffea90a38c40d50b845bc1e69fa067acd..7c31bfe5da2176e2d502512d59faf60859e11cb5 100644
--- a/src/core/surface/byte_buffer_queue.c
+++ b/src/core/surface/byte_buffer_queue.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/byte_buffer_queue.h b/src/core/surface/byte_buffer_queue.h
index 3420dc5cabaf8ae5df13e1f30b31650d143547ba..9d3b5257a7af8b799049bcf416e7b6b522e1caaa 100644
--- a/src/core/surface/byte_buffer_queue.h
+++ b/src/core/surface/byte_buffer_queue.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c
index 18500b83e8d1eff738eb465eba7d004df2d5d179..fd5289bac3827b42884a1aef834cc267c0847eeb 100644
--- a/src/core/surface/byte_buffer_reader.c
+++ b/src/core/surface/byte_buffer_reader.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 58a2436937f57a5b0a2285a925da8a3bb27413a4..40caa938680520f7b79126987399f5cbe7a47885 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -258,6 +258,10 @@ void grpc_call_set_completion_queue(grpc_call *call,
   call->cq = cq;
 }
 
+grpc_completion_queue *grpc_call_get_completion_queue(grpc_call *call) {
+  return call->cq;
+}
+
 void grpc_call_internal_ref(grpc_call *c) { gpr_ref(&c->internal_refcount); }
 
 static void destroy_call(void *call, int ignored_success) {
@@ -309,7 +313,6 @@ static void set_status_code(grpc_call *call, status_source source,
   }
 
   if (flush && !grpc_bbq_empty(&call->incoming_queue)) {
-    gpr_log(GPR_ERROR, "Flushing unread messages due to error status %d", status);
     grpc_bbq_flush(&call->incoming_queue);
   }
 }
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index 05014c631c7b99515c1d143fdc9ccb1e98c5d9e4..dd3ad124e6da53b64d5ef838bee70c3fc10dcf11 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,6 +89,7 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
                             const void *server_transport_data);
 
 void grpc_call_set_completion_queue(grpc_call *call, grpc_completion_queue *cq);
+grpc_completion_queue *grpc_call_get_completion_queue(grpc_call *call);
 
 void grpc_call_internal_ref(grpc_call *call);
 void grpc_call_internal_unref(grpc_call *call, int allow_immediate_deletion);
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index 514073ce0bf51eddc2dd23762abbddf4cf1bda81..e38734c6a4921fb4e7e63a6d247262b13637e1c9 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "src/core/iomgr/iomgr.h"
 #include "src/core/surface/call.h"
 #include "src/core/surface/client.h"
 #include <grpc/support/alloc.h>
@@ -138,15 +139,20 @@ void grpc_channel_internal_ref(grpc_channel *channel) {
   gpr_ref(&channel->refs);
 }
 
+static void destroy_channel(void *p, int ok) {
+  grpc_channel *channel = p;
+  grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
+  grpc_mdstr_unref(channel->grpc_status_string);
+  grpc_mdstr_unref(channel->grpc_message_string);
+  grpc_mdstr_unref(channel->path_string);
+  grpc_mdstr_unref(channel->authority_string);
+  grpc_mdctx_unref(channel->metadata_context);
+  gpr_free(channel);
+}
+
 void grpc_channel_internal_unref(grpc_channel *channel) {
   if (gpr_unref(&channel->refs)) {
-    grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel));
-    grpc_mdstr_unref(channel->grpc_status_string);
-    grpc_mdstr_unref(channel->grpc_message_string);
-    grpc_mdstr_unref(channel->path_string);
-    grpc_mdstr_unref(channel->authority_string);
-    grpc_mdctx_orphan(channel->metadata_context);
-    gpr_free(channel);
+    grpc_iomgr_add_callback(destroy_channel, channel);
   }
 }
 
diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h
index ff9bbc237ef5f57ab0a1da51614249d278bbbb2e..6bdfd474d2eb97b290e0fd9cf67f307eab7f3d64 100644
--- a/src/core/surface/channel.h
+++ b/src/core/surface/channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index d3faf0c996a2eeca9d9ba20bb64201214359a44e..3104b1d00d58784ae5938ba3d3b1443fa34f0d19 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -107,13 +107,16 @@ static void on_connect(void *rp, grpc_endpoint *tcp) {
     } else {
       return;
     }
-  } else {
+  } else if (grpc_client_setup_cb_begin(r->cs_request)) {
     grpc_create_chttp2_transport(
         r->setup->setup_callback, r->setup->setup_user_data,
         grpc_client_setup_get_channel_args(r->cs_request), tcp, NULL, 0,
         grpc_client_setup_get_mdctx(r->cs_request), 1);
+    grpc_client_setup_cb_end(r->cs_request);
     done(r, 1);
     return;
+  } else {
+    done(r, 0);
   }
 }
 
diff --git a/src/core/surface/client.c b/src/core/surface/client.c
index 64ee9d51e807b6a6b416937c208322365d30472b..4d54865d1671b3ddcf5e2704b6d553de6788286a 100644
--- a/src/core/surface/client.c
+++ b/src/core/surface/client.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/client.h b/src/core/surface/client.h
index cff3d401d92c0ac552834eecb4a14be93259eea1..06ce8f66567202804eceebb319e0c05089b9330a 100644
--- a/src/core/surface/client.h
+++ b/src/core/surface/client.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 8b94aa920afe64b31d98cd25593387d749756fb3..2efc084d7b3a967f718d2a2b824b64e80c263c93 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 205cb76cee884178f00aa01d2a72d3083aae404a..a7688b844c6d79ea953aa94a56ff8f7b7dae0819 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/event_string.c b/src/core/surface/event_string.c
index ab9435351e1a670908632c16e4bbfa4b617ba1b7..0fa3f166e2c56024579b4b8e1e14d23293e96434 100644
--- a/src/core/surface/event_string.c
+++ b/src/core/surface/event_string.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/event_string.h b/src/core/surface/event_string.h
index b34e2d152b5d05165da0aaa45a105430f17ad009..d9b1e4e0747b1ff20ee1c0d8dfa6ae453c1f8be0 100644
--- a/src/core/surface/event_string.h
+++ b/src/core/surface/event_string.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index 4d639fcbce26a20b38f2b75c3947578d13fe4975..43c9906a8a4c01666230d583600346ea8747894c 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,4 +63,3 @@ void grpc_shutdown(void) {
   }
   gpr_mu_unlock(&g_init_mu);
 }
-
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 411dbabfd3261e1b994fae72b8fe09535dc1e300..57f6ddf0f7ff6bca8b82e02946dd7cbb8a3e1bb9 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,7 @@ typedef struct {
 } call_data;
 
 typedef struct {
+  grpc_mdelem *status;
   grpc_mdelem *message;
 } channel_data;
 
@@ -57,6 +58,7 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
 
   switch (op->type) {
     case GRPC_SEND_START:
+      grpc_call_recv_metadata(elem, grpc_mdelem_ref(channeld->status));
       grpc_call_recv_metadata(elem, grpc_mdelem_ref(channeld->message));
       grpc_call_stream_closed(elem);
       break;
@@ -93,18 +95,22 @@ static void init_channel_elem(grpc_channel_element *elem,
                               const grpc_channel_args *args, grpc_mdctx *mdctx,
                               int is_first, int is_last) {
   channel_data *channeld = elem->channel_data;
+  char status[12];
 
   GPR_ASSERT(is_first);
   GPR_ASSERT(is_last);
 
   channeld->message = grpc_mdelem_from_strings(mdctx, "grpc-message",
                                                "Rpc sent on a lame channel.");
+  gpr_ltoa(GRPC_STATUS_UNKNOWN, status);
+  channeld->status = grpc_mdelem_from_strings(mdctx, "grpc-status", status);
 }
 
 static void destroy_channel_elem(grpc_channel_element *elem) {
   channel_data *channeld = elem->channel_data;
 
   grpc_mdelem_unref(channeld->message);
+  grpc_mdelem_unref(channeld->status);
 }
 
 static const grpc_channel_filter lame_filter = {
diff --git a/src/core/surface/lame_client.h b/src/core/surface/lame_client.h
index 3cfbf7b954f90aed429f504dc2bfb6c26b30e279..2bd97b95eb188c257a56ffb28420f61d32c7cbb8 100644
--- a/src/core/surface/lame_client.h
+++ b/src/core/surface/lame_client.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 562e27ff6d43e76dc3ad81b5624c343a493a4505..8e56868d4207319c50265eac21a34a836b7253f5 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -97,12 +97,15 @@ static void on_secure_transport_setup_done(void *rp,
   if (status != GRPC_SECURITY_OK) {
     gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
     done(r, 0);
-  } else {
+  } else if (grpc_client_setup_cb_begin(r->cs_request)) {
     grpc_create_chttp2_transport(
         r->setup->setup_callback, r->setup->setup_user_data,
         grpc_client_setup_get_channel_args(r->cs_request), secure_endpoint,
         NULL, 0, grpc_client_setup_get_mdctx(r->cs_request), 1);
+    grpc_client_setup_cb_end(r->cs_request);
     done(r, 1);
+  } else {
+    done(r, 0);
   }
 }
 
diff --git a/src/core/surface/secure_server_create.c b/src/core/surface/secure_server_create.c
index bf0f62367fc07a2cfbafd4a96776e5a0b4ca3fe6..1d5b9279977cbe2bd40da3082905b564d5ef9eaa 100644
--- a/src/core/surface/secure_server_create.c
+++ b/src/core/surface/secure_server_create.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 456c7826a28072c509b7b9a91180a7a44bfaf7f4..a95215c5de99fff7521389209a1731d0896f22d9 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,13 +53,64 @@ typedef enum { PENDING_START, ALL_CALLS, CALL_LIST_COUNT } call_list;
 
 typedef struct listener {
   void *arg;
-  void (*start)(grpc_server *server, void *arg, grpc_pollset *pollset);
+  void (*start)(grpc_server *server, void *arg, grpc_pollset **pollsets,
+                size_t pollset_count);
   void (*destroy)(grpc_server *server, void *arg);
   struct listener *next;
 } listener;
 
 typedef struct call_data call_data;
 typedef struct channel_data channel_data;
+typedef struct registered_method registered_method;
+
+typedef struct {
+  call_data *next;
+  call_data *prev;
+} call_link;
+
+typedef enum { LEGACY_CALL, BATCH_CALL, REGISTERED_CALL } requested_call_type;
+
+typedef struct {
+  requested_call_type type;
+  void *tag;
+  union {
+    struct {
+      grpc_completion_queue *cq_bind;
+      grpc_call **call;
+      grpc_call_details *details;
+      grpc_metadata_array *initial_metadata;
+    } batch;
+    struct {
+      grpc_completion_queue *cq_bind;
+      grpc_call **call;
+      registered_method *registered_method;
+      gpr_timespec *deadline;
+      grpc_metadata_array *initial_metadata;
+      grpc_byte_buffer **optional_payload;
+    } registered;
+  } data;
+} requested_call;
+
+typedef struct {
+  requested_call *calls;
+  size_t count;
+  size_t capacity;
+} requested_call_array;
+
+struct registered_method {
+  char *method;
+  char *host;
+  call_data *pending;
+  requested_call_array requested;
+  grpc_completion_queue *cq;
+  registered_method *next;
+};
+
+typedef struct channel_registered_method {
+  registered_method *server_registered_method;
+  grpc_mdstr *method;
+  grpc_mdstr *host;
+} channel_registered_method;
 
 struct channel_data {
   grpc_server *server;
@@ -69,33 +120,25 @@ struct channel_data {
   /* linked list of all channels on a server */
   channel_data *next;
   channel_data *prev;
+  channel_registered_method *registered_methods;
+  gpr_uint32 registered_method_slots;
+  gpr_uint32 registered_method_max_probes;
 };
 
-typedef void (*new_call_cb)(grpc_server *server, grpc_completion_queue *cq,
-                            grpc_call **call, grpc_call_details *details,
-                            grpc_metadata_array *initial_metadata,
-                            call_data *calld, void *user_data);
-
-typedef struct {
-  void *user_data;
-  grpc_completion_queue *cq;
-  grpc_call **call;
-  grpc_call_details *details;
-  grpc_metadata_array *initial_metadata;
-  new_call_cb cb;
-} requested_call;
-
 struct grpc_server {
   size_t channel_filter_count;
   const grpc_channel_filter **channel_filters;
   grpc_channel_args *channel_args;
-  grpc_completion_queue *cq;
+  grpc_completion_queue *unregistered_cq;
+
+  grpc_completion_queue **cqs;
+  grpc_pollset **pollsets;
+  size_t cq_count;
 
   gpr_mu mu;
 
-  requested_call *requested_calls;
-  size_t requested_call_count;
-  size_t requested_call_capacity;
+  registered_method *registered_methods;
+  requested_call_array requested_calls;
 
   gpr_uint8 shutdown;
   size_t num_shutdown_tags;
@@ -108,11 +151,6 @@ struct grpc_server {
   gpr_refcount internal_refcount;
 };
 
-typedef struct {
-  call_data *next;
-  call_data *prev;
-} call_link;
-
 typedef enum {
   /* waiting for metadata */
   NOT_STARTED,
@@ -125,7 +163,7 @@ typedef enum {
 } call_state;
 
 typedef struct legacy_data {
-  grpc_metadata_array *initial_metadata;
+  grpc_metadata_array initial_metadata;
 } legacy_data;
 
 struct call_data {
@@ -137,9 +175,9 @@ struct call_data {
   grpc_mdstr *host;
 
   legacy_data *legacy;
-  grpc_call_details *details;
+  grpc_completion_queue *cq_new;
 
-  gpr_uint8 included[CALL_LIST_COUNT];
+  call_data **root[CALL_LIST_COUNT];
   call_link links[CALL_LIST_COUNT];
 };
 
@@ -148,30 +186,33 @@ struct call_data {
 
 static void do_nothing(void *unused, grpc_op_error ignored) {}
 
-static int call_list_join(grpc_server *server, call_data *call,
-                          call_list list) {
-  if (call->included[list]) return 0;
-  call->included[list] = 1;
-  if (!server->lists[list]) {
-    server->lists[list] = call;
+static void begin_call(grpc_server *server, call_data *calld,
+                       requested_call *rc);
+static void fail_call(grpc_server *server, requested_call *rc);
+
+static int call_list_join(call_data **root, call_data *call, call_list list) {
+  GPR_ASSERT(!call->root[list]);
+  call->root[list] = root;
+  if (!*root) {
+    *root = call;
     call->links[list].next = call->links[list].prev = call;
   } else {
-    call->links[list].next = server->lists[list];
-    call->links[list].prev = server->lists[list]->links[list].prev;
+    call->links[list].next = *root;
+    call->links[list].prev = (*root)->links[list].prev;
     call->links[list].next->links[list].prev =
         call->links[list].prev->links[list].next = call;
   }
   return 1;
 }
 
-static call_data *call_list_remove_head(grpc_server *server, call_list list) {
-  call_data *out = server->lists[list];
+static call_data *call_list_remove_head(call_data **root, call_list list) {
+  call_data *out = *root;
   if (out) {
-    out->included[list] = 0;
+    out->root[list] = NULL;
     if (out->links[list].next == out) {
-      server->lists[list] = NULL;
+      *root = NULL;
     } else {
-      server->lists[list] = out->links[list].next;
+      *root = out->links[list].next;
       out->links[list].next->links[list].prev = out->links[list].prev;
       out->links[list].prev->links[list].next = out->links[list].next;
     }
@@ -179,33 +220,59 @@ static call_data *call_list_remove_head(grpc_server *server, call_list list) {
   return out;
 }
 
-static int call_list_remove(grpc_server *server, call_data *call,
-                            call_list list) {
-  if (!call->included[list]) return 0;
-  call->included[list] = 0;
-  if (server->lists[list] == call) {
-    server->lists[list] = call->links[list].next;
-    if (server->lists[list] == call) {
-      server->lists[list] = NULL;
+static int call_list_remove(call_data *call, call_list list) {
+  call_data **root = call->root[list];
+  if (root == NULL) return 0;
+  call->root[list] = NULL;
+  if (*root == call) {
+    *root = call->links[list].next;
+    if (*root == call) {
+      *root = NULL;
       return 1;
     }
   }
-  GPR_ASSERT(server->lists[list] != call);
+  GPR_ASSERT(*root != call);
   call->links[list].next->links[list].prev = call->links[list].prev;
   call->links[list].prev->links[list].next = call->links[list].next;
   return 1;
 }
 
+static void requested_call_array_destroy(requested_call_array *array) {
+  gpr_free(array->calls);
+}
+
+static requested_call *requested_call_array_add(requested_call_array *array) {
+  requested_call *rc;
+  if (array->count == array->capacity) {
+    array->capacity = GPR_MAX(array->capacity + 8, array->capacity * 2);
+    array->calls =
+        gpr_realloc(array->calls, sizeof(requested_call) * array->capacity);
+  }
+  rc = &array->calls[array->count++];
+  memset(rc, 0, sizeof(*rc));
+  return rc;
+}
+
 static void server_ref(grpc_server *server) {
   gpr_ref(&server->internal_refcount);
 }
 
 static void server_unref(grpc_server *server) {
+  registered_method *rm;
   if (gpr_unref(&server->internal_refcount)) {
     grpc_channel_args_destroy(server->channel_args);
     gpr_mu_destroy(&server->mu);
     gpr_free(server->channel_filters);
-    gpr_free(server->requested_calls);
+    requested_call_array_destroy(&server->requested_calls);
+    while ((rm = server->registered_methods) != NULL) {
+      server->registered_methods = rm->next;
+      gpr_free(rm->method);
+      gpr_free(rm->host);
+      requested_call_array_destroy(&rm->requested);
+      gpr_free(rm);
+    }
+    gpr_free(server->cqs);
+    gpr_free(server->pollsets);
     gpr_free(server->shutdown_tags);
     gpr_free(server);
   }
@@ -224,7 +291,6 @@ static void orphan_channel(channel_data *chand) {
 static void finish_destroy_channel(void *cd, int success) {
   channel_data *chand = cd;
   grpc_server *server = chand->server;
-  /*gpr_log(GPR_INFO, "destroy channel %p", chand->channel);*/
   grpc_channel_destroy(chand->channel);
   server_unref(server);
 }
@@ -237,23 +303,64 @@ static void destroy_channel(channel_data *chand) {
   grpc_iomgr_add_callback(finish_destroy_channel, chand);
 }
 
+static void finish_start_new_rpc_and_unlock(grpc_server *server,
+                                            grpc_call_element *elem,
+                                            call_data **pending_root,
+                                            requested_call_array *array) {
+  requested_call rc;
+  call_data *calld = elem->call_data;
+  if (array->count == 0) {
+    calld->state = PENDING;
+    call_list_join(pending_root, calld, PENDING_START);
+    gpr_mu_unlock(&server->mu);
+  } else {
+    rc = array->calls[--array->count];
+    calld->state = ACTIVATED;
+    gpr_mu_unlock(&server->mu);
+    begin_call(server, calld, &rc);
+  }
+}
+
 static void start_new_rpc(grpc_call_element *elem) {
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
   grpc_server *server = chand->server;
+  gpr_uint32 i;
+  gpr_uint32 hash;
+  channel_registered_method *rm;
 
   gpr_mu_lock(&server->mu);
-  if (server->requested_call_count > 0) {
-    requested_call rc = server->requested_calls[--server->requested_call_count];
-    calld->state = ACTIVATED;
-    gpr_mu_unlock(&server->mu);
-    rc.cb(server, rc.cq, rc.call, rc.details, rc.initial_metadata, calld,
-          rc.user_data);
-  } else {
-    calld->state = PENDING;
-    call_list_join(server, calld, PENDING_START);
-    gpr_mu_unlock(&server->mu);
+  if (chand->registered_methods && calld->path && calld->host) {
+    /* TODO(ctiller): unify these two searches */
+    /* check for an exact match with host */
+    hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
+    for (i = 0; i < chand->registered_method_max_probes; i++) {
+      rm = &chand->registered_methods[(hash + i) %
+                                      chand->registered_method_slots];
+      if (!rm) break;
+      if (rm->host != calld->host) continue;
+      if (rm->method != calld->path) continue;
+      finish_start_new_rpc_and_unlock(server, elem,
+                                      &rm->server_registered_method->pending,
+                                      &rm->server_registered_method->requested);
+      return;
+    }
+    /* check for a wildcard method definition (no host set) */
+    hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
+    for (i = 0; i <= chand->registered_method_max_probes; i++) {
+      rm = &chand->registered_methods[(hash + i) %
+                                      chand->registered_method_slots];
+      if (!rm) break;
+      if (rm->host != NULL) continue;
+      if (rm->method != calld->path) continue;
+      finish_start_new_rpc_and_unlock(server, elem,
+                                      &rm->server_registered_method->pending,
+                                      &rm->server_registered_method->requested);
+      return;
+    }
   }
+  finish_start_new_rpc_and_unlock(server, elem, &server->lists[PENDING_START],
+                                  &server->requested_calls);
 }
 
 static void kill_zombie(void *elem, int success) {
@@ -268,7 +375,7 @@ static void stream_closed(grpc_call_element *elem) {
     case ACTIVATED:
       break;
     case PENDING:
-      call_list_remove(chand->server, calld, PENDING_START);
+      call_list_remove(calld, PENDING_START);
     /* fallthrough intended */
     case NOT_STARTED:
       calld->state = ZOMBIED;
@@ -399,7 +506,7 @@ static void init_call_elem(grpc_call_element *elem,
   calld->call = grpc_call_from_top_element(elem);
 
   gpr_mu_lock(&chand->server->mu);
-  call_list_join(chand->server, calld, ALL_CALLS);
+  call_list_join(&chand->server->lists[ALL_CALLS], calld, ALL_CALLS);
   gpr_mu_unlock(&chand->server->mu);
 
   server_ref(chand->server);
@@ -408,16 +515,18 @@ static void init_call_elem(grpc_call_element *elem,
 static void destroy_call_elem(grpc_call_element *elem) {
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
-  size_t i;
+  size_t i, j;
 
   gpr_mu_lock(&chand->server->mu);
   for (i = 0; i < CALL_LIST_COUNT; i++) {
-    call_list_remove(chand->server, elem->call_data, i);
+    call_list_remove(elem->call_data, i);
   }
   if (chand->server->shutdown && chand->server->lists[ALL_CALLS] == NULL) {
     for (i = 0; i < chand->server->num_shutdown_tags; i++) {
-      grpc_cq_end_server_shutdown(chand->server->cq,
-                                  chand->server->shutdown_tags[i]);
+      for (j = 0; j < chand->server->cq_count; j++) {
+        grpc_cq_end_server_shutdown(chand->server->cqs[j],
+                                    chand->server->shutdown_tags[i]);
+      }
     }
   }
   gpr_mu_unlock(&chand->server->mu);
@@ -430,8 +539,7 @@ static void destroy_call_elem(grpc_call_element *elem) {
   }
 
   if (calld->legacy) {
-    gpr_free(calld->legacy->initial_metadata->metadata);
-    gpr_free(calld->legacy->initial_metadata);
+    gpr_free(calld->legacy->initial_metadata.metadata);
     gpr_free(calld->legacy);
   }
 
@@ -450,10 +558,23 @@ static void init_channel_elem(grpc_channel_element *elem,
   chand->path_key = grpc_mdstr_from_string(metadata_context, ":path");
   chand->authority_key = grpc_mdstr_from_string(metadata_context, ":authority");
   chand->next = chand->prev = chand;
+  chand->registered_methods = NULL;
 }
 
 static void destroy_channel_elem(grpc_channel_element *elem) {
+  size_t i;
   channel_data *chand = elem->channel_data;
+  if (chand->registered_methods) {
+    for (i = 0; i < chand->registered_method_slots; i++) {
+      if (chand->registered_methods[i].method) {
+        grpc_mdstr_unref(chand->registered_methods[i].method);
+      }
+      if (chand->registered_methods[i].host) {
+        grpc_mdstr_unref(chand->registered_methods[i].host);
+      }
+    }
+    gpr_free(chand->registered_methods);
+  }
   if (chand->server) {
     gpr_mu_lock(&chand->server->mu);
     chand->next->prev = chand->prev;
@@ -472,6 +593,17 @@ static const grpc_channel_filter server_surface_filter = {
     init_channel_elem, destroy_channel_elem, "server",
 };
 
+static void addcq(grpc_server *server, grpc_completion_queue *cq) {
+  size_t i, n;
+  for (i = 0; i < server->cq_count; i++) {
+    if (server->cqs[i] == cq) return;
+  }
+  n = server->cq_count++;
+  server->cqs = gpr_realloc(server->cqs,
+                            server->cq_count * sizeof(grpc_completion_queue *));
+  server->cqs[n] = cq;
+}
+
 grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
                                              grpc_channel_filter **filters,
                                              size_t filter_count,
@@ -481,10 +613,11 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
 
   grpc_server *server = gpr_malloc(sizeof(grpc_server));
   memset(server, 0, sizeof(grpc_server));
+  if (cq) addcq(server, cq);
 
   gpr_mu_init(&server->mu);
 
-  server->cq = cq;
+  server->unregistered_cq = cq;
   /* decremented by grpc_server_destroy */
   gpr_ref_init(&server->internal_refcount, 1);
   server->root_channel_data.next = server->root_channel_data.prev =
@@ -512,11 +645,50 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
   return server;
 }
 
+static int streq(const char *a, const char *b) {
+  if (a == NULL && b == NULL) return 1;
+  if (a == NULL) return 0;
+  if (b == NULL) return 0;
+  return 0 == strcmp(a, b);
+}
+
+void *grpc_server_register_method(grpc_server *server, const char *method,
+                                  const char *host,
+                                  grpc_completion_queue *cq_new_rpc) {
+  registered_method *m;
+  if (!method) {
+    gpr_log(GPR_ERROR, "%s method string cannot be NULL", __FUNCTION__);
+    return NULL;
+  }
+  for (m = server->registered_methods; m; m = m->next) {
+    if (streq(m->method, method) && streq(m->host, host)) {
+      gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
+              host ? host : "*");
+      return NULL;
+    }
+  }
+  addcq(server, cq_new_rpc);
+  m = gpr_malloc(sizeof(registered_method));
+  memset(m, 0, sizeof(*m));
+  m->method = gpr_strdup(method);
+  m->host = gpr_strdup(host);
+  m->next = server->registered_methods;
+  m->cq = cq_new_rpc;
+  server->registered_methods = m;
+  return m;
+}
+
 void grpc_server_start(grpc_server *server) {
   listener *l;
+  size_t i;
+
+  server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
+  for (i = 0; i < server->cq_count; i++) {
+    server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
+  }
 
   for (l = server->listeners; l; l = l->next) {
-    l->start(server, l->arg, grpc_cq_pollset(server->cq));
+    l->start(server, l->arg, server->pollsets, server->cq_count);
   }
 }
 
@@ -528,8 +700,19 @@ grpc_transport_setup_result grpc_server_setup_transport(
   grpc_channel_filter const **filters =
       gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
   size_t i;
+  size_t num_registered_methods;
+  size_t alloc;
+  registered_method *rm;
+  channel_registered_method *crm;
   grpc_channel *channel;
   channel_data *chand;
+  grpc_mdstr *host;
+  grpc_mdstr *method;
+  gpr_uint32 hash;
+  gpr_uint32 slots;
+  gpr_uint32 probes;
+  gpr_uint32 max_probes = 0;
+  grpc_transport_setup_result result;
 
   for (i = 0; i < s->channel_filter_count; i++) {
     filters[i] = s->channel_filters[i];
@@ -539,7 +722,9 @@ grpc_transport_setup_result grpc_server_setup_transport(
   }
   filters[i] = &grpc_connected_channel_filter;
 
-  grpc_transport_add_to_pollset(transport, grpc_cq_pollset(s->cq));
+  for (i = 0; i < s->cq_count; i++) {
+    grpc_transport_add_to_pollset(transport, grpc_cq_pollset(s->cqs[i]));
+  }
 
   channel = grpc_channel_create_from_filters(filters, num_filters,
                                              s->channel_args, mdctx, 0);
@@ -549,6 +734,38 @@ grpc_transport_setup_result grpc_server_setup_transport(
   server_ref(s);
   chand->channel = channel;
 
+  num_registered_methods = 0;
+  for (rm = s->registered_methods; rm; rm = rm->next) {
+    num_registered_methods++;
+  }
+  /* build a lookup table phrased in terms of mdstr's in this channels context
+     to quickly find registered methods */
+  if (num_registered_methods > 0) {
+    slots = 2 * num_registered_methods;
+    alloc = sizeof(channel_registered_method) * slots;
+    chand->registered_methods = gpr_malloc(alloc);
+    memset(chand->registered_methods, 0, alloc);
+    for (rm = s->registered_methods; rm; rm = rm->next) {
+      host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host) : NULL;
+      method = grpc_mdstr_from_string(mdctx, rm->method);
+      hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
+      for (probes = 0; chand->registered_methods[(hash + probes) % slots]
+                               .server_registered_method != NULL;
+           probes++)
+        ;
+      if (probes > max_probes) max_probes = probes;
+      crm = &chand->registered_methods[(hash + probes) % slots];
+      crm->server_registered_method = rm;
+      crm->host = host;
+      crm->method = method;
+    }
+    chand->registered_method_slots = slots;
+    chand->registered_method_max_probes = max_probes;
+  }
+
+  result = grpc_connected_channel_bind_transport(
+      grpc_channel_get_channel_stack(channel), transport);
+
   gpr_mu_lock(&s->mu);
   chand->next = &s->root_channel_data;
   chand->prev = chand->next->prev;
@@ -557,26 +774,27 @@ grpc_transport_setup_result grpc_server_setup_transport(
 
   gpr_free(filters);
 
-  return grpc_connected_channel_bind_transport(
-      grpc_channel_get_channel_stack(channel), transport);
+  return result;
 }
 
-void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
-                       void *shutdown_tag) {
+static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
+                              void *shutdown_tag) {
   listener *l;
-  requested_call *requested_calls;
-  size_t requested_call_count;
+  requested_call_array requested_calls;
   channel_data **channels;
   channel_data *c;
   size_t nchannels;
-  size_t i;
+  size_t i, j;
   grpc_channel_op op;
   grpc_channel_element *elem;
+  registered_method *rm;
 
   /* lock, and gather up some stuff to do */
   gpr_mu_lock(&server->mu);
   if (have_shutdown_tag) {
-    grpc_cq_begin_op(server->cq, NULL, GRPC_SERVER_SHUTDOWN);
+    for (i = 0; i < server->cq_count; i++) {
+      grpc_cq_begin_op(server->cqs[i], NULL, GRPC_SERVER_SHUTDOWN);
+    }
     server->shutdown_tags =
         gpr_realloc(server->shutdown_tags,
                     sizeof(void *) * (server->num_shutdown_tags + 1));
@@ -601,15 +819,32 @@ void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
     i++;
   }
 
+  /* collect all unregistered then registered calls */
   requested_calls = server->requested_calls;
-  requested_call_count = server->requested_call_count;
-  server->requested_calls = NULL;
-  server->requested_call_count = 0;
+  memset(&server->requested_calls, 0, sizeof(server->requested_calls));
+  for (rm = server->registered_methods; rm; rm = rm->next) {
+    if (requested_calls.count + rm->requested.count >
+        requested_calls.capacity) {
+      requested_calls.capacity =
+          GPR_MAX(requested_calls.count + rm->requested.count,
+                  2 * requested_calls.capacity);
+      requested_calls.calls =
+          gpr_realloc(requested_calls.calls, sizeof(*requested_calls.calls) *
+                                                 requested_calls.capacity);
+    }
+    memcpy(requested_calls.calls + requested_calls.count, rm->requested.calls,
+           sizeof(*requested_calls.calls) * rm->requested.count);
+    requested_calls.count += rm->requested.count;
+    gpr_free(rm->requested.calls);
+    memset(&rm->requested, 0, sizeof(rm->requested));
+  }
 
   server->shutdown = 1;
   if (server->lists[ALL_CALLS] == NULL) {
     for (i = 0; i < server->num_shutdown_tags; i++) {
-      grpc_cq_end_server_shutdown(server->cq, server->shutdown_tags[i]);
+      for (j = 0; j < server->cq_count; j++) {
+        grpc_cq_end_server_shutdown(server->cqs[j], server->shutdown_tags[i]);
+      }
     }
   }
   gpr_mu_unlock(&server->mu);
@@ -630,13 +865,10 @@ void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
   gpr_free(channels);
 
   /* terminate all the requested calls */
-  for (i = 0; i < requested_call_count; i++) {
-    requested_calls[i].cb(server, requested_calls[i].cq,
-                          requested_calls[i].call, requested_calls[i].details,
-                          requested_calls[i].initial_metadata, NULL,
-                          requested_calls[i].user_data);
+  for (i = 0; i < requested_calls.count; i++) {
+    fail_call(server, &requested_calls.calls[i]);
   }
-  gpr_free(requested_calls);
+  gpr_free(requested_calls.calls);
 
   /* Shutdown listeners */
   for (l = server->listeners; l; l = l->next) {
@@ -677,7 +909,8 @@ void grpc_server_destroy(grpc_server *server) {
 
 void grpc_server_add_listener(grpc_server *server, void *arg,
                               void (*start)(grpc_server *server, void *arg,
-                                            grpc_pollset *pollset),
+                                            grpc_pollset **pollsets,
+                                            size_t pollset_count),
                               void (*destroy)(grpc_server *server, void *arg)) {
   listener *l = gpr_malloc(sizeof(listener));
   l->arg = arg;
@@ -688,47 +921,92 @@ void grpc_server_add_listener(grpc_server *server, void *arg,
 }
 
 static grpc_call_error queue_call_request(grpc_server *server,
-                                          grpc_completion_queue *cq,
-                                          grpc_call **call,
-                                          grpc_call_details *details,
-                                          grpc_metadata_array *initial_metadata,
-                                          new_call_cb cb, void *user_data) {
-  call_data *calld;
-  requested_call *rc;
+                                          requested_call *rc) {
+  call_data *calld = NULL;
+  requested_call_array *requested_calls = NULL;
   gpr_mu_lock(&server->mu);
   if (server->shutdown) {
     gpr_mu_unlock(&server->mu);
-    cb(server, cq, call, details, initial_metadata, NULL, user_data);
+    fail_call(server, rc);
     return GRPC_CALL_OK;
   }
-  calld = call_list_remove_head(server, PENDING_START);
+  switch (rc->type) {
+    case LEGACY_CALL:
+    case BATCH_CALL:
+      calld =
+          call_list_remove_head(&server->lists[PENDING_START], PENDING_START);
+      requested_calls = &server->requested_calls;
+      break;
+    case REGISTERED_CALL:
+      calld = call_list_remove_head(
+          &rc->data.registered.registered_method->pending, PENDING_START);
+      requested_calls = &rc->data.registered.registered_method->requested;
+      break;
+  }
   if (calld) {
     GPR_ASSERT(calld->state == PENDING);
     calld->state = ACTIVATED;
     gpr_mu_unlock(&server->mu);
-    cb(server, cq, call, details, initial_metadata, calld, user_data);
+    begin_call(server, calld, rc);
     return GRPC_CALL_OK;
   } else {
-    if (server->requested_call_count == server->requested_call_capacity) {
-      server->requested_call_capacity =
-          GPR_MAX(server->requested_call_capacity + 8,
-                  server->requested_call_capacity * 2);
-      server->requested_calls =
-          gpr_realloc(server->requested_calls,
-                      sizeof(requested_call) * server->requested_call_capacity);
-    }
-    rc = &server->requested_calls[server->requested_call_count++];
-    rc->cb = cb;
-    rc->cq = cq;
-    rc->call = call;
-    rc->details = details;
-    rc->user_data = user_data;
-    rc->initial_metadata = initial_metadata;
+    *requested_call_array_add(requested_calls) = *rc;
     gpr_mu_unlock(&server->mu);
     return GRPC_CALL_OK;
   }
 }
 
+grpc_call_error grpc_server_request_call(grpc_server *server, grpc_call **call,
+                                         grpc_call_details *details,
+                                         grpc_metadata_array *initial_metadata,
+                                         grpc_completion_queue *cq_bind,
+                                         void *tag) {
+  requested_call rc;
+  grpc_cq_begin_op(server->unregistered_cq, NULL, GRPC_OP_COMPLETE);
+  rc.type = BATCH_CALL;
+  rc.tag = tag;
+  rc.data.batch.cq_bind = cq_bind;
+  rc.data.batch.call = call;
+  rc.data.batch.details = details;
+  rc.data.batch.initial_metadata = initial_metadata;
+  return queue_call_request(server, &rc);
+}
+
+grpc_call_error grpc_server_request_registered_call(
+    grpc_server *server, void *rm, grpc_call **call, gpr_timespec *deadline,
+    grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
+    grpc_completion_queue *cq_bind, void *tag) {
+  requested_call rc;
+  registered_method *registered_method = rm;
+  grpc_cq_begin_op(registered_method->cq, NULL, GRPC_OP_COMPLETE);
+  rc.type = REGISTERED_CALL;
+  rc.tag = tag;
+  rc.data.registered.cq_bind = cq_bind;
+  rc.data.registered.call = call;
+  rc.data.registered.registered_method = registered_method;
+  rc.data.registered.deadline = deadline;
+  rc.data.registered.initial_metadata = initial_metadata;
+  rc.data.registered.optional_payload = optional_payload;
+  return queue_call_request(server, &rc);
+}
+
+grpc_call_error grpc_server_request_call_old(grpc_server *server,
+                                             void *tag_new) {
+  requested_call rc;
+  grpc_cq_begin_op(server->unregistered_cq, NULL, GRPC_SERVER_RPC_NEW);
+  rc.type = LEGACY_CALL;
+  rc.tag = tag_new;
+  return queue_call_request(server, &rc);
+}
+
+static void publish_legacy(grpc_call *call, grpc_op_error status, void *tag);
+static void publish_registered_or_batch(grpc_call *call, grpc_op_error status,
+                                        void *tag);
+static void publish_was_not_set(grpc_call *call, grpc_op_error status,
+                                void *tag) {
+  abort();
+}
+
 static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
   gpr_slice slice = value->slice;
   size_t len = GPR_SLICE_LENGTH(slice);
@@ -740,57 +1018,84 @@ static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
   memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
 }
 
-static void publish_request(grpc_call *call, grpc_op_error status, void *tag) {
-  grpc_call_element *elem =
-      grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
-  call_data *calld = elem->call_data;
-  channel_data *chand = elem->channel_data;
-  grpc_server *server = chand->server;
-
-  if (status == GRPC_OP_OK) {
-    cpstr(&calld->details->host, &calld->details->host_capacity, calld->host);
-    cpstr(&calld->details->method, &calld->details->method_capacity,
-          calld->path);
-    calld->details->deadline = calld->deadline;
-    grpc_cq_end_op_complete(server->cq, tag, call, do_nothing, NULL,
-                            GRPC_OP_OK);
-  } else {
-    abort();
+static void begin_call(grpc_server *server, call_data *calld,
+                       requested_call *rc) {
+  grpc_ioreq_completion_func publish = publish_was_not_set;
+  grpc_ioreq req[2];
+  grpc_ioreq *r = req;
+
+  /* called once initial metadata has been read by the call, but BEFORE
+     the ioreq to fetch it out of the call has been executed.
+     This means metadata related fields can be relied on in calld, but to
+     fill in the metadata array passed by the client, we need to perform
+     an ioreq op, that should complete immediately. */
+
+  switch (rc->type) {
+    case LEGACY_CALL:
+      calld->legacy = gpr_malloc(sizeof(legacy_data));
+      memset(calld->legacy, 0, sizeof(legacy_data));
+      r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
+      r->data.recv_metadata = &calld->legacy->initial_metadata;
+      r++;
+      publish = publish_legacy;
+      break;
+    case BATCH_CALL:
+      cpstr(&rc->data.batch.details->host,
+            &rc->data.batch.details->host_capacity, calld->host);
+      cpstr(&rc->data.batch.details->method,
+            &rc->data.batch.details->method_capacity, calld->path);
+      grpc_call_set_completion_queue(calld->call, rc->data.batch.cq_bind);
+      *rc->data.batch.call = calld->call;
+      r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
+      r->data.recv_metadata = rc->data.batch.initial_metadata;
+      r++;
+      calld->cq_new = server->unregistered_cq;
+      publish = publish_registered_or_batch;
+      break;
+    case REGISTERED_CALL:
+      *rc->data.registered.deadline = calld->deadline;
+      grpc_call_set_completion_queue(calld->call, rc->data.registered.cq_bind);
+      *rc->data.registered.call = calld->call;
+      r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
+      r->data.recv_metadata = rc->data.registered.initial_metadata;
+      r++;
+      if (rc->data.registered.optional_payload) {
+        r->op = GRPC_IOREQ_RECV_MESSAGE;
+        r->data.recv_message = rc->data.registered.optional_payload;
+        r++;
+      }
+      calld->cq_new = rc->data.registered.registered_method->cq;
+      publish = publish_registered_or_batch;
+      break;
   }
-}
 
-static void begin_request(grpc_server *server, grpc_completion_queue *cq,
-                          grpc_call **call, grpc_call_details *details,
-                          grpc_metadata_array *initial_metadata,
-                          call_data *calld, void *tag) {
-  grpc_ioreq req;
-  if (!calld) {
-    *call = NULL;
-    initial_metadata->count = 0;
-    grpc_cq_end_op_complete(cq, tag, NULL, do_nothing, NULL, GRPC_OP_ERROR);
-    return;
-  }
-  calld->details = details;
-  grpc_call_set_completion_queue(calld->call, cq);
-  *call = calld->call;
-  req.op = GRPC_IOREQ_RECV_INITIAL_METADATA;
-  req.data.recv_metadata = initial_metadata;
   grpc_call_internal_ref(calld->call);
-  grpc_call_start_ioreq_and_call_back(calld->call, &req, 1, publish_request,
-                                      tag);
+  grpc_call_start_ioreq_and_call_back(calld->call, req, r - req, publish,
+                                      rc->tag);
 }
 
-grpc_call_error grpc_server_request_call(grpc_server *server, grpc_call **call,
-                                         grpc_call_details *details,
-                                         grpc_metadata_array *initial_metadata,
-                                         grpc_completion_queue *cq, void *tag) {
-  grpc_cq_begin_op(cq, NULL, GRPC_OP_COMPLETE);
-  return queue_call_request(server, cq, call, details, initial_metadata,
-                            begin_request, tag);
+static void fail_call(grpc_server *server, requested_call *rc) {
+  switch (rc->type) {
+    case LEGACY_CALL:
+      grpc_cq_end_new_rpc(server->unregistered_cq, rc->tag, NULL, do_nothing,
+                          NULL, NULL, NULL, gpr_inf_past, 0, NULL);
+      break;
+    case BATCH_CALL:
+      *rc->data.batch.call = NULL;
+      rc->data.batch.initial_metadata->count = 0;
+      grpc_cq_end_op_complete(server->unregistered_cq, rc->tag, NULL,
+                              do_nothing, NULL, GRPC_OP_ERROR);
+      break;
+    case REGISTERED_CALL:
+      *rc->data.registered.call = NULL;
+      rc->data.registered.initial_metadata->count = 0;
+      grpc_cq_end_op_complete(rc->data.registered.registered_method->cq,
+                              rc->tag, NULL, do_nothing, NULL, GRPC_OP_ERROR);
+      break;
+  }
 }
 
-static void publish_legacy_request(grpc_call *call, grpc_op_error status,
-                                   void *tag) {
+static void publish_legacy(grpc_call *call, grpc_op_error status, void *tag) {
   grpc_call_element *elem =
       grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
   call_data *calld = elem->call_data;
@@ -798,47 +1103,23 @@ static void publish_legacy_request(grpc_call *call, grpc_op_error status,
   grpc_server *server = chand->server;
 
   if (status == GRPC_OP_OK) {
-    grpc_cq_end_new_rpc(server->cq, tag, call, do_nothing, NULL,
+    grpc_cq_end_new_rpc(server->unregistered_cq, tag, call, do_nothing, NULL,
                         grpc_mdstr_as_c_string(calld->path),
                         grpc_mdstr_as_c_string(calld->host), calld->deadline,
-                        calld->legacy->initial_metadata->count,
-                        calld->legacy->initial_metadata->metadata);
+                        calld->legacy->initial_metadata.count,
+                        calld->legacy->initial_metadata.metadata);
   } else {
+    gpr_log(GPR_ERROR, "should never reach here");
     abort();
   }
 }
 
-static void begin_legacy_request(grpc_server *server, grpc_completion_queue *cq,
-                                 grpc_call **call, grpc_call_details *details,
-                                 grpc_metadata_array *initial_metadata,
-                                 call_data *calld, void *tag) {
-  grpc_ioreq req;
-  GPR_ASSERT(call == NULL);
-  GPR_ASSERT(details == NULL);
-  if (!calld) {
-    gpr_free(initial_metadata);
-    grpc_cq_end_new_rpc(cq, tag, NULL, do_nothing, NULL, NULL, NULL,
-                        gpr_inf_past, 0, NULL);
-    return;
-  }
-  req.op = GRPC_IOREQ_RECV_INITIAL_METADATA;
-  req.data.recv_metadata = initial_metadata;
-  calld->legacy = gpr_malloc(sizeof(legacy_data));
-  memset(calld->legacy, 0, sizeof(legacy_data));
-  calld->legacy->initial_metadata = initial_metadata;
-  grpc_call_internal_ref(calld->call);
-  grpc_call_start_ioreq_and_call_back(calld->call, &req, 1,
-                                      publish_legacy_request, tag);
-}
-
-grpc_call_error grpc_server_request_call_old(grpc_server *server,
-                                             void *tag_new) {
-  grpc_metadata_array *client_metadata =
-      gpr_malloc(sizeof(grpc_metadata_array));
-  memset(client_metadata, 0, sizeof(*client_metadata));
-  grpc_cq_begin_op(server->cq, NULL, GRPC_SERVER_RPC_NEW);
-  return queue_call_request(server, server->cq, NULL, NULL, client_metadata,
-                            begin_legacy_request, tag_new);
+static void publish_registered_or_batch(grpc_call *call, grpc_op_error status,
+                                        void *tag) {
+  grpc_call_element *elem =
+      grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
+  call_data *calld = elem->call_data;
+  grpc_cq_end_op_complete(calld->cq_new, tag, call, do_nothing, NULL, status);
 }
 
 const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index 50574d66a404c8971816059430075cdefc56232f..5ae59b22554fc4c0c16e93209f8309cdbc877efc 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,7 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
    and when it shuts down, it will call destroy */
 void grpc_server_add_listener(grpc_server *server, void *listener,
                               void (*start)(grpc_server *server, void *arg,
-                                            grpc_pollset *pollset),
+                                            grpc_pollset **pollsets, size_t npollsets),
                               void (*destroy)(grpc_server *server, void *arg));
 
 /* Setup a transport - creates a channel stack, binds the transport to the
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index 5ba7d47efd97a8de0f5873dff5de364fdc00783e..fd702593b89dfdcef593f5061003ef21320070ce 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,9 +59,9 @@ static void new_transport(void *server, grpc_endpoint *tcp) {
 }
 
 /* Server callback: start listening on our ports */
-static void start(grpc_server *server, void *tcpp, grpc_pollset *pollset) {
+static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) {
   grpc_tcp_server *tcp = tcpp;
-  grpc_tcp_server_start(tcp, pollset, new_transport, server);
+  grpc_tcp_server_start(tcp, pollsets, pollset_count, new_transport, server);
 }
 
 /* Server callback: destroy the tcp listener (so we don't generate further
diff --git a/src/core/surface/server_create.c b/src/core/surface/server_create.c
index dcc6ce1ccc8ffc060c707c48e8dda0c5d6b468f1..f629c7c72de87ea3d48fd22d59877241633a79df 100644
--- a/src/core/surface/server_create.c
+++ b/src/core/surface/server_create.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h
index df1aea9669ea5c3424f6e83c5d20ee9c176f7e4a..f998de1ad6aaf8da4f9da41f8f7793b3070c397e 100644
--- a/src/core/surface/surface_trace.h
+++ b/src/core/surface/surface_trace.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/alpn.c b/src/core/transport/chttp2/alpn.c
index bc4e789f60cf632c2592b519d2447019e61fde32..11901a58a060f601ea096d00f3ef8594e0b16d66 100644
--- a/src/core/transport/chttp2/alpn.c
+++ b/src/core/transport/chttp2/alpn.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/alpn.h b/src/core/transport/chttp2/alpn.h
index cb96f17831f713a96ef11b441bb0c038233ef643..796f514f19ed918fff38cb47f913c388621644bd 100644
--- a/src/core/transport/chttp2/alpn.h
+++ b/src/core/transport/chttp2/alpn.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/bin_encoder.c b/src/core/transport/chttp2/bin_encoder.c
index e3b5fe9fcf7f1dc4d1364cece50e7ffaea22b271..f5ca6c4e50620796f8837edf72e0fc15e00fb63c 100644
--- a/src/core/transport/chttp2/bin_encoder.c
+++ b/src/core/transport/chttp2/bin_encoder.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/bin_encoder.h b/src/core/transport/chttp2/bin_encoder.h
index 2310f841f8b0622bb7f1e1194a54972592e9a919..2368fdd738c768ca774b97723be8872428b10408 100644
--- a/src/core/transport/chttp2/bin_encoder.h
+++ b/src/core/transport/chttp2/bin_encoder.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h
index 6d286383091b2d067e4a0ba827a0d3594f016fa2..733dd5eec48951da1aae5433fa95c67bad1519ea 100644
--- a/src/core/transport/chttp2/frame.h
+++ b/src/core/transport/chttp2/frame.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
index c4ad8f11d5c8b30064bc15ff90b3091da755cdb1..a1ae9ed2e653f712d6c93a3829900ccb08325fb6 100644
--- a/src/core/transport/chttp2/frame_data.c
+++ b/src/core/transport/chttp2/frame_data.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -135,7 +135,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
     case GRPC_CHTTP2_DATA_FRAME:
       if (cur == end) {
         return GRPC_CHTTP2_PARSE_OK;
-      } else if (end - cur == p->frame_size) {
+      } else if ((gpr_uint32)(end - cur) == p->frame_size) {
         state->need_flush_reads = 1;
         grpc_sopb_add_slice(&p->incoming_sopb,
                             gpr_slice_sub(slice, cur - beg, end - beg));
diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h
index c260059e8b90a37e680b6f82a421ccfcc9c30a1c..4d05a5f45291e9528957da5f1acca2cc2c9ff679 100644
--- a/src/core/transport/chttp2/frame_data.h
+++ b/src/core/transport/chttp2/frame_data.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_goaway.c b/src/core/transport/chttp2/frame_goaway.c
index 3d6e9431933bf46bf2d53d5f3586291b9f5d0837..95b75d4fded380dfefd4fdcc6f3eb31d75d5274d 100644
--- a/src/core/transport/chttp2/frame_goaway.c
+++ b/src/core/transport/chttp2/frame_goaway.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_goaway.h b/src/core/transport/chttp2/frame_goaway.h
index 9a3f8e6a7a62d97d921d711e76fb401b66f8cab3..9ccef276346c5053405d2919cf60d67dfa863f3d 100644
--- a/src/core/transport/chttp2/frame_goaway.h
+++ b/src/core/transport/chttp2/frame_goaway.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_ping.c b/src/core/transport/chttp2/frame_ping.c
index 9556c0cae80aaabcce7291349643dc42277e24c9..26004b3b7c6260b884b4987fec2fd2b9558e85dc 100644
--- a/src/core/transport/chttp2/frame_ping.c
+++ b/src/core/transport/chttp2/frame_ping.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h
index fa778c51b2f282b1ffe702fcd375ec047164808f..d9d6f7ef15eebefd97bd49dd94aff9e4dd71534b 100644
--- a/src/core/transport/chttp2/frame_ping.h
+++ b/src/core/transport/chttp2/frame_ping.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_rst_stream.c b/src/core/transport/chttp2/frame_rst_stream.c
index 825e156e46e47932c9922043f878df6c1a227555..368ca864816a368204273150d4d22917b378c04e 100644
--- a/src/core/transport/chttp2/frame_rst_stream.c
+++ b/src/core/transport/chttp2/frame_rst_stream.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h
index dbb262971b3e93fc41767840990b3c57734640b3..83fc3806eb21b5eaf913949b3d93b2ad2a129614 100644
--- a/src/core/transport/chttp2/frame_rst_stream.h
+++ b/src/core/transport/chttp2/frame_rst_stream.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c
index 63c21a9b92a5c5de16e1a9770bf8e9a9164bedfc..06429e220b7f02ea06d19ca7aa02c9ebe8432b9a 100644
--- a/src/core/transport/chttp2/frame_settings.c
+++ b/src/core/transport/chttp2/frame_settings.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h
index fc513913d90b2aa3b58758a29a05c3a3ee86c87e..6cde2c6e47e7e72a3e24ff459affa58bd2dc3eb3 100644
--- a/src/core/transport/chttp2/frame_settings.h
+++ b/src/core/transport/chttp2/frame_settings.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_window_update.c b/src/core/transport/chttp2/frame_window_update.c
index 04bc690108b6fffe03b8531dba8249e5175dfa08..a8db7d66531f93f18d53b8f381ba5b785d6174c7 100644
--- a/src/core/transport/chttp2/frame_window_update.c
+++ b/src/core/transport/chttp2/frame_window_update.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h
index 2d9e6c4dcb7433f65046db9a84d9997fb25b4b84..093263db170f6a99b067efe0626c95821e1de640 100644
--- a/src/core/transport/chttp2/frame_window_update.h
+++ b/src/core/transport/chttp2/frame_window_update.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/gen_hpack_tables.c b/src/core/transport/chttp2/gen_hpack_tables.c
index fefaf159a5c56387a61785b340a81785a4b59608..86b593129b052b873b46c1f2fea36dd558294f66 100644
--- a/src/core/transport/chttp2/gen_hpack_tables.c
+++ b/src/core/transport/chttp2/gen_hpack_tables.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index 1eba4a243156bd20351d45191309a558f8d34638..3fd8f672265a815b50191863818f6947e1790c6d 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
index b0a0d76713c9e7c2d1b3d64e24ac64295fd3d10a..94acc8864f7eb77e47edda2126c0181f4bddf9a5 100644
--- a/src/core/transport/chttp2/hpack_parser.h
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/hpack_table.c b/src/core/transport/chttp2/hpack_table.c
index f5c10f934bf7d4db6328f36fd594f5b8297d1fc5..2c0159260f5a79851b6188e9d229ef6a647f4ee0 100644
--- a/src/core/transport/chttp2/hpack_table.c
+++ b/src/core/transport/chttp2/hpack_table.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h
index 84a8e2d1e08765d0bfbdba15f95ad793bfbccafc..ea0fc1d0302281e608fd8c1f31f9a82f78112478 100644
--- a/src/core/transport/chttp2/hpack_table.h
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/http2_errors.h b/src/core/transport/chttp2/http2_errors.h
index 7791da6d5ad5fb663036f70061b38219f272a814..1eecd1754016a63c3e9623cfaedf3320ca6a71e1 100644
--- a/src/core/transport/chttp2/http2_errors.h
+++ b/src/core/transport/chttp2/http2_errors.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/huffsyms.c b/src/core/transport/chttp2/huffsyms.c
index 1014a29b9f91a5535359f88732963b2f780770e0..0a926e7e351632f134bab3dae2cffbf0316d1c25 100644
--- a/src/core/transport/chttp2/huffsyms.c
+++ b/src/core/transport/chttp2/huffsyms.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/huffsyms.h b/src/core/transport/chttp2/huffsyms.h
index 02d0e53fdd516445382d819208c6d1ec0eec7c11..131c4acbebb104e5d206041d413c8fe5c182a864 100644
--- a/src/core/transport/chttp2/huffsyms.h
+++ b/src/core/transport/chttp2/huffsyms.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/status_conversion.c b/src/core/transport/chttp2/status_conversion.c
index 7bd85e8b29da28bba4e2d270f02e49b1a09d56c0..bf214b017a21bcf3e5194271a697676f7bc09a26 100644
--- a/src/core/transport/chttp2/status_conversion.c
+++ b/src/core/transport/chttp2/status_conversion.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/status_conversion.h b/src/core/transport/chttp2/status_conversion.h
index f78d81e0aab422daa7b00bd9a2c235ddbf42a805..8e2672008cf8ab4da60361d10cfa3fdf5b601ac4 100644
--- a/src/core/transport/chttp2/status_conversion.h
+++ b/src/core/transport/chttp2/status_conversion.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 2af18c30358dce17f9cff047b009c8729cd9dbfd..79cce553fa72249641c232f33c8ba986e2a8d582 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/stream_encoder.h b/src/core/transport/chttp2/stream_encoder.h
index 147b1d31ffe55ff3f94f8e033910530dc99ff196..a99d61a553fd24e141464b236fc5325b0206eef6 100644
--- a/src/core/transport/chttp2/stream_encoder.h
+++ b/src/core/transport/chttp2/stream_encoder.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/stream_map.c b/src/core/transport/chttp2/stream_map.c
index 9ac3a4750d0dd7c70f80f11e8997cdad83dba06d..580e32c582e6af683ba5e2f9db7c80310339d340 100644
--- a/src/core/transport/chttp2/stream_map.c
+++ b/src/core/transport/chttp2/stream_map.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/stream_map.h b/src/core/transport/chttp2/stream_map.h
index 03bf719f376f7e99420cce338373ebe56703de01..3fb91fc88f7021018d07aaea77ca5036486bfc04 100644
--- a/src/core/transport/chttp2/stream_map.h
+++ b/src/core/transport/chttp2/stream_map.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c
index 31018c3d27b0da10f03b612b7190d7773cba868f..33915c4039f3bc51fd8defafb3c318e9ab87da8a 100644
--- a/src/core/transport/chttp2/timeout_encoding.c
+++ b/src/core/transport/chttp2/timeout_encoding.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/timeout_encoding.h b/src/core/transport/chttp2/timeout_encoding.h
index d1e47760324cf519479eebc8e1993d3a94fec1ed..2bef8ba67f5a23fdb3a504c5856cf7c768e93acd 100644
--- a/src/core/transport/chttp2/timeout_encoding.h
+++ b/src/core/transport/chttp2/timeout_encoding.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/varint.c b/src/core/transport/chttp2/varint.c
index 5d551be642204f08b5aec43b0f0b4eb4a9f78787..0722c9ada9baa5579ce1bb3600016a5eb0f0a2d8 100644
--- a/src/core/transport/chttp2/varint.c
+++ b/src/core/transport/chttp2/varint.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2/varint.h b/src/core/transport/chttp2/varint.h
index d75869866a5a2e8e6e3e66d5c7fe97dc1e533e92..8c353c66a725ea03729dd4d2a98162632e8b49e4 100644
--- a/src/core/transport/chttp2/varint.h
+++ b/src/core/transport/chttp2/varint.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 5921c3806ec32e022d9caed7edd94b0d94cdf5a7..982417ec8a41710c457e3a194d9b32f7ed9052f7 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -336,11 +336,9 @@ static void recv_data(void *tp, gpr_slice *slices, size_t nslices,
  * CONSTRUCTION/DESTRUCTION/REFCOUNTING
  */
 
-static void unref_transport(transport *t) {
+static void destruct_transport(transport *t) {
   size_t i;
 
-  if (!gpr_unref(&t->refs)) return;
-
   gpr_mu_lock(&t->mu);
 
   GPR_ASSERT(t->ep == NULL);
@@ -380,9 +378,16 @@ static void unref_transport(transport *t) {
 
   grpc_sopb_destroy(&t->nuke_later_sopb);
 
+  grpc_mdctx_unref(t->metadata_context);
+
   gpr_free(t);
 }
 
+static void unref_transport(transport *t) {
+  if (!gpr_unref(&t->refs)) return;
+  destruct_transport(t);
+}
+
 static void ref_transport(transport *t) { gpr_ref(&t->refs); }
 
 static void init_transport(transport *t, grpc_transport_setup_callback setup,
@@ -401,6 +406,7 @@ static void init_transport(transport *t, grpc_transport_setup_callback setup,
   gpr_ref_init(&t->refs, 2);
   gpr_mu_init(&t->mu);
   gpr_cv_init(&t->cv);
+  grpc_mdctx_ref(mdctx);
   t->metadata_context = mdctx;
   t->str_grpc_timeout =
       grpc_mdstr_from_string(t->metadata_context, "grpc-timeout");
@@ -483,9 +489,6 @@ static void init_transport(transport *t, grpc_transport_setup_callback setup,
   ref_transport(t);
   gpr_mu_unlock(&t->mu);
 
-  ref_transport(t);
-  recv_data(t, slices, nslices, GRPC_ENDPOINT_CB_OK);
-
   sr = setup(arg, &t->base, t->metadata_context);
 
   lock(t);
@@ -494,6 +497,10 @@ static void init_transport(transport *t, grpc_transport_setup_callback setup,
   t->calling_back = 0;
   if (t->destroying) gpr_cv_signal(&t->cv);
   unlock(t);
+
+  ref_transport(t);
+  recv_data(t, slices, nslices, GRPC_ENDPOINT_CB_OK);
+
   unref_transport(t);
 }
 
@@ -695,7 +702,7 @@ static void unlock(transport *t) {
   pending_goaway *goaways = NULL;
   grpc_endpoint *ep = t->ep;
   grpc_stream_op_buffer nuke_now;
-  
+
   grpc_sopb_init(&nuke_now);
   if (t->nuke_later_sopb.nops) {
     grpc_sopb_swap(&nuke_now, &t->nuke_later_sopb);
@@ -1624,7 +1631,7 @@ static int process_read(transport *t, gpr_slice slice) {
     /* fallthrough */
     case DTS_FRAME:
       GPR_ASSERT(cur < end);
-      if (end - cur == t->incoming_frame_size) {
+      if ((gpr_uint32)(end - cur) == t->incoming_frame_size) {
         if (!parse_frame_slice(
                 t, gpr_slice_sub_no_ref(slice, cur - beg, end - beg), 1)) {
           return 0;
diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h
index e12357ff5ef388783144d40c51d4552e03a50fc2..6fbc5961a1d2505ba0a1bb8887d85cc9c4602b3b 100644
--- a/src/core/transport/chttp2_transport.h
+++ b/src/core/transport/chttp2_transport.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 74bbb02134d0adad48c10c2f09bfd423c05f5940..1c15716fadf8a6582ae901537fa701c220f8eed5 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -79,7 +79,7 @@ typedef struct internal_metadata {
 
 struct grpc_mdctx {
   gpr_uint32 hash_seed;
-  int orphaned;
+  int refs;
 
   gpr_mu mu;
 
@@ -114,7 +114,7 @@ static void unlock(grpc_mdctx *ctx) {
      mdelems on every unlock (instead of the usual 'I'm too loaded' trigger
      case), since otherwise we can be stuck waiting for a garbage collection
      that will never happen. */
-  if (ctx->orphaned) {
+  if (ctx->refs == 0) {
     /* uncomment if you're having trouble diagnosing an mdelem leak to make
        things clearer (slows down destruction a lot, however) */
     /* gc_mdtab(ctx); */
@@ -139,7 +139,7 @@ static void ref_md(internal_metadata *md) {
 grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed) {
   grpc_mdctx *ctx = gpr_malloc(sizeof(grpc_mdctx));
 
-  ctx->orphaned = 0;
+  ctx->refs = 1;
   ctx->hash_seed = seed;
   gpr_mu_init(&ctx->mu);
   ctx->strtab = gpr_malloc(sizeof(internal_string *) * INITIAL_STRTAB_CAPACITY);
@@ -197,10 +197,17 @@ static void metadata_context_destroy(grpc_mdctx *ctx) {
   gpr_free(ctx);
 }
 
-void grpc_mdctx_orphan(grpc_mdctx *ctx) {
+void grpc_mdctx_ref(grpc_mdctx *ctx) {
   lock(ctx);
-  GPR_ASSERT(!ctx->orphaned);
-  ctx->orphaned = 1;
+  GPR_ASSERT(ctx->refs > 0);
+  ctx->refs++;
+  unlock(ctx);
+}
+
+void grpc_mdctx_unref(grpc_mdctx *ctx) {
+  lock(ctx);
+  GPR_ASSERT(ctx->refs > 0);
+  ctx->refs--;
   unlock(ctx);
 }
 
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index ac845def379c3b2d6df7df9157930c80ee15c153..7a56e34690135a82005404ccc235c0a42c86413e 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -84,7 +84,8 @@ struct grpc_mdelem {
 /* Create/orphan a metadata context */
 grpc_mdctx *grpc_mdctx_create(void);
 grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed);
-void grpc_mdctx_orphan(grpc_mdctx *mdctx);
+void grpc_mdctx_ref(grpc_mdctx *mdctx);
+void grpc_mdctx_unref(grpc_mdctx *mdctx);
 
 /* Test only accessors to internal state - only for testing this code - do not
    rely on it outside of metadata_test.c */
diff --git a/src/core/transport/stream_op.c b/src/core/transport/stream_op.c
index 03a338bd9becdfae1eee23922bbbc1821a0bd504..c30e3a27f1d5ff435602ff766d5d14a3fd2d2319 100644
--- a/src/core/transport/stream_op.c
+++ b/src/core/transport/stream_op.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/stream_op.h b/src/core/transport/stream_op.h
index d4d7515c4f2dfd17fe7542655c3bd34113125c8e..828a7f7226f36c921fbbf41a70e94c56d2779509 100644
--- a/src/core/transport/stream_op.h
+++ b/src/core/transport/stream_op.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c
index 0ca67acb92db0b6e29987505027b5136293ae9a5..ef0020dc58b665b5a34c2259c34e5d4bd62b1af7 100644
--- a/src/core/transport/transport.c
+++ b/src/core/transport/transport.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
index af12f4e700dfd0acfcf0e29e612b42b5ff089fa2..60193b1844cfcea8af5f75480c266b5323a10a74 100644
--- a/src/core/transport/transport.h
+++ b/src/core/transport/transport.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h
index 31e80d36edd9fc9b7fdd0eeb23381b749edcc951..d1e0b1920ea33671747e02f21f440ed547871cf8 100644
--- a/src/core/transport/transport_impl.h
+++ b/src/core/transport/transport_impl.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index a96c7df4a3475e9ef145cf7d37de184b1e7317c4..e8af200284ae2cb1daaea6be09cab3c0e9c2cdf6 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
index 9e3480adfaa9c8c729615995a04f949091d2bec6..36e62bce3dad899b5643a4fd22909fca5402fc11 100644
--- a/src/core/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index e23421fc15782dafc130f525fab7ab26e17e4427..92fcb96dd23cbfc4e957502e93e5bbb6c5789e0f 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1084,7 +1084,7 @@ static int server_handshaker_factory_alpn_callback(
   tsi_ssl_server_handshaker_factory* factory =
       (tsi_ssl_server_handshaker_factory*)arg;
   const unsigned char* client_current = in;
-  while ((client_current - in) < inlen) {
+  while ((unsigned int)(client_current - in) < inlen) {
     unsigned char client_current_len = *(client_current++);
     const unsigned char* server_current = factory->alpn_protocol_list;
     while ((server_current >= factory->alpn_protocol_list) &&
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index 3a33deacac55871ce9f46001095df5c20a99e357..3c1c4c01a2add9788266520ed415e463eb8d7395 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
index fcf03eeb952caa4f5f4f69253d4e1eea649f633a..aeb9b3fc17d3779446a44724212cccf306ed5604 100644
--- a/src/core/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index 3a6ed5290b35dcd183c62484a3dc80860746387e..432da0734631b8d1798e2ce01320c7f56ea8f9ef 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index d180e90799a997b084e168d397c883d8260717ec..90e119ca8e4b224b88b8e6ded56926dfc6c61529 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/README.md b/src/cpp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a2eb9a08c81ec5930e79b15d9ce7812d50153928
--- /dev/null
+++ b/src/cpp/README.md
@@ -0,0 +1,9 @@
+
+#Overview
+
+This directory contains source code for C++ implementation of gRPC.
+
+#Status
+
+Alpha : Ready for early adopters
+
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc
index 3f39364bda208b6c173dc50e96ad2fe9c837efb9..ca69d66cbbfcf541e7e0bdfde03b77052c74d929 100644
--- a/src/cpp/client/channel.cc
+++ b/src/cpp/client/channel.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,11 +42,12 @@
 #include <grpc/support/slice.h>
 
 #include "src/cpp/proto/proto_utils.h"
-#include "src/cpp/stream/stream_context.h"
 #include <grpc++/channel_arguments.h>
 #include <grpc++/client_context.h>
+#include <grpc++/completion_queue.h>
 #include <grpc++/config.h>
 #include <grpc++/credentials.h>
+#include <grpc++/impl/call.h>
 #include <grpc++/impl/rpc_method.h>
 #include <grpc++/status.h>
 #include <google/protobuf/message.h>
@@ -77,103 +78,25 @@ Channel::Channel(const grpc::string &target,
 
 Channel::~Channel() { grpc_channel_destroy(c_channel_); }
 
-namespace {
-// Pluck the finished event and set to status when it is not nullptr.
-void GetFinalStatus(grpc_completion_queue *cq, void *finished_tag,
-                    Status *status) {
-  grpc_event *ev =
-      grpc_completion_queue_pluck(cq, finished_tag, gpr_inf_future);
-  if (status) {
-    StatusCode error_code = static_cast<StatusCode>(ev->data.finished.status);
-    grpc::string details(ev->data.finished.details ? ev->data.finished.details
-                                                   : "");
-    *status = Status(error_code, details);
-  }
-  grpc_event_finish(ev);
+Call Channel::CreateCall(const RpcMethod &method, ClientContext *context,
+                         CompletionQueue *cq) {
+  auto c_call =
+      grpc_channel_create_call(
+          c_channel_, cq->cq(), method.name(),
+          context->authority().empty() ? target_.c_str()
+                                       : context->authority().c_str(),
+          context->RawDeadline());
+  context->set_call(c_call);
+  return Call(c_call, this, cq);
 }
-}  // namespace
 
-// TODO(yangg) more error handling
-Status Channel::StartBlockingRpc(const RpcMethod &method,
-                                 ClientContext *context,
-                                 const google::protobuf::Message &request,
-                                 google::protobuf::Message *result) {
-  Status status;
-  grpc_call *call = grpc_channel_create_call_old(
-      c_channel_, method.name(), target_.c_str(), context->RawDeadline());
-  context->set_call(call);
-
-  grpc_event *ev;
-  void *finished_tag = reinterpret_cast<char *>(call);
-  void *metadata_read_tag = reinterpret_cast<char *>(call) + 2;
-  void *write_tag = reinterpret_cast<char *>(call) + 3;
-  void *halfclose_tag = reinterpret_cast<char *>(call) + 4;
-  void *read_tag = reinterpret_cast<char *>(call) + 5;
-
-  grpc_completion_queue *cq = grpc_completion_queue_create();
-  context->set_cq(cq);
-  // add_metadata from context
-  //
-  // invoke
-  GPR_ASSERT(grpc_call_invoke_old(call, cq, metadata_read_tag, finished_tag,
-                                  GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK);
-  // write request
-  grpc_byte_buffer *write_buffer = nullptr;
-  bool success = SerializeProto(request, &write_buffer);
-  if (!success) {
-    grpc_call_cancel(call);
-    status =
-        Status(StatusCode::DATA_LOSS, "Failed to serialize request proto.");
-    GetFinalStatus(cq, finished_tag, nullptr);
-    return status;
-  }
-  GPR_ASSERT(grpc_call_start_write_old(call, write_buffer, write_tag,
-                                       GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK);
-  grpc_byte_buffer_destroy(write_buffer);
-  ev = grpc_completion_queue_pluck(cq, write_tag, gpr_inf_future);
-
-  success = ev->data.write_accepted == GRPC_OP_OK;
-  grpc_event_finish(ev);
-  if (!success) {
-    GetFinalStatus(cq, finished_tag, &status);
-    return status;
-  }
-  // writes done
-  GPR_ASSERT(grpc_call_writes_done_old(call, halfclose_tag) == GRPC_CALL_OK);
-  ev = grpc_completion_queue_pluck(cq, halfclose_tag, gpr_inf_future);
-  grpc_event_finish(ev);
-  // start read metadata
-  //
-  ev = grpc_completion_queue_pluck(cq, metadata_read_tag, gpr_inf_future);
-  grpc_event_finish(ev);
-  // start read
-  GPR_ASSERT(grpc_call_start_read_old(call, read_tag) == GRPC_CALL_OK);
-  ev = grpc_completion_queue_pluck(cq, read_tag, gpr_inf_future);
-  if (ev->data.read) {
-    if (!DeserializeProto(ev->data.read, result)) {
-      grpc_event_finish(ev);
-      status = Status(StatusCode::DATA_LOSS, "Failed to parse response proto.");
-      GetFinalStatus(cq, finished_tag, nullptr);
-      return status;
-    }
-  }
-  grpc_event_finish(ev);
-
-  // wait status
-  GetFinalStatus(cq, finished_tag, &status);
-  return status;
-}
-
-StreamContextInterface *Channel::CreateStream(
-    const RpcMethod &method, ClientContext *context,
-    const google::protobuf::Message *request,
-    google::protobuf::Message *result) {
-  grpc_call *call = grpc_channel_create_call_old(
-      c_channel_, method.name(), target_.c_str(), context->RawDeadline());
-  context->set_call(call);
-  grpc_completion_queue *cq = grpc_completion_queue_create();
-  context->set_cq(cq);
-  return new StreamContext(method, context, request, result);
+void Channel::PerformOpsOnCall(CallOpBuffer *buf, Call *call) {
+  static const size_t MAX_OPS = 8;
+  size_t nops = MAX_OPS;
+  grpc_op ops[MAX_OPS];
+  buf->FillOps(ops, &nops);
+  GPR_ASSERT(GRPC_CALL_OK ==
+             grpc_call_start_batch(call->call(), ops, nops, buf));
 }
 
 }  // namespace grpc
diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h
index 67d18bf4c890fbac886d2ae58b25963e53f8cd6f..06f5a8ffdfe7052767aa508c9685fad7b9eb1691 100644
--- a/src/cpp/client/channel.h
+++ b/src/cpp/client/channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,11 +42,14 @@
 struct grpc_channel;
 
 namespace grpc {
+class Call;
+class CallOpBuffer;
 class ChannelArguments;
+class CompletionQueue;
 class Credentials;
 class StreamContextInterface;
 
-class Channel : public ChannelInterface {
+class Channel final : public ChannelInterface {
  public:
   Channel(const grpc::string &target, const ChannelArguments &args);
   Channel(const grpc::string &target, const std::unique_ptr<Credentials> &creds,
@@ -54,14 +57,9 @@ class Channel : public ChannelInterface {
 
   ~Channel() override;
 
-  Status StartBlockingRpc(const RpcMethod &method, ClientContext *context,
-                          const google::protobuf::Message &request,
-                          google::protobuf::Message *result) override;
-
-  StreamContextInterface *CreateStream(
-      const RpcMethod &method, ClientContext *context,
-      const google::protobuf::Message *request,
-      google::protobuf::Message *result) override;
+  virtual Call CreateCall(const RpcMethod &method, ClientContext *context,
+                          CompletionQueue *cq) override;
+  virtual void PerformOpsOnCall(CallOpBuffer *ops, Call *call) override;
 
  private:
   const grpc::string target_;
diff --git a/src/cpp/client/channel_arguments.cc b/src/cpp/client/channel_arguments.cc
index 70713f015f1a75e43e8de6478f08b0e712a5f0d1..abf0fc1c0ad7a44dfb59d619d66c1cdfbadfbd7d 100644
--- a/src/cpp/client/channel_arguments.cc
+++ b/src/cpp/client/channel_arguments.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 7bda2d07c317a03595d20eb309667a6d48fb21c4..80cbdd93accc6498b16fd9007d79a7b5047b13e0 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,9 +72,13 @@ system_clock::time_point ClientContext::absolute_deadline() {
 
 void ClientContext::AddMetadata(const grpc::string &meta_key,
                                 const grpc::string &meta_value) {
-  return;
+  send_initial_metadata_.insert(std::make_pair(meta_key, meta_value));
 }
 
-void ClientContext::StartCancel() {}
+void ClientContext::TryCancel() {
+  if (call_) {
+    grpc_call_cancel(call_);
+  }
+}
 
 }  // namespace grpc
diff --git a/test/cpp/end2end/async_test_server.h b/src/cpp/client/client_unary_call.cc
similarity index 62%
rename from test/cpp/end2end/async_test_server.h
rename to src/cpp/client/client_unary_call.cc
index a277061acecb20a8603fd679c0e3cb7757b46e45..684b3cbadb49a6c33fa029fd296e1dac2b91b3cf 100644
--- a/test/cpp/end2end/async_test_server.h
+++ b/src/cpp/client/client_unary_call.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,45 +31,34 @@
  *
  */
 
-#ifndef __GRPCPP_TEST_END2END_ASYNC_TEST_SERVER_H__
-#define __GRPCPP_TEST_END2END_ASYNC_TEST_SERVER_H__
-
-#include <condition_variable>
-#include <mutex>
-#include <string>
-
-#include <grpc++/async_server.h>
+#include <grpc++/impl/client_unary_call.h>
+#include <grpc++/impl/call.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
 #include <grpc++/completion_queue.h>
+#include <grpc++/status.h>
+#include <grpc/support/log.h>
 
 namespace grpc {
 
-namespace testing {
-
-class AsyncTestServer {
- public:
-  AsyncTestServer();
-  virtual ~AsyncTestServer();
-
-  void AddPort(const grpc::string& addr);
-  void Start();
-  void RequestOneRpc();
-  virtual void MainLoop();
-  void Shutdown();
+// Wrapper that performs a blocking unary call
+Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method,
+                         ClientContext *context,
+                         const google::protobuf::Message &request,
+                         google::protobuf::Message *result) {
+  CompletionQueue cq;
+  Call call(channel->CreateCall(method, context, &cq));
+  CallOpBuffer buf;
+  Status status;
+  buf.AddSendInitialMetadata(context);
+  buf.AddSendMessage(request);
+  buf.AddRecvInitialMetadata(context);
+  buf.AddRecvMessage(result);
+  buf.AddClientSendClose();
+  buf.AddClientRecvStatus(context, &status);
+  call.PerformOps(&buf);
+  GPR_ASSERT((cq.Pluck(&buf) && buf.got_message) || !status.IsOk());
+  return status;
+}
 
-  CompletionQueue* completion_queue() { return &cq_; }
-
- protected:
-  void HandleQueueClosed();
-
- private:
-  CompletionQueue cq_;
-  AsyncServer server_;
-  bool cq_drained_;
-  std::mutex cq_drained_mu_;
-  std::condition_variable cq_drained_cv_;
-};
-
-}  // namespace testing
 }  // namespace grpc
-
-#endif  // __GRPCPP_TEST_END2END_ASYNC_TEST_SERVER_H__
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index 9cc5cff21485285c7766be5ed3a082a5ba3e5f24..acf51cb90b194c1acff6585a73463e8618b6be63 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc
index 8e3a9884770cbf8cface579e13d57e5c2be1157c..66571cad73dc0cc70b9e7e9fb46234fcf9efd231 100644
--- a/src/cpp/client/credentials.cc
+++ b/src/cpp/client/credentials.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/client/internal_stub.cc b/src/cpp/client/internal_stub.cc
index 51cb99d1b49c016254767f8bcae858d3ea0195c3..91724a4837a2a3f9d4471bf5146026a4a5777132 100644
--- a/src/cpp/client/internal_stub.cc
+++ b/src/cpp/client/internal_stub.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e6a20a252dbb588388c5444b8ebf9c77ae932901
--- /dev/null
+++ b/src/cpp/common/call.cc
@@ -0,0 +1,287 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <google/protobuf/message.h>
+#include <grpc/support/alloc.h>
+#include <grpc++/impl/call.h>
+#include <grpc++/client_context.h>
+#include <grpc++/channel_interface.h>
+
+#include "src/cpp/proto/proto_utils.h"
+
+namespace grpc {
+
+void CallOpBuffer::Reset(void* next_return_tag) {
+  return_tag_ = next_return_tag;
+
+  send_initial_metadata_ = false;
+  initial_metadata_count_ = 0;
+  gpr_free(initial_metadata_);
+
+  recv_initial_metadata_ = nullptr;
+  recv_initial_metadata_arr_.count = 0;
+
+  send_message_ = nullptr;
+  if (send_message_buf_) {
+    grpc_byte_buffer_destroy(send_message_buf_);
+    send_message_buf_ = nullptr;
+  }
+
+  recv_message_ = nullptr;
+  got_message = false;
+  if (recv_message_buf_) {
+    grpc_byte_buffer_destroy(recv_message_buf_);
+    recv_message_buf_ = nullptr;
+  }
+
+  client_send_close_ = false;
+
+  recv_trailing_metadata_ = nullptr;
+  recv_status_ = nullptr;
+  recv_trailing_metadata_arr_.count = 0;
+
+  status_code_ = GRPC_STATUS_OK;
+
+  send_status_ = nullptr;
+  trailing_metadata_count_ = 0;
+  trailing_metadata_ = nullptr;
+
+  recv_closed_ = nullptr;
+}
+
+CallOpBuffer::~CallOpBuffer() {
+  gpr_free(status_details_);
+  gpr_free(recv_initial_metadata_arr_.metadata);
+  gpr_free(recv_trailing_metadata_arr_.metadata);
+  if (recv_message_buf_) {
+    grpc_byte_buffer_destroy(recv_message_buf_);
+  }
+  if (send_message_buf_) {
+    grpc_byte_buffer_destroy(send_message_buf_);
+  }
+}
+
+namespace {
+// TODO(yangg) if the map is changed before we send, the pointers will be a
+// mess. Make sure it does not happen.
+grpc_metadata* FillMetadataArray(
+    std::multimap<grpc::string, grpc::string>* metadata) {
+  if (metadata->empty()) {
+    return nullptr;
+  }
+  grpc_metadata* metadata_array =
+      (grpc_metadata*)gpr_malloc(metadata->size() * sizeof(grpc_metadata));
+  size_t i = 0;
+  for (auto iter = metadata->cbegin(); iter != metadata->cend(); ++iter, ++i) {
+    metadata_array[i].key = iter->first.c_str();
+    metadata_array[i].value = iter->second.c_str();
+    metadata_array[i].value_length = iter->second.size();
+  }
+  return metadata_array;
+}
+
+void FillMetadataMap(grpc_metadata_array* arr,
+                     std::multimap<grpc::string, grpc::string>* metadata) {
+  for (size_t i = 0; i < arr->count; i++) {
+    // TODO(yangg) handle duplicates?
+    metadata->insert(std::pair<grpc::string, grpc::string>(
+        arr->metadata[i].key,
+        {arr->metadata[i].value, arr->metadata[i].value_length}));
+  }
+  grpc_metadata_array_destroy(arr);
+  grpc_metadata_array_init(arr);
+}
+}  // namespace
+
+void CallOpBuffer::AddSendInitialMetadata(
+    std::multimap<grpc::string, grpc::string>* metadata) {
+  send_initial_metadata_ = true;
+  initial_metadata_count_ = metadata->size();
+  initial_metadata_ = FillMetadataArray(metadata);
+}
+
+void CallOpBuffer::AddRecvInitialMetadata(ClientContext* ctx) {
+  ctx->initial_metadata_received_ = true;
+  recv_initial_metadata_ = &ctx->recv_initial_metadata_;
+}
+
+void CallOpBuffer::AddSendInitialMetadata(ClientContext* ctx) {
+  AddSendInitialMetadata(&ctx->send_initial_metadata_);
+}
+
+void CallOpBuffer::AddSendMessage(const google::protobuf::Message& message) {
+  send_message_ = &message;
+}
+
+void CallOpBuffer::AddRecvMessage(google::protobuf::Message* message) {
+  recv_message_ = message;
+  recv_message_->Clear();
+}
+
+void CallOpBuffer::AddClientSendClose() { client_send_close_ = true; }
+
+void CallOpBuffer::AddServerRecvClose(bool* cancelled) {
+  recv_closed_ = cancelled;
+}
+
+void CallOpBuffer::AddClientRecvStatus(ClientContext* context, Status* status) {
+  recv_trailing_metadata_ = &context->trailing_metadata_;
+  recv_status_ = status;
+}
+
+void CallOpBuffer::AddServerSendStatus(
+    std::multimap<grpc::string, grpc::string>* metadata, const Status& status) {
+  if (metadata != NULL) {
+    trailing_metadata_count_ = metadata->size();
+    trailing_metadata_ = FillMetadataArray(metadata);
+  } else {
+    trailing_metadata_count_ = 0;
+  }
+  send_status_ = &status;
+}
+
+void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) {
+  *nops = 0;
+  if (send_initial_metadata_) {
+    ops[*nops].op = GRPC_OP_SEND_INITIAL_METADATA;
+    ops[*nops].data.send_initial_metadata.count = initial_metadata_count_;
+    ops[*nops].data.send_initial_metadata.metadata = initial_metadata_;
+    (*nops)++;
+  }
+  if (recv_initial_metadata_) {
+    ops[*nops].op = GRPC_OP_RECV_INITIAL_METADATA;
+    ops[*nops].data.recv_initial_metadata = &recv_initial_metadata_arr_;
+    (*nops)++;
+  }
+  if (send_message_) {
+    bool success = SerializeProto(*send_message_, &send_message_buf_);
+    if (!success) {
+      abort();
+      // TODO handle parse failure
+    }
+    ops[*nops].op = GRPC_OP_SEND_MESSAGE;
+    ops[*nops].data.send_message = send_message_buf_;
+    (*nops)++;
+  }
+  if (recv_message_) {
+    ops[*nops].op = GRPC_OP_RECV_MESSAGE;
+    ops[*nops].data.recv_message = &recv_message_buf_;
+    (*nops)++;
+  }
+  if (client_send_close_) {
+    ops[*nops].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+    (*nops)++;
+  }
+  if (recv_status_) {
+    ops[*nops].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+    ops[*nops].data.recv_status_on_client.trailing_metadata =
+        &recv_trailing_metadata_arr_;
+    ops[*nops].data.recv_status_on_client.status = &status_code_;
+    ops[*nops].data.recv_status_on_client.status_details = &status_details_;
+    ops[*nops].data.recv_status_on_client.status_details_capacity =
+        &status_details_capacity_;
+    (*nops)++;
+  }
+  if (send_status_) {
+    ops[*nops].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+    ops[*nops].data.send_status_from_server.trailing_metadata_count =
+        trailing_metadata_count_;
+    ops[*nops].data.send_status_from_server.trailing_metadata =
+        trailing_metadata_;
+    ops[*nops].data.send_status_from_server.status =
+        static_cast<grpc_status_code>(send_status_->code());
+    ops[*nops].data.send_status_from_server.status_details =
+        send_status_->details().c_str();
+    (*nops)++;
+  }
+  if (recv_closed_) {
+    ops[*nops].op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+    ops[*nops].data.recv_close_on_server.cancelled = &cancelled_buf_;
+    (*nops)++;
+  }
+}
+
+bool CallOpBuffer::FinalizeResult(void** tag, bool* status) {
+  // Release send buffers.
+  if (send_message_buf_) {
+    grpc_byte_buffer_destroy(send_message_buf_);
+    send_message_buf_ = nullptr;
+  }
+  if (initial_metadata_) {
+    gpr_free(initial_metadata_);
+    initial_metadata_ = nullptr;
+  }
+  if (trailing_metadata_count_) {
+    gpr_free(trailing_metadata_);
+    trailing_metadata_ = nullptr;
+  }
+  // Set user-facing tag.
+  *tag = return_tag_;
+  // Process received initial metadata
+  if (recv_initial_metadata_) {
+    FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_);
+  }
+  // Parse received message if any.
+  if (recv_message_) {
+    if (recv_message_buf_) {
+      got_message = *status;
+      *status = *status && DeserializeProto(recv_message_buf_, recv_message_);
+      grpc_byte_buffer_destroy(recv_message_buf_);
+      recv_message_buf_ = nullptr;
+    } else {
+      // Read failed
+      got_message = false;
+      *status = false;
+    }
+  }
+  // Parse received status.
+  if (recv_status_) {
+    FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_);
+    *recv_status_ = Status(
+        static_cast<StatusCode>(status_code_),
+        status_details_ ? grpc::string(status_details_) : grpc::string());
+  }
+  if (recv_closed_) {
+    *recv_closed_ = cancelled_buf_ != 0;
+  }
+  return true;
+}
+
+Call::Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
+    : call_hook_(call_hook), cq_(cq), call_(call) {}
+
+void Call::PerformOps(CallOpBuffer* buffer) {
+  call_hook_->PerformOpsOnCall(buffer, this);
+}
+
+}  // namespace grpc
diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue.cc
index f06da9b04feb5a90560f6d21a9bea0dba712428e..414966c1cdfe8710382855ddd80d695d3e75021f 100644
--- a/src/cpp/common/completion_queue.cc
+++ b/src/cpp/common/completion_queue.cc
@@ -1,6 +1,5 @@
 /*
- *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,80 +32,68 @@
 
 #include <grpc++/completion_queue.h>
 
+#include <memory>
+
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include "src/cpp/util/time.h"
-#include <grpc++/async_server_context.h>
 
 namespace grpc {
 
 CompletionQueue::CompletionQueue() { cq_ = grpc_completion_queue_create(); }
 
+CompletionQueue::CompletionQueue(grpc_completion_queue* take) : cq_(take) {}
+
 CompletionQueue::~CompletionQueue() { grpc_completion_queue_destroy(cq_); }
 
 void CompletionQueue::Shutdown() { grpc_completion_queue_shutdown(cq_); }
 
-CompletionQueue::CompletionType CompletionQueue::Next(void **tag) {
-  grpc_event *ev;
-  CompletionType return_type;
-  bool success;
-
-  ev = grpc_completion_queue_next(cq_, gpr_inf_future);
-  if (!ev) {
-    gpr_log(GPR_ERROR, "no next event in queue");
-    abort();
+// Helper class so we can declare a unique_ptr with grpc_event
+class EventDeleter {
+ public:
+  void operator()(grpc_event* ev) {
+    if (ev) grpc_event_finish(ev);
   }
-  switch (ev->type) {
-    case GRPC_QUEUE_SHUTDOWN:
-      return_type = QUEUE_CLOSED;
-      break;
-    case GRPC_READ:
-      *tag = ev->tag;
-      if (ev->data.read) {
-        success = static_cast<AsyncServerContext *>(ev->tag)
-                      ->ParseRead(ev->data.read);
-        return_type = success ? SERVER_READ_OK : SERVER_READ_ERROR;
-      } else {
-        return_type = SERVER_READ_ERROR;
-      }
-      break;
-    case GRPC_WRITE_ACCEPTED:
-      *tag = ev->tag;
-      if (ev->data.write_accepted != GRPC_OP_ERROR) {
-        return_type = SERVER_WRITE_OK;
-      } else {
-        return_type = SERVER_WRITE_ERROR;
-      }
-      break;
-    case GRPC_SERVER_RPC_NEW:
-      GPR_ASSERT(!ev->tag);
-      // Finishing the pending new rpcs after the server has been shutdown.
-      if (!ev->call) {
-        *tag = nullptr;
-      } else {
-        *tag = new AsyncServerContext(
-            ev->call, ev->data.server_rpc_new.method,
-            ev->data.server_rpc_new.host,
-            Timespec2Timepoint(ev->data.server_rpc_new.deadline));
-      }
-      return_type = SERVER_RPC_NEW;
-      break;
-    case GRPC_FINISHED:
-      *tag = ev->tag;
-      return_type = RPC_END;
-      break;
-    case GRPC_FINISH_ACCEPTED:
-      *tag = ev->tag;
-      return_type = HALFCLOSE_OK;
-      break;
-    default:
-      // We do not handle client side messages now
-      gpr_log(GPR_ERROR, "client-side messages aren't supported yet");
-      abort();
+};
+
+bool CompletionQueue::Next(void** tag, bool* ok) {
+  std::unique_ptr<grpc_event, EventDeleter> ev;
+
+  for (;;) {
+    ev.reset(grpc_completion_queue_next(cq_, gpr_inf_future));
+    if (ev->type == GRPC_QUEUE_SHUTDOWN) {
+      return false;
+    }
+    auto cq_tag = static_cast<CompletionQueueTag*>(ev->tag);
+    *ok = ev->data.op_complete == GRPC_OP_OK;
+    *tag = cq_tag;
+    if (cq_tag->FinalizeResult(tag, ok)) {
+      return true;
+    }
   }
-  grpc_event_finish(ev);
-  return return_type;
+}
+
+bool CompletionQueue::Pluck(CompletionQueueTag* tag) {
+  std::unique_ptr<grpc_event, EventDeleter> ev;
+
+  ev.reset(grpc_completion_queue_pluck(cq_, tag, gpr_inf_future));
+  bool ok = ev->data.op_complete == GRPC_OP_OK;
+  void* ignored = tag;
+  GPR_ASSERT(tag->FinalizeResult(&ignored, &ok));
+  GPR_ASSERT(ignored == tag);
+  return ok;
+}
+
+void CompletionQueue::TryPluck(CompletionQueueTag* tag) {
+  std::unique_ptr<grpc_event, EventDeleter> ev;
+
+  ev.reset(grpc_completion_queue_pluck(cq_, tag, gpr_inf_past));
+  if (!ev) return;
+  bool ok = ev->data.op_complete == GRPC_OP_OK;
+  void* ignored = tag;
+  // the tag must be swallowed if using TryPluck
+  GPR_ASSERT(!tag->FinalizeResult(&ignored, &ok));
 }
 
 }  // namespace grpc
diff --git a/src/cpp/common/rpc_method.cc b/src/cpp/common/rpc_method.cc
index c8b2ccb10e26214af7fb41d8241a3eede316e54b..1654d4a262cde57ef180c23742ff8e1f2712faae 100644
--- a/src/cpp/common/rpc_method.cc
+++ b/src/cpp/common/rpc_method.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/proto/proto_utils.cc
index 85f859b9eb54bdc1708729a82b4299afac14c8fc..69a6bb080e0abed0b637ab443118955528bf9dbb 100644
--- a/src/cpp/proto/proto_utils.cc
+++ b/src/cpp/proto/proto_utils.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/proto/proto_utils.h b/src/cpp/proto/proto_utils.h
index a611a227fa7468b1a6c72f016d622b67ce096941..834884d579693788fad6f0352ddffe92a2c7dfc9 100644
--- a/src/cpp/proto/proto_utils.h
+++ b/src/cpp/proto/proto_utils.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/server/async_server_context.cc b/src/cpp/server/async_server_context.cc
index 886e794137f62df66c7ed05ed5ddd4a690c49abd..5f8c2ba10f4cd5511d0a3216c2d920370f48622f 100644
--- a/src/cpp/server/async_server_context.cc
+++ b/src/cpp/server/async_server_context.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,8 @@ AsyncServerContext::~AsyncServerContext() { grpc_call_destroy(call_); }
 
 void AsyncServerContext::Accept(grpc_completion_queue *cq) {
   GPR_ASSERT(grpc_call_server_accept_old(call_, cq, this) == GRPC_CALL_OK);
-  GPR_ASSERT(grpc_call_server_end_initial_metadata_old(call_, GRPC_WRITE_BUFFER_HINT) ==
-             GRPC_CALL_OK);
+  GPR_ASSERT(grpc_call_server_end_initial_metadata_old(
+                 call_, GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK);
 }
 
 bool AsyncServerContext::StartRead(google::protobuf::Message *request) {
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 1abdf702e212ad6045b52e1941c8925078e3ad53..f565d3aa5d5ec16b1e936318585d4d8e842adf1c 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,25 +37,145 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/log.h>
-#include "src/cpp/server/server_rpc_handler.h"
-#include "src/cpp/server/thread_pool.h"
-#include <grpc++/async_server_context.h>
 #include <grpc++/completion_queue.h>
 #include <grpc++/impl/rpc_service_method.h>
+#include <grpc++/impl/service_type.h>
+#include <grpc++/server_context.h>
 #include <grpc++/server_credentials.h>
+#include <grpc++/thread_pool_interface.h>
+
+#include "src/cpp/proto/proto_utils.h"
+#include "src/cpp/util/time.h"
 
 namespace grpc {
 
-// TODO(rocking): consider a better default value like num of cores.
-static const int kNumThreads = 4;
+class Server::SyncRequest final : public CompletionQueueTag {
+ public:
+  SyncRequest(RpcServiceMethod* method, void* tag)
+      : method_(method),
+        tag_(tag),
+        has_request_payload_(method->method_type() == RpcMethod::NORMAL_RPC ||
+                             method->method_type() ==
+                                 RpcMethod::SERVER_STREAMING),
+        has_response_payload_(method->method_type() == RpcMethod::NORMAL_RPC ||
+                              method->method_type() ==
+                                  RpcMethod::CLIENT_STREAMING) {
+    grpc_metadata_array_init(&request_metadata_);
+  }
+
+  static SyncRequest* Wait(CompletionQueue* cq, bool* ok) {
+    void* tag = nullptr;
+    *ok = false;
+    if (!cq->Next(&tag, ok)) {
+      return nullptr;
+    }
+    auto* mrd = static_cast<SyncRequest*>(tag);
+    GPR_ASSERT(mrd->in_flight_);
+    return mrd;
+  }
+
+  void Request(grpc_server* server) {
+    GPR_ASSERT(!in_flight_);
+    in_flight_ = true;
+    cq_ = grpc_completion_queue_create();
+    GPR_ASSERT(GRPC_CALL_OK ==
+               grpc_server_request_registered_call(
+                   server, tag_, &call_, &deadline_, &request_metadata_,
+                   has_request_payload_ ? &request_payload_ : nullptr, cq_,
+                   this));
+  }
 
-Server::Server(ThreadPoolInterface *thread_pool, ServerCredentials *creds)
+  bool FinalizeResult(void** tag, bool* status) override {
+    if (!*status) {
+      grpc_completion_queue_destroy(cq_);
+    }
+    return true;
+  }
+
+  class CallData final {
+   public:
+    explicit CallData(Server* server, SyncRequest* mrd)
+        : cq_(mrd->cq_),
+          call_(mrd->call_, server, &cq_),
+          ctx_(mrd->deadline_, mrd->request_metadata_.metadata,
+               mrd->request_metadata_.count),
+          has_request_payload_(mrd->has_request_payload_),
+          has_response_payload_(mrd->has_response_payload_),
+          request_payload_(mrd->request_payload_),
+          method_(mrd->method_) {
+      ctx_.call_ = mrd->call_;
+      GPR_ASSERT(mrd->in_flight_);
+      mrd->in_flight_ = false;
+      mrd->request_metadata_.count = 0;
+    }
+
+    ~CallData() {
+      if (has_request_payload_ && request_payload_) {
+        grpc_byte_buffer_destroy(request_payload_);
+      }
+    }
+
+    void Run() {
+      std::unique_ptr<google::protobuf::Message> req;
+      std::unique_ptr<google::protobuf::Message> res;
+      if (has_request_payload_) {
+        req.reset(method_->AllocateRequestProto());
+        if (!DeserializeProto(request_payload_, req.get())) {
+          abort();  // for now
+        }
+      }
+      if (has_response_payload_) {
+        res.reset(method_->AllocateResponseProto());
+      }
+      ctx_.BeginCompletionOp(&call_);
+      auto status = method_->handler()->RunHandler(
+          MethodHandler::HandlerParameter(&call_, &ctx_, req.get(), res.get()));
+      CallOpBuffer buf;
+      if (!ctx_.sent_initial_metadata_) {
+        buf.AddSendInitialMetadata(&ctx_.initial_metadata_);
+      }
+      if (has_response_payload_) {
+        buf.AddSendMessage(*res);
+      }
+      buf.AddServerSendStatus(&ctx_.trailing_metadata_, status);
+      call_.PerformOps(&buf);
+      GPR_ASSERT(cq_.Pluck(&buf));
+      void* ignored_tag;
+      bool ignored_ok;
+      cq_.Shutdown();
+      GPR_ASSERT(cq_.Next(&ignored_tag, &ignored_ok) == false);
+    }
+
+   private:
+    CompletionQueue cq_;
+    Call call_;
+    ServerContext ctx_;
+    const bool has_request_payload_;
+    const bool has_response_payload_;
+    grpc_byte_buffer* request_payload_;
+    RpcServiceMethod* const method_;
+  };
+
+ private:
+  RpcServiceMethod* const method_;
+  void* const tag_;
+  bool in_flight_ = false;
+  const bool has_request_payload_;
+  const bool has_response_payload_;
+  grpc_call* call_;
+  gpr_timespec deadline_;
+  grpc_metadata_array request_metadata_;
+  grpc_byte_buffer* request_payload_;
+  grpc_completion_queue* cq_;
+};
+
+Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
+               ServerCredentials* creds)
     : started_(false),
       shutdown_(false),
       num_running_cb_(0),
-      thread_pool_(thread_pool == nullptr ? new ThreadPool(kNumThreads)
-                                          : thread_pool),
-      thread_pool_owned_(thread_pool == nullptr),
+      thread_pool_(thread_pool),
+      thread_pool_owned_(thread_pool_owned),
       secure_(creds != nullptr) {
   if (creds) {
     server_ =
@@ -75,6 +195,8 @@ Server::~Server() {
   if (started_ && !shutdown_) {
     lock.unlock();
     Shutdown();
+  } else {
+    lock.unlock();
   }
   grpc_server_destroy(server_);
   if (thread_pool_owned_) {
@@ -82,37 +204,64 @@ Server::~Server() {
   }
 }
 
-void Server::RegisterService(RpcService *service) {
+bool Server::RegisterService(RpcService* service) {
   for (int i = 0; i < service->GetMethodCount(); ++i) {
-    RpcServiceMethod *method = service->GetMethod(i);
-    method_map_.insert(std::make_pair(method->name(), method));
+    RpcServiceMethod* method = service->GetMethod(i);
+    void* tag =
+        grpc_server_register_method(server_, method->name(), nullptr, cq_.cq());
+    if (!tag) {
+      gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
+              method->name());
+      return false;
+    }
+    sync_methods_.emplace_back(method, tag);
   }
+  return true;
 }
 
-void Server::AddPort(const grpc::string &addr) {
+bool Server::RegisterAsyncService(AsynchronousService* service) {
+  GPR_ASSERT(service->dispatch_impl_ == nullptr &&
+             "Can only register an asynchronous service against one server.");
+  service->dispatch_impl_ = this;
+  service->request_args_ = new void* [service->method_count_];
+  for (size_t i = 0; i < service->method_count_; ++i) {
+    void* tag =
+        grpc_server_register_method(server_, service->method_names_[i], nullptr,
+                                    service->completion_queue()->cq());
+    if (!tag) {
+      gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
+              service->method_names_[i]);
+      return false;
+    }
+    service->request_args_[i] = tag;
+  }
+  return true;
+}
+
+int Server::AddPort(const grpc::string& addr) {
   GPR_ASSERT(!started_);
-  int success;
   if (secure_) {
-    success = grpc_server_add_secure_http2_port(server_, addr.c_str());
+    return grpc_server_add_secure_http2_port(server_, addr.c_str());
   } else {
-    success = grpc_server_add_http2_port(server_, addr.c_str());
+    return grpc_server_add_http2_port(server_, addr.c_str());
   }
-  GPR_ASSERT(success);
 }
 
-void Server::Start() {
+bool Server::Start() {
   GPR_ASSERT(!started_);
   started_ = true;
   grpc_server_start(server_);
 
   // Start processing rpcs.
-  ScheduleCallback();
-}
+  if (!sync_methods_.empty()) {
+    for (auto& m : sync_methods_) {
+      m.Request(server_);
+    }
 
-void Server::AllowOneRpc() {
-  GPR_ASSERT(started_);
-  grpc_call_error err = grpc_server_request_call_old(server_, nullptr);
-  GPR_ASSERT(err == GRPC_CALL_OK);
+    ScheduleCallback();
+  }
+
+  return true;
 }
 
 void Server::Shutdown() {
@@ -121,6 +270,7 @@ void Server::Shutdown() {
     if (started_ && !shutdown_) {
       shutdown_ = true;
       grpc_server_shutdown(server_);
+      cq_.Shutdown();
 
       // Wait for running callbacks to finish.
       while (num_running_cb_ != 0) {
@@ -128,12 +278,88 @@ void Server::Shutdown() {
       }
     }
   }
+}
+
+void Server::PerformOpsOnCall(CallOpBuffer* buf, Call* call) {
+  static const size_t MAX_OPS = 8;
+  size_t nops = MAX_OPS;
+  grpc_op ops[MAX_OPS];
+  buf->FillOps(ops, &nops);
+  GPR_ASSERT(GRPC_CALL_OK ==
+             grpc_call_start_batch(call->call(), ops, nops, buf));
+}
+
+class Server::AsyncRequest final : public CompletionQueueTag {
+ public:
+  AsyncRequest(Server* server, void* registered_method, ServerContext* ctx,
+               ::google::protobuf::Message* request,
+               ServerAsyncStreamingInterface* stream, CompletionQueue* cq,
+               void* tag)
+      : tag_(tag),
+        request_(request),
+        stream_(stream),
+        cq_(cq),
+        ctx_(ctx),
+        server_(server) {
+    memset(&array_, 0, sizeof(array_));
+    grpc_server_request_registered_call(
+        server->server_, registered_method, &call_, &deadline_, &array_,
+        request ? &payload_ : nullptr, cq->cq(), this);
+  }
+
+  ~AsyncRequest() {
+    if (payload_) {
+      grpc_byte_buffer_destroy(payload_);
+    }
+    grpc_metadata_array_destroy(&array_);
+  }
+
+  bool FinalizeResult(void** tag, bool* status) override {
+    *tag = tag_;
+    if (*status && request_) {
+      if (payload_) {
+        *status = DeserializeProto(payload_, request_);
+      } else {
+        *status = false;
+      }
+    }
+    if (*status) {
+      ctx_->deadline_ = Timespec2Timepoint(deadline_);
+      for (size_t i = 0; i < array_.count; i++) {
+        ctx_->client_metadata_.insert(std::make_pair(
+            grpc::string(array_.metadata[i].key),
+            grpc::string(
+                array_.metadata[i].value,
+                array_.metadata[i].value + array_.metadata[i].value_length)));
+      }
+    }
+    ctx_->call_ = call_;
+    Call call(call_, server_, cq_);
+    ctx_->BeginCompletionOp(&call);
+    // just the pointers inside call are copied here
+    stream_->BindCall(&call);
+    delete this;
+    return true;
+  }
+
+ private:
+  void* const tag_;
+  ::google::protobuf::Message* const request_;
+  ServerAsyncStreamingInterface* const stream_;
+  CompletionQueue* const cq_;
+  ServerContext* const ctx_;
+  Server* const server_;
+  grpc_call* call_ = nullptr;
+  gpr_timespec deadline_;
+  grpc_metadata_array array_;
+  grpc_byte_buffer* payload_ = nullptr;
+};
 
-  // Shutdown the completion queue.
-  cq_.Shutdown();
-  void *tag = nullptr;
-  CompletionQueue::CompletionType t = cq_.Next(&tag);
-  GPR_ASSERT(t == CompletionQueue::QUEUE_CLOSED);
+void Server::RequestAsyncCall(void* registered_method, ServerContext* context,
+                              ::google::protobuf::Message* request,
+                              ServerAsyncStreamingInterface* stream,
+                              CompletionQueue* cq, void* tag) {
+  new AsyncRequest(this, registered_method, context, request, stream, cq, tag);
 }
 
 void Server::ScheduleCallback() {
@@ -141,30 +367,21 @@ void Server::ScheduleCallback() {
     std::unique_lock<std::mutex> lock(mu_);
     num_running_cb_++;
   }
-  std::function<void()> callback = std::bind(&Server::RunRpc, this);
-  thread_pool_->ScheduleCallback(callback);
+  thread_pool_->ScheduleCallback(std::bind(&Server::RunRpc, this));
 }
 
 void Server::RunRpc() {
   // Wait for one more incoming rpc.
-  void *tag = nullptr;
-  AllowOneRpc();
-  CompletionQueue::CompletionType t = cq_.Next(&tag);
-  GPR_ASSERT(t == CompletionQueue::SERVER_RPC_NEW);
-
-  AsyncServerContext *server_context = static_cast<AsyncServerContext *>(tag);
-  // server_context could be nullptr during server shutdown.
-  if (server_context != nullptr) {
-    // Schedule a new callback to handle more rpcs.
+  bool ok;
+  auto* mrd = SyncRequest::Wait(&cq_, &ok);
+  if (mrd) {
     ScheduleCallback();
+    if (ok) {
+      SyncRequest::CallData cd(this, mrd);
+      mrd->Request(server_);
 
-    RpcServiceMethod *method = nullptr;
-    auto iter = method_map_.find(server_context->method());
-    if (iter != method_map_.end()) {
-      method = iter->second;
+      cd.Run();
     }
-    ServerRpcHandler rpc_handler(server_context, method);
-    rpc_handler.StartRpc();
   }
 
   {
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index add22cc3d868530036670ae0a2ebf0166a2e668c..3c2093c3638996e4110339b4a70e9dfe66938cd6 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,40 +33,70 @@
 
 #include <grpc++/server_builder.h>
 
+#include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
+#include <grpc++/impl/service_type.h>
 #include <grpc++/server.h>
+#include "src/cpp/server/thread_pool.h"
 
 namespace grpc {
 
-ServerBuilder::ServerBuilder() : thread_pool_(nullptr) {}
+ServerBuilder::ServerBuilder() {}
 
-void ServerBuilder::RegisterService(RpcService *service) {
-  services_.push_back(service);
+void ServerBuilder::RegisterService(SynchronousService* service) {
+  services_.push_back(service->service());
 }
 
-void ServerBuilder::AddPort(const grpc::string &addr) {
+void ServerBuilder::RegisterAsyncService(AsynchronousService* service) {
+  async_services_.push_back(service);
+}
+
+void ServerBuilder::AddPort(const grpc::string& addr) {
   ports_.push_back(addr);
 }
 
 void ServerBuilder::SetCredentials(
-    const std::shared_ptr<ServerCredentials> &creds) {
+    const std::shared_ptr<ServerCredentials>& creds) {
   GPR_ASSERT(!creds_);
   creds_ = creds;
 }
 
-void ServerBuilder::SetThreadPool(ThreadPoolInterface *thread_pool) {
+void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) {
   thread_pool_ = thread_pool;
 }
 
 std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
-  std::unique_ptr<Server> server(new Server(thread_pool_, creds_.get()));
-  for (auto *service : services_) {
-    server->RegisterService(service);
+  bool thread_pool_owned = false;
+  if (!async_services_.empty() && !services_.empty()) {
+    gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now");
+    return nullptr;
+  }
+  if (!thread_pool_ && services_.size()) {
+    int cores = gpr_cpu_num_cores();
+    if (!cores) cores = 4;
+    thread_pool_ = new ThreadPool(cores);
+    thread_pool_owned = true;
+  }
+  std::unique_ptr<Server> server(
+      new Server(thread_pool_, thread_pool_owned, creds_.get()));
+  for (auto* service : services_) {
+    if (!server->RegisterService(service)) {
+      return nullptr;
+    }
+  }
+  for (auto* service : async_services_) {
+    if (!server->RegisterAsyncService(service)) {
+      return nullptr;
+    }
+  }
+  for (auto& port : ports_) {
+    if (!server->AddPort(port)) {
+      return nullptr;
+    }
   }
-  for (auto &port : ports_) {
-    server->AddPort(port);
+  if (!server->Start()) {
+    return nullptr;
   }
-  server->Start();
   return server;
 }
 
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1aa18bcac572d82fe222736eeac283198ee7fa56
--- /dev/null
+++ b/src/cpp/server/server_context.cc
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/server_context.h>
+
+#include <mutex>
+
+#include <grpc++/impl/call.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "src/cpp/util/time.h"
+
+namespace grpc {
+
+// CompletionOp
+
+class ServerContext::CompletionOp final : public CallOpBuffer {
+ public:
+  CompletionOp();
+  bool FinalizeResult(void** tag, bool* status) override;
+
+  bool CheckCancelled(CompletionQueue* cq);
+
+  void Unref();
+
+ private:
+  std::mutex mu_;
+  int refs_ = 2;  // initial refs: one in the server context, one in the cq
+  bool finalized_ = false;
+  bool cancelled_ = false;
+};
+
+ServerContext::CompletionOp::CompletionOp() { AddServerRecvClose(&cancelled_); }
+
+void ServerContext::CompletionOp::Unref() {
+  std::unique_lock<std::mutex> lock(mu_);
+  if (--refs_ == 0) {
+    lock.unlock();
+    delete this;
+  }
+}
+
+bool ServerContext::CompletionOp::CheckCancelled(CompletionQueue* cq) {
+  cq->TryPluck(this);
+  std::lock_guard<std::mutex> g(mu_);
+  return finalized_ ? cancelled_ : false;
+}
+
+bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) {
+  GPR_ASSERT(CallOpBuffer::FinalizeResult(tag, status));
+  std::unique_lock<std::mutex> lock(mu_);
+  finalized_ = true;
+  if (!*status) cancelled_ = true;
+  if (--refs_ == 0) {
+    lock.unlock();
+    delete this;
+  }
+  return false;
+}
+
+// ServerContext body
+
+ServerContext::ServerContext() {}
+
+ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
+                             size_t metadata_count)
+    : deadline_(Timespec2Timepoint(deadline)) {
+  for (size_t i = 0; i < metadata_count; i++) {
+    client_metadata_.insert(std::make_pair(
+        grpc::string(metadata[i].key),
+        grpc::string(metadata[i].value,
+                     metadata[i].value + metadata[i].value_length)));
+  }
+}
+
+ServerContext::~ServerContext() {
+  if (call_) {
+    grpc_call_destroy(call_);
+  }
+  if (completion_op_) {
+    completion_op_->Unref();
+  }
+}
+
+void ServerContext::BeginCompletionOp(Call* call) {
+  GPR_ASSERT(!completion_op_);
+  completion_op_ = new CompletionOp();
+  call->PerformOps(completion_op_);
+}
+
+void ServerContext::AddInitialMetadata(const grpc::string& key,
+                                       const grpc::string& value) {
+  initial_metadata_.insert(std::make_pair(key, value));
+}
+
+void ServerContext::AddTrailingMetadata(const grpc::string& key,
+                                        const grpc::string& value) {
+  trailing_metadata_.insert(std::make_pair(key, value));
+}
+
+bool ServerContext::IsCancelled() {
+  return completion_op_ && completion_op_->CheckCancelled(cq_);
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc
index ce0271b6a0aa6c48a94aae25e6e95cf239f6d89a..69ad000ccc69f2d433910c52dc421466b6e193f4 100644
--- a/src/cpp/server/server_credentials.cc
+++ b/src/cpp/server/server_credentials.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/server/server_rpc_handler.cc b/src/cpp/server/server_rpc_handler.cc
deleted file mode 100644
index bf02de8b805c59adc30026feab6fc39e8aa011c6..0000000000000000000000000000000000000000
--- a/src/cpp/server/server_rpc_handler.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *
- * Copyright 2014, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/cpp/server/server_rpc_handler.h"
-
-#include <grpc/support/log.h>
-#include "src/cpp/server/server_context_impl.h"
-#include "src/cpp/stream/stream_context.h"
-#include <grpc++/async_server_context.h>
-#include <grpc++/impl/rpc_service_method.h>
-
-namespace grpc {
-
-ServerRpcHandler::ServerRpcHandler(AsyncServerContext *async_server_context,
-                                   RpcServiceMethod *method)
-    : async_server_context_(async_server_context), method_(method) {}
-
-void ServerRpcHandler::StartRpc() {
-  if (method_ == nullptr) {
-    // Method not supported, finish the rpc with error.
-    // TODO(rocking): do we need to call read to consume the request?
-    FinishRpc(Status(StatusCode::UNIMPLEMENTED, "No such method."));
-    return;
-  }
-
-  ServerContextImpl user_context(async_server_context_->absolute_deadline());
-
-  if (method_->method_type() == RpcMethod::NORMAL_RPC) {
-    // Start the rpc on this dedicated completion queue.
-    async_server_context_->Accept(cq_.cq());
-
-    // Allocate request and response.
-    std::unique_ptr<google::protobuf::Message> request(
-        method_->AllocateRequestProto());
-    std::unique_ptr<google::protobuf::Message> response(
-        method_->AllocateResponseProto());
-
-    // Read request
-    async_server_context_->StartRead(request.get());
-    auto type = WaitForNextEvent();
-    GPR_ASSERT(type == CompletionQueue::SERVER_READ_OK);
-
-    // Run the application's rpc handler
-    MethodHandler *handler = method_->handler();
-    Status status = handler->RunHandler(MethodHandler::HandlerParameter(
-        &user_context, request.get(), response.get()));
-
-    if (status.IsOk()) {
-      // Send the response if we get an ok status.
-      async_server_context_->StartWrite(*response, GRPC_WRITE_BUFFER_HINT);
-      type = WaitForNextEvent();
-      if (type != CompletionQueue::SERVER_WRITE_OK) {
-        status = Status(StatusCode::INTERNAL, "Error writing response.");
-      }
-    }
-
-    FinishRpc(status);
-  } else {
-    // Allocate request and response.
-    // TODO(yangg) maybe not allocate both when not needed?
-    std::unique_ptr<google::protobuf::Message> request(
-        method_->AllocateRequestProto());
-    std::unique_ptr<google::protobuf::Message> response(
-        method_->AllocateResponseProto());
-
-    StreamContext stream_context(*method_, async_server_context_->call(),
-                                 cq_.cq(), request.get(), response.get());
-
-    // Run the application's rpc handler
-    MethodHandler *handler = method_->handler();
-    Status status = handler->RunHandler(MethodHandler::HandlerParameter(
-        &user_context, request.get(), response.get(), &stream_context));
-    if (status.IsOk() &&
-        method_->method_type() == RpcMethod::CLIENT_STREAMING) {
-      stream_context.Write(response.get(), false);
-    }
-    // TODO(yangg) Do we need to consider the status in stream_context?
-    FinishRpc(status);
-  }
-}
-
-CompletionQueue::CompletionType ServerRpcHandler::WaitForNextEvent() {
-  void *tag = nullptr;
-  CompletionQueue::CompletionType type = cq_.Next(&tag);
-  if (type != CompletionQueue::QUEUE_CLOSED &&
-      type != CompletionQueue::RPC_END) {
-    GPR_ASSERT(static_cast<AsyncServerContext *>(tag) ==
-               async_server_context_.get());
-  }
-  return type;
-}
-
-void ServerRpcHandler::FinishRpc(const Status &status) {
-  async_server_context_->StartWriteStatus(status);
-  CompletionQueue::CompletionType type;
-
-  // HALFCLOSE_OK and RPC_END events come in either order.
-  type = WaitForNextEvent();
-  GPR_ASSERT(type == CompletionQueue::HALFCLOSE_OK ||
-             type == CompletionQueue::RPC_END);
-  type = WaitForNextEvent();
-  GPR_ASSERT(type == CompletionQueue::HALFCLOSE_OK ||
-             type == CompletionQueue::RPC_END);
-
-  cq_.Shutdown();
-  type = WaitForNextEvent();
-  GPR_ASSERT(type == CompletionQueue::QUEUE_CLOSED);
-}
-
-}  // namespace grpc
diff --git a/src/cpp/server/thread_pool.cc b/src/cpp/server/thread_pool.cc
index 20279592cbc59981fdc92e23d76915dc64010e44..1ca98129d3eeb385a060b67374c5d78433f65187 100644
--- a/src/cpp/server/thread_pool.cc
+++ b/src/cpp/server/thread_pool.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/server/thread_pool.h b/src/cpp/server/thread_pool.h
index c53f7a7517a3fe79202baf030d39057a90cf5df0..283618f4b6860d2ac0f96c15d9f4ae62fa86f3bc 100644
--- a/src/cpp/server/thread_pool.h
+++ b/src/cpp/server/thread_pool.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,12 +44,12 @@
 
 namespace grpc {
 
-class ThreadPool : public ThreadPoolInterface {
+class ThreadPool final : public ThreadPoolInterface {
  public:
   explicit ThreadPool(int num_threads);
   ~ThreadPool();
 
-  void ScheduleCallback(const std::function<void()> &callback) final;
+  void ScheduleCallback(const std::function<void()> &callback) override;
 
  private:
   std::mutex mu_;
diff --git a/src/cpp/stream/stream_context.cc b/src/cpp/stream/stream_context.cc
deleted file mode 100644
index e4f344dbb935f9c7605a8ab1f2f9f4e8a4700788..0000000000000000000000000000000000000000
--- a/src/cpp/stream/stream_context.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *
- * Copyright 2014, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/cpp/stream/stream_context.h"
-
-#include <grpc/support/log.h>
-#include "src/cpp/proto/proto_utils.h"
-#include "src/cpp/util/time.h"
-#include <grpc++/client_context.h>
-#include <grpc++/config.h>
-#include <grpc++/impl/rpc_method.h>
-#include <google/protobuf/message.h>
-
-namespace grpc {
-
-// Client only ctor
-StreamContext::StreamContext(const RpcMethod &method, ClientContext *context,
-                             const google::protobuf::Message *request,
-                             google::protobuf::Message *result)
-    : is_client_(true),
-      method_(&method),
-      call_(context->call()),
-      cq_(context->cq()),
-      request_(const_cast<google::protobuf::Message *>(request)),
-      result_(result),
-      peer_halfclosed_(false),
-      self_halfclosed_(false) {
-  GPR_ASSERT(method_->method_type() != RpcMethod::RpcType::NORMAL_RPC);
-}
-
-// Server only ctor
-StreamContext::StreamContext(const RpcMethod &method, grpc_call *call,
-                             grpc_completion_queue *cq,
-                             google::protobuf::Message *request,
-                             google::protobuf::Message *result)
-    : is_client_(false),
-      method_(&method),
-      call_(call),
-      cq_(cq),
-      request_(request),
-      result_(result),
-      peer_halfclosed_(false),
-      self_halfclosed_(false) {
-  GPR_ASSERT(method_->method_type() != RpcMethod::RpcType::NORMAL_RPC);
-}
-
-StreamContext::~StreamContext() {}
-
-void StreamContext::Start(bool buffered) {
-  if (is_client_) {
-    // TODO(yangg) handle metadata send path
-    int flag = buffered ? GRPC_WRITE_BUFFER_HINT : 0;
-    grpc_call_error error = grpc_call_invoke_old(
-        call(), cq(), client_metadata_read_tag(), finished_tag(), flag);
-    GPR_ASSERT(GRPC_CALL_OK == error);
-  } else {
-    // TODO(yangg) metadata needs to be added before accept
-    // TODO(yangg) correctly set flag to accept
-    GPR_ASSERT(grpc_call_server_accept_old(call(), cq(), finished_tag()) ==
-               GRPC_CALL_OK);
-    GPR_ASSERT(grpc_call_server_end_initial_metadata_old(call(), 0) ==
-               GRPC_CALL_OK);
-  }
-}
-
-bool StreamContext::Read(google::protobuf::Message *msg) {
-  // TODO(yangg) check peer_halfclosed_ here for possible early return.
-  grpc_call_error err = grpc_call_start_read_old(call(), read_tag());
-  GPR_ASSERT(err == GRPC_CALL_OK);
-  grpc_event *read_ev =
-      grpc_completion_queue_pluck(cq(), read_tag(), gpr_inf_future);
-  GPR_ASSERT(read_ev->type == GRPC_READ);
-  bool ret = true;
-  if (read_ev->data.read) {
-    if (!DeserializeProto(read_ev->data.read, msg)) {
-      ret = false;
-      grpc_call_cancel_with_status(call(), GRPC_STATUS_DATA_LOSS,
-                                   "Failed to parse incoming proto");
-    }
-  } else {
-    ret = false;
-    peer_halfclosed_ = true;
-  }
-  grpc_event_finish(read_ev);
-  return ret;
-}
-
-bool StreamContext::Write(const google::protobuf::Message *msg, bool is_last) {
-  // TODO(yangg) check self_halfclosed_ for possible early return.
-  bool ret = true;
-  grpc_event *ev = nullptr;
-
-  if (msg) {
-    grpc_byte_buffer *out_buf = nullptr;
-    if (!SerializeProto(*msg, &out_buf)) {
-      grpc_call_cancel_with_status(call(), GRPC_STATUS_INVALID_ARGUMENT,
-                                   "Failed to serialize outgoing proto");
-      return false;
-    }
-    int flag = is_last ? GRPC_WRITE_BUFFER_HINT : 0;
-    grpc_call_error err =
-        grpc_call_start_write_old(call(), out_buf, write_tag(), flag);
-    grpc_byte_buffer_destroy(out_buf);
-    GPR_ASSERT(err == GRPC_CALL_OK);
-
-    ev = grpc_completion_queue_pluck(cq(), write_tag(), gpr_inf_future);
-    GPR_ASSERT(ev->type == GRPC_WRITE_ACCEPTED);
-
-    ret = ev->data.write_accepted == GRPC_OP_OK;
-    grpc_event_finish(ev);
-  }
-  if (ret && is_last) {
-    grpc_call_error err = grpc_call_writes_done_old(call(), halfclose_tag());
-    GPR_ASSERT(err == GRPC_CALL_OK);
-    ev = grpc_completion_queue_pluck(cq(), halfclose_tag(), gpr_inf_future);
-    GPR_ASSERT(ev->type == GRPC_FINISH_ACCEPTED);
-    grpc_event_finish(ev);
-
-    self_halfclosed_ = true;
-  } else if (!ret) {  // Stream broken
-    self_halfclosed_ = true;
-    peer_halfclosed_ = true;
-  }
-
-  return ret;
-}
-
-const Status &StreamContext::Wait() {
-  // TODO(yangg) properly support metadata
-  grpc_event *metadata_ev = grpc_completion_queue_pluck(
-      cq(), client_metadata_read_tag(), gpr_inf_future);
-  grpc_event_finish(metadata_ev);
-  // TODO(yangg) protect states by a mutex, including other places.
-  if (!self_halfclosed_ || !peer_halfclosed_) {
-    Cancel();
-  }
-  grpc_event *finish_ev =
-      grpc_completion_queue_pluck(cq(), finished_tag(), gpr_inf_future);
-  GPR_ASSERT(finish_ev->type == GRPC_FINISHED);
-  final_status_ = Status(
-      static_cast<StatusCode>(finish_ev->data.finished.status),
-      finish_ev->data.finished.details ? finish_ev->data.finished.details : "");
-  grpc_event_finish(finish_ev);
-  return final_status_;
-}
-
-void StreamContext::Cancel() { grpc_call_cancel(call()); }
-
-}  // namespace grpc
diff --git a/src/cpp/stream/stream_context.h b/src/cpp/stream/stream_context.h
deleted file mode 100644
index 8def589841b3295055e4dda56a176c1a846e7548..0000000000000000000000000000000000000000
--- a/src/cpp/stream/stream_context.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- *
- * Copyright 2014, 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 __GRPCPP_INTERNAL_STREAM_STREAM_CONTEXT_H__
-#define __GRPCPP_INTERNAL_STREAM_STREAM_CONTEXT_H__
-
-#include <grpc/grpc.h>
-#include <grpc++/status.h>
-#include <grpc++/stream_context_interface.h>
-
-namespace google {
-namespace protobuf {
-class Message;
-}
-}
-
-namespace grpc {
-class ClientContext;
-class RpcMethod;
-
-class StreamContext final : public StreamContextInterface {
- public:
-  StreamContext(const RpcMethod &method, ClientContext *context,
-                const google::protobuf::Message *request,
-                google::protobuf::Message *result);
-  StreamContext(const RpcMethod &method, grpc_call *call,
-                grpc_completion_queue *cq, google::protobuf::Message *request,
-                google::protobuf::Message *result);
-  ~StreamContext();
-  // Start the stream, if there is a final write following immediately, set
-  // buffered so that the messages can be sent in batch.
-  void Start(bool buffered) override;
-  bool Read(google::protobuf::Message *msg) override;
-  bool Write(const google::protobuf::Message *msg, bool is_last) override;
-  const Status &Wait() override;
-  void Cancel() override;
-
-  google::protobuf::Message *request() override { return request_; }
-  google::protobuf::Message *response() override { return result_; }
-
- private:
-  // Unique tags for plucking events from the c layer. this pointer is casted
-  // to char* to create single byte step between tags. It implicitly relies on
-  // that StreamContext is large enough to contain all the pointers.
-  void *finished_tag() { return reinterpret_cast<char *>(this); }
-  void *read_tag() { return reinterpret_cast<char *>(this) + 1; }
-  void *write_tag() { return reinterpret_cast<char *>(this) + 2; }
-  void *halfclose_tag() { return reinterpret_cast<char *>(this) + 3; }
-  void *client_metadata_read_tag() {
-    return reinterpret_cast<char *>(this) + 5;
-  }
-  grpc_call *call() { return call_; }
-  grpc_completion_queue *cq() { return cq_; }
-
-  bool is_client_;
-  const RpcMethod *method_;             // not owned
-  grpc_call *call_;                     // not owned
-  grpc_completion_queue *cq_;           // not owned
-  google::protobuf::Message *request_;  // first request, not owned
-  google::protobuf::Message *result_;   // last response, not owned
-
-  bool peer_halfclosed_;
-  bool self_halfclosed_;
-  Status final_status_;
-};
-
-}  // namespace grpc
-
-#endif  // __GRPCPP_INTERNAL_STREAM_STREAM_CONTEXT_H__
diff --git a/src/cpp/util/status.cc b/src/cpp/util/status.cc
index 1ca12d0ae900fe9a0bfc71cdca9cc464939f0a12..bbf803066869500cbec90d5e0ccbd72019ff116a 100644
--- a/src/cpp/util/status.cc
+++ b/src/cpp/util/status.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc
index 7ce7a371f5618ecf85b2c0c2810b162be17e8c63..919e5623fa31eb48995c23afaf58c46be9a3e3ee 100644
--- a/src/cpp/util/time.cc
+++ b/src/cpp/util/time.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/cpp/util/time.h b/src/cpp/util/time.h
index 908395c92b9a02dd07bea9affaef51136b31a88d..9f9e582d070ace021114c3167c20c0d34d6d4303 100644
--- a/src/cpp/util/time.h
+++ b/src/cpp/util/time.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/GrpcApi/Empty.cs b/src/csharp/GrpcApi/Empty.cs
index dadfd151ecc739839bea2c60ba46c1d6d566b60a..7169ee2a4a5d8bf10ec6ead259d5518c1d8c0c7e 100644
--- a/src/csharp/GrpcApi/Empty.cs
+++ b/src/csharp/GrpcApi/Empty.cs
@@ -7,12 +7,12 @@ using pbc = global::Google.ProtocolBuffers.Collections;
 using pbd = global::Google.ProtocolBuffers.Descriptors;
 using scg = global::System.Collections.Generic;
 namespace grpc.testing {
-  
+
   namespace Proto {
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public static partial class Empty {
-    
+
       #region Extension registration
       public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
       }
@@ -26,7 +26,7 @@ namespace grpc.testing {
         get { return descriptor; }
       }
       private static pbd::FileDescriptor descriptor;
-      
+
       static Empty() {
         byte[] descriptorData = global::System.Convert.FromBase64String(
             string.Concat(
@@ -34,7 +34,7 @@ namespace grpc.testing {
         pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
           descriptor = root;
           internal__static_grpc_testing_Empty__Descriptor = Descriptor.MessageTypes[0];
-          internal__static_grpc_testing_Empty__FieldAccessorTable = 
+          internal__static_grpc_testing_Empty__FieldAccessorTable =
               new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Empty, global::grpc.testing.Empty.Builder>(internal__static_grpc_testing_Empty__Descriptor,
                   new string[] { });
           return null;
@@ -44,7 +44,7 @@ namespace grpc.testing {
             }, assigner);
       }
       #endregion
-      
+
     }
   }
   #region Messages
@@ -57,48 +57,48 @@ namespace grpc.testing {
     public static Empty DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override Empty DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override Empty ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Proto.Empty.internal__static_grpc_testing_Empty__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<Empty, Empty.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Proto.Empty.internal__static_grpc_testing_Empty__FieldAccessorTable; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _emptyFieldNames;
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         size += UnknownFields.SerializedSize;
         memoizedSerializedSize = size;
         return size;
       }
     }
-    
+
     public static Empty ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -132,14 +132,14 @@ namespace grpc.testing {
     private Empty MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(Empty prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<Empty, Builder> {
       protected override Builder ThisBuilder {
@@ -153,10 +153,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private Empty result;
-      
+
       private Empty PrepareBuilder() {
         if (resultIsReadOnly) {
           Empty original = result;
@@ -166,21 +166,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override Empty MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -188,15 +188,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.Empty.Descriptor; }
       }
-      
+
       public override Empty DefaultInstanceForType {
         get { return global::grpc.testing.Empty.DefaultInstance; }
       }
-      
+
       public override Empty BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -204,7 +204,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is Empty) {
           return MergeFrom((Empty) other);
@@ -213,18 +213,18 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(Empty other) {
         if (other == global::grpc.testing.Empty.DefaultInstance) return this;
         PrepareBuilder();
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -262,21 +262,21 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
+
     }
     static Empty() {
       object.ReferenceEquals(global::grpc.testing.Proto.Empty.Descriptor, null);
     }
   }
-  
+
   #endregion
-  
+
 }
 
 #endregion Designer generated code
diff --git a/src/csharp/GrpcApi/Math.cs b/src/csharp/GrpcApi/Math.cs
index 2d700337ac7953c343353240645f12803df70130..75b1e9dbc2ab5b82922ad4386a5f0472dbf8e5b5 100644
--- a/src/csharp/GrpcApi/Math.cs
+++ b/src/csharp/GrpcApi/Math.cs
@@ -7,12 +7,12 @@ using pbc = global::Google.ProtocolBuffers.Collections;
 using pbd = global::Google.ProtocolBuffers.Descriptors;
 using scg = global::System.Collections.Generic;
 namespace math {
-  
+
   namespace Proto {
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public static partial class Math {
-    
+
       #region Extension registration
       public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
       }
@@ -34,38 +34,38 @@ namespace math {
         get { return descriptor; }
       }
       private static pbd::FileDescriptor descriptor;
-      
+
       static Math() {
         byte[] descriptorData = global::System.Convert.FromBase64String(
             string.Concat(
-              "CgptYXRoLnByb3RvEgRtYXRoIiwKB0RpdkFyZ3MSEAoIZGl2aWRlbmQYASAB", 
-              "KAMSDwoHZGl2aXNvchgCIAEoAyIvCghEaXZSZXBseRIQCghxdW90aWVudBgB", 
-              "IAEoAxIRCglyZW1haW5kZXIYAiABKAMiGAoHRmliQXJncxINCgVsaW1pdBgB", 
-              "IAEoAyISCgNOdW0SCwoDbnVtGAEgASgDIhkKCEZpYlJlcGx5Eg0KBWNvdW50", 
-              "GAEgASgDMqQBCgRNYXRoEiYKA0RpdhINLm1hdGguRGl2QXJncxoOLm1hdGgu", 
-              "RGl2UmVwbHkiABIuCgdEaXZNYW55Eg0ubWF0aC5EaXZBcmdzGg4ubWF0aC5E", 
-              "aXZSZXBseSIAKAEwARIjCgNGaWISDS5tYXRoLkZpYkFyZ3MaCS5tYXRoLk51", 
+              "CgptYXRoLnByb3RvEgRtYXRoIiwKB0RpdkFyZ3MSEAoIZGl2aWRlbmQYASAB",
+              "KAMSDwoHZGl2aXNvchgCIAEoAyIvCghEaXZSZXBseRIQCghxdW90aWVudBgB",
+              "IAEoAxIRCglyZW1haW5kZXIYAiABKAMiGAoHRmliQXJncxINCgVsaW1pdBgB",
+              "IAEoAyISCgNOdW0SCwoDbnVtGAEgASgDIhkKCEZpYlJlcGx5Eg0KBWNvdW50",
+              "GAEgASgDMqQBCgRNYXRoEiYKA0RpdhINLm1hdGguRGl2QXJncxoOLm1hdGgu",
+              "RGl2UmVwbHkiABIuCgdEaXZNYW55Eg0ubWF0aC5EaXZBcmdzGg4ubWF0aC5E",
+              "aXZSZXBseSIAKAEwARIjCgNGaWISDS5tYXRoLkZpYkFyZ3MaCS5tYXRoLk51",
             "bSIAMAESHwoDU3VtEgkubWF0aC5OdW0aCS5tYXRoLk51bSIAKAE="));
         pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
           descriptor = root;
           internal__static_math_DivArgs__Descriptor = Descriptor.MessageTypes[0];
-          internal__static_math_DivArgs__FieldAccessorTable = 
+          internal__static_math_DivArgs__FieldAccessorTable =
               new pb::FieldAccess.FieldAccessorTable<global::math.DivArgs, global::math.DivArgs.Builder>(internal__static_math_DivArgs__Descriptor,
                   new string[] { "Dividend", "Divisor", });
           internal__static_math_DivReply__Descriptor = Descriptor.MessageTypes[1];
-          internal__static_math_DivReply__FieldAccessorTable = 
+          internal__static_math_DivReply__FieldAccessorTable =
               new pb::FieldAccess.FieldAccessorTable<global::math.DivReply, global::math.DivReply.Builder>(internal__static_math_DivReply__Descriptor,
                   new string[] { "Quotient", "Remainder", });
           internal__static_math_FibArgs__Descriptor = Descriptor.MessageTypes[2];
-          internal__static_math_FibArgs__FieldAccessorTable = 
+          internal__static_math_FibArgs__FieldAccessorTable =
               new pb::FieldAccess.FieldAccessorTable<global::math.FibArgs, global::math.FibArgs.Builder>(internal__static_math_FibArgs__Descriptor,
                   new string[] { "Limit", });
           internal__static_math_Num__Descriptor = Descriptor.MessageTypes[3];
-          internal__static_math_Num__FieldAccessorTable = 
+          internal__static_math_Num__FieldAccessorTable =
               new pb::FieldAccess.FieldAccessorTable<global::math.Num, global::math.Num.Builder>(internal__static_math_Num__Descriptor,
                   new string[] { "Num_", });
           internal__static_math_FibReply__Descriptor = Descriptor.MessageTypes[4];
-          internal__static_math_FibReply__FieldAccessorTable = 
+          internal__static_math_FibReply__FieldAccessorTable =
               new pb::FieldAccess.FieldAccessorTable<global::math.FibReply, global::math.FibReply.Builder>(internal__static_math_FibReply__Descriptor,
                   new string[] { "Count", });
           pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
@@ -77,7 +77,7 @@ namespace math {
             }, assigner);
       }
       #endregion
-      
+
     }
   }
   #region Messages
@@ -90,23 +90,23 @@ namespace math {
     public static DivArgs DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override DivArgs DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override DivArgs ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::math.Proto.Math.internal__static_math_DivArgs__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<DivArgs, DivArgs.Builder> InternalFieldAccessors {
       get { return global::math.Proto.Math.internal__static_math_DivArgs__FieldAccessorTable; }
     }
-    
+
     public const int DividendFieldNumber = 1;
     private bool hasDividend;
     private long dividend_;
@@ -116,7 +116,7 @@ namespace math {
     public long Dividend {
       get { return dividend_; }
     }
-    
+
     public const int DivisorFieldNumber = 2;
     private bool hasDivisor;
     private long divisor_;
@@ -126,13 +126,13 @@ namespace math {
     public long Divisor {
       get { return divisor_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _divArgsFieldNames;
@@ -144,13 +144,13 @@ namespace math {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasDividend) {
           size += pb::CodedOutputStream.ComputeInt64Size(1, Dividend);
@@ -163,7 +163,7 @@ namespace math {
         return size;
       }
     }
-    
+
     public static DivArgs ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -197,14 +197,14 @@ namespace math {
     private DivArgs MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(DivArgs prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<DivArgs, Builder> {
       protected override Builder ThisBuilder {
@@ -218,10 +218,10 @@ namespace math {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private DivArgs result;
-      
+
       private DivArgs PrepareBuilder() {
         if (resultIsReadOnly) {
           DivArgs original = result;
@@ -231,21 +231,21 @@ namespace math {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override DivArgs MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -253,15 +253,15 @@ namespace math {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::math.DivArgs.Descriptor; }
       }
-      
+
       public override DivArgs DefaultInstanceForType {
         get { return global::math.DivArgs.DefaultInstance; }
       }
-      
+
       public override DivArgs BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -269,7 +269,7 @@ namespace math {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is DivArgs) {
           return MergeFrom((DivArgs) other);
@@ -278,7 +278,7 @@ namespace math {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(DivArgs other) {
         if (other == global::math.DivArgs.DefaultInstance) return this;
         PrepareBuilder();
@@ -291,11 +291,11 @@ namespace math {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -341,14 +341,14 @@ namespace math {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasDividend {
         get { return result.hasDividend; }
       }
@@ -368,7 +368,7 @@ namespace math {
         result.dividend_ = 0L;
         return this;
       }
-      
+
       public bool HasDivisor {
         get { return result.hasDivisor; }
       }
@@ -393,7 +393,7 @@ namespace math {
       object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class DivReply : pb::GeneratedMessage<DivReply, DivReply.Builder> {
     private DivReply() { }
@@ -403,23 +403,23 @@ namespace math {
     public static DivReply DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override DivReply DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override DivReply ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::math.Proto.Math.internal__static_math_DivReply__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<DivReply, DivReply.Builder> InternalFieldAccessors {
       get { return global::math.Proto.Math.internal__static_math_DivReply__FieldAccessorTable; }
     }
-    
+
     public const int QuotientFieldNumber = 1;
     private bool hasQuotient;
     private long quotient_;
@@ -429,7 +429,7 @@ namespace math {
     public long Quotient {
       get { return quotient_; }
     }
-    
+
     public const int RemainderFieldNumber = 2;
     private bool hasRemainder;
     private long remainder_;
@@ -439,13 +439,13 @@ namespace math {
     public long Remainder {
       get { return remainder_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _divReplyFieldNames;
@@ -457,13 +457,13 @@ namespace math {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasQuotient) {
           size += pb::CodedOutputStream.ComputeInt64Size(1, Quotient);
@@ -476,7 +476,7 @@ namespace math {
         return size;
       }
     }
-    
+
     public static DivReply ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -510,14 +510,14 @@ namespace math {
     private DivReply MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(DivReply prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<DivReply, Builder> {
       protected override Builder ThisBuilder {
@@ -531,10 +531,10 @@ namespace math {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private DivReply result;
-      
+
       private DivReply PrepareBuilder() {
         if (resultIsReadOnly) {
           DivReply original = result;
@@ -544,21 +544,21 @@ namespace math {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override DivReply MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -566,15 +566,15 @@ namespace math {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::math.DivReply.Descriptor; }
       }
-      
+
       public override DivReply DefaultInstanceForType {
         get { return global::math.DivReply.DefaultInstance; }
       }
-      
+
       public override DivReply BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -582,7 +582,7 @@ namespace math {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is DivReply) {
           return MergeFrom((DivReply) other);
@@ -591,7 +591,7 @@ namespace math {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(DivReply other) {
         if (other == global::math.DivReply.DefaultInstance) return this;
         PrepareBuilder();
@@ -604,11 +604,11 @@ namespace math {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -654,14 +654,14 @@ namespace math {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasQuotient {
         get { return result.hasQuotient; }
       }
@@ -681,7 +681,7 @@ namespace math {
         result.quotient_ = 0L;
         return this;
       }
-      
+
       public bool HasRemainder {
         get { return result.hasRemainder; }
       }
@@ -706,7 +706,7 @@ namespace math {
       object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class FibArgs : pb::GeneratedMessage<FibArgs, FibArgs.Builder> {
     private FibArgs() { }
@@ -716,23 +716,23 @@ namespace math {
     public static FibArgs DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override FibArgs DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override FibArgs ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::math.Proto.Math.internal__static_math_FibArgs__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<FibArgs, FibArgs.Builder> InternalFieldAccessors {
       get { return global::math.Proto.Math.internal__static_math_FibArgs__FieldAccessorTable; }
     }
-    
+
     public const int LimitFieldNumber = 1;
     private bool hasLimit;
     private long limit_;
@@ -742,13 +742,13 @@ namespace math {
     public long Limit {
       get { return limit_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _fibArgsFieldNames;
@@ -757,13 +757,13 @@ namespace math {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasLimit) {
           size += pb::CodedOutputStream.ComputeInt64Size(1, Limit);
@@ -773,7 +773,7 @@ namespace math {
         return size;
       }
     }
-    
+
     public static FibArgs ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -807,14 +807,14 @@ namespace math {
     private FibArgs MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(FibArgs prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<FibArgs, Builder> {
       protected override Builder ThisBuilder {
@@ -828,10 +828,10 @@ namespace math {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private FibArgs result;
-      
+
       private FibArgs PrepareBuilder() {
         if (resultIsReadOnly) {
           FibArgs original = result;
@@ -841,21 +841,21 @@ namespace math {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override FibArgs MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -863,15 +863,15 @@ namespace math {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::math.FibArgs.Descriptor; }
       }
-      
+
       public override FibArgs DefaultInstanceForType {
         get { return global::math.FibArgs.DefaultInstance; }
       }
-      
+
       public override FibArgs BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -879,7 +879,7 @@ namespace math {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is FibArgs) {
           return MergeFrom((FibArgs) other);
@@ -888,7 +888,7 @@ namespace math {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(FibArgs other) {
         if (other == global::math.FibArgs.DefaultInstance) return this;
         PrepareBuilder();
@@ -898,11 +898,11 @@ namespace math {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -944,14 +944,14 @@ namespace math {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasLimit {
         get { return result.hasLimit; }
       }
@@ -976,7 +976,7 @@ namespace math {
       object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Num : pb::GeneratedMessage<Num, Num.Builder> {
     private Num() { }
@@ -986,23 +986,23 @@ namespace math {
     public static Num DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override Num DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override Num ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::math.Proto.Math.internal__static_math_Num__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<Num, Num.Builder> InternalFieldAccessors {
       get { return global::math.Proto.Math.internal__static_math_Num__FieldAccessorTable; }
     }
-    
+
     public const int Num_FieldNumber = 1;
     private bool hasNum_;
     private long num_;
@@ -1012,13 +1012,13 @@ namespace math {
     public long Num_ {
       get { return num_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _numFieldNames;
@@ -1027,13 +1027,13 @@ namespace math {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasNum_) {
           size += pb::CodedOutputStream.ComputeInt64Size(1, Num_);
@@ -1043,7 +1043,7 @@ namespace math {
         return size;
       }
     }
-    
+
     public static Num ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -1077,14 +1077,14 @@ namespace math {
     private Num MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(Num prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<Num, Builder> {
       protected override Builder ThisBuilder {
@@ -1098,10 +1098,10 @@ namespace math {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private Num result;
-      
+
       private Num PrepareBuilder() {
         if (resultIsReadOnly) {
           Num original = result;
@@ -1111,21 +1111,21 @@ namespace math {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override Num MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -1133,15 +1133,15 @@ namespace math {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::math.Num.Descriptor; }
       }
-      
+
       public override Num DefaultInstanceForType {
         get { return global::math.Num.DefaultInstance; }
       }
-      
+
       public override Num BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -1149,7 +1149,7 @@ namespace math {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is Num) {
           return MergeFrom((Num) other);
@@ -1158,7 +1158,7 @@ namespace math {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(Num other) {
         if (other == global::math.Num.DefaultInstance) return this;
         PrepareBuilder();
@@ -1168,11 +1168,11 @@ namespace math {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -1214,14 +1214,14 @@ namespace math {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasNum_ {
         get { return result.hasNum_; }
       }
@@ -1246,7 +1246,7 @@ namespace math {
       object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class FibReply : pb::GeneratedMessage<FibReply, FibReply.Builder> {
     private FibReply() { }
@@ -1256,23 +1256,23 @@ namespace math {
     public static FibReply DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override FibReply DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override FibReply ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::math.Proto.Math.internal__static_math_FibReply__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<FibReply, FibReply.Builder> InternalFieldAccessors {
       get { return global::math.Proto.Math.internal__static_math_FibReply__FieldAccessorTable; }
     }
-    
+
     public const int CountFieldNumber = 1;
     private bool hasCount;
     private long count_;
@@ -1282,13 +1282,13 @@ namespace math {
     public long Count {
       get { return count_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _fibReplyFieldNames;
@@ -1297,13 +1297,13 @@ namespace math {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasCount) {
           size += pb::CodedOutputStream.ComputeInt64Size(1, Count);
@@ -1313,7 +1313,7 @@ namespace math {
         return size;
       }
     }
-    
+
     public static FibReply ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -1347,14 +1347,14 @@ namespace math {
     private FibReply MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(FibReply prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<FibReply, Builder> {
       protected override Builder ThisBuilder {
@@ -1368,10 +1368,10 @@ namespace math {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private FibReply result;
-      
+
       private FibReply PrepareBuilder() {
         if (resultIsReadOnly) {
           FibReply original = result;
@@ -1381,21 +1381,21 @@ namespace math {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override FibReply MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -1403,15 +1403,15 @@ namespace math {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::math.FibReply.Descriptor; }
       }
-      
+
       public override FibReply DefaultInstanceForType {
         get { return global::math.FibReply.DefaultInstance; }
       }
-      
+
       public override FibReply BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -1419,7 +1419,7 @@ namespace math {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is FibReply) {
           return MergeFrom((FibReply) other);
@@ -1428,7 +1428,7 @@ namespace math {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(FibReply other) {
         if (other == global::math.FibReply.DefaultInstance) return this;
         PrepareBuilder();
@@ -1438,11 +1438,11 @@ namespace math {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -1484,14 +1484,14 @@ namespace math {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasCount {
         get { return result.hasCount; }
       }
@@ -1516,16 +1516,16 @@ namespace math {
       object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
     }
   }
-  
+
   #endregion
-  
+
   #region Services
   /*
   * Service generation is now disabled by default, use the following option to enable:
   * option (google.protobuf.csharp_file_options).service_generator_type = GENERIC;
   */
   #endregion
-  
+
 }
 
 #endregion Designer generated code
diff --git a/src/csharp/GrpcApi/MathExamples.cs b/src/csharp/GrpcApi/MathExamples.cs
index 07bcc9c9cd48185b354c643aebaaac4901865ef4..97c91b1b1b586248b03e4d94200e7a9629627fef 100644
--- a/src/csharp/GrpcApi/MathExamples.cs
+++ b/src/csharp/GrpcApi/MathExamples.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,10 +32,10 @@
 #endregion
 
 using System;
-using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Reactive.Linq;
-using Google.GRPC.Core.Utils;
+using System.Threading.Tasks;
+using Grpc.Core.Utils;
 
 namespace math
 {
@@ -72,10 +72,10 @@ namespace math
 
 		public static void SumExample(MathGrpc.IMathServiceClient stub)
 		{
-			List<Num> numbers = new List<Num>{new Num.Builder { Num_ = 1 }.Build(), 
+			List<Num> numbers = new List<Num>{new Num.Builder { Num_ = 1 }.Build(),
 				new Num.Builder { Num_ = 2 }.Build(),
 				new Num.Builder { Num_ = 3 }.Build()};
-			
+
             var res = stub.Sum();
             foreach (var num in numbers) {
                 res.Inputs.OnNext(num);
@@ -94,7 +94,7 @@ namespace math
 			};
 
             var recorder = new RecordingObserver<DivReply>();
-			
+
             var inputs = stub.DivMany(recorder);
             foreach (var input in divArgsList)
             {
@@ -108,14 +108,14 @@ namespace math
 		public static void DependendRequestsExample(MathGrpc.IMathServiceClient stub)
 		{
 			var numberList = new List<Num>
-			{ new Num.Builder{ Num_ = 1 }.Build(), 
+			{ new Num.Builder{ Num_ = 1 }.Build(),
 				new Num.Builder{ Num_ = 2 }.Build(), new Num.Builder{ Num_ = 3 }.Build()
 			};
 
 			numberList.ToObservable();
 
 			//IObserver<Num> numbers;
-			//Task<Num> call = stub.Sum(out numbers);            
+			//Task<Num> call = stub.Sum(out numbers);
 			//foreach (var num in numberList)
 			//{
 			//	numbers.OnNext(num);
diff --git a/src/csharp/GrpcApi/MathGrpc.cs b/src/csharp/GrpcApi/MathGrpc.cs
index 606e7f023903de78d6e1e80260968e749c591f5a..f938a245439b9bb04222c1c86ded99ab0b820d11 100644
--- a/src/csharp/GrpcApi/MathGrpc.cs
+++ b/src/csharp/GrpcApi/MathGrpc.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,11 +32,11 @@
 #endregion
 
 using System;
-using System.Threading;
-using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Reactive.Linq;
-using Google.GRPC.Core;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
 
 namespace math
 {
@@ -81,7 +81,7 @@ namespace math
 
             Task<DivReply> DivAsync(DivArgs request, CancellationToken token = default(CancellationToken));
 
-            Task Fib(FibArgs request, IObserver<Num> responseObserver, CancellationToken token = default(CancellationToken));
+            void Fib(FibArgs request, IObserver<Num> responseObserver, CancellationToken token = default(CancellationToken));
 
             ClientStreamingAsyncResult<Num, Num> Sum(CancellationToken token = default(CancellationToken));
 
@@ -99,31 +99,31 @@ namespace math
 
             public DivReply Div(DivArgs request, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<DivArgs, DivReply>(divMethod, channel);
+                var call = new Grpc.Core.Call<DivArgs, DivReply>(divMethod, channel);
                 return Calls.BlockingUnaryCall(call, request, token);
             }
 
             public Task<DivReply> DivAsync(DivArgs request, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<DivArgs, DivReply>(divMethod, channel);
+                var call = new Grpc.Core.Call<DivArgs, DivReply>(divMethod, channel);
                 return Calls.AsyncUnaryCall(call, request, token);
             }
 
-            public Task Fib(FibArgs request, IObserver<Num> responseObserver, CancellationToken token = default(CancellationToken))
+            public void Fib(FibArgs request, IObserver<Num> responseObserver, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<FibArgs, Num>(fibMethod, channel);
-                return Calls.AsyncServerStreamingCall(call, request, responseObserver, token);
+                var call = new Grpc.Core.Call<FibArgs, Num>(fibMethod, channel);
+                Calls.AsyncServerStreamingCall(call, request, responseObserver, token);
             }
 
             public ClientStreamingAsyncResult<Num, Num> Sum(CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<Num, Num>(sumMethod, channel);
+                var call = new Grpc.Core.Call<Num, Num>(sumMethod, channel);
                 return Calls.AsyncClientStreamingCall(call, token);
             }
 
             public IObserver<DivArgs> DivMany(IObserver<DivReply> responseObserver, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<DivArgs, DivReply>(divManyMethod, channel);
+                var call = new Grpc.Core.Call<DivArgs, DivReply>(divManyMethod, channel);
                 return Calls.DuplexStreamingCall(call, responseObserver, token);
             }
         }
@@ -154,4 +154,4 @@ namespace math
             return new MathServiceClientStub(channel);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/GrpcApi/MathServiceImpl.cs b/src/csharp/GrpcApi/MathServiceImpl.cs
index ffd794d6c6bfeba9f7e936c15ebb1807bffcdf3a..462fab4454fdf6f25b75ab8ad976fea82687e91b 100644
--- a/src/csharp/GrpcApi/MathServiceImpl.cs
+++ b/src/csharp/GrpcApi/MathServiceImpl.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,11 +32,11 @@
 #endregion
 
 using System;
-using System.Threading;
-using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Reactive.Linq;
-using Google.GRPC.Core.Utils;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core.Utils;
 
 namespace math
 {
@@ -59,7 +59,7 @@ namespace math
                 // TODO: support cancellation....
                 throw new NotImplementedException("Not implemented yet");
             }
-                                  
+
             if (request.Limit > 0)
             {
                 foreach (var num in FibInternal(request.Limit))
@@ -124,7 +124,7 @@ namespace math
             {
                 this.responseObserver = responseObserver;
             }
-            
+
             public void OnCompleted()
             {
                 Task.Factory.StartNew(() =>
@@ -143,7 +143,7 @@ namespace math
                 // callback is called from grpc threadpool which
                 // currently only has one thread.
                 // Same story for OnCompleted().
-                Task.Factory.StartNew(() => 
+                Task.Factory.StartNew(() =>
                 responseObserver.OnNext(DivInternal(value)));
             }
         }
diff --git a/src/csharp/GrpcApi/Messages.cs b/src/csharp/GrpcApi/Messages.cs
index 78e3404d226e52e812dde9b5119027c2cfddc675..386f377f08b099b386a0303d5469a2fea41af137 100644
--- a/src/csharp/GrpcApi/Messages.cs
+++ b/src/csharp/GrpcApi/Messages.cs
@@ -7,10 +7,10 @@ using pbc = global::Google.ProtocolBuffers.Collections;
 using pbd = global::Google.ProtocolBuffers.Descriptors;
 using scg = global::System.Collections.Generic;
 namespace grpc.testing {
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class Messages {
-  
+
     #region Extension registration
     public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
     }
@@ -38,62 +38,62 @@ namespace grpc.testing {
       get { return descriptor; }
     }
     private static pbd::FileDescriptor descriptor;
-    
+
     static Messages() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "Cg5tZXNzYWdlcy5wcm90bxIMZ3JwYy50ZXN0aW5nIkAKB1BheWxvYWQSJwoE", 
-            "dHlwZRgBIAEoDjIZLmdycGMudGVzdGluZy5QYXlsb2FkVHlwZRIMCgRib2R5", 
-            "GAIgASgMIrEBCg1TaW1wbGVSZXF1ZXN0EjAKDXJlc3BvbnNlX3R5cGUYASAB", 
-            "KA4yGS5ncnBjLnRlc3RpbmcuUGF5bG9hZFR5cGUSFQoNcmVzcG9uc2Vfc2l6", 
-            "ZRgCIAEoBRImCgdwYXlsb2FkGAMgASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxv", 
-            "YWQSFQoNZmlsbF91c2VybmFtZRgEIAEoCBIYChBmaWxsX29hdXRoX3Njb3Bl", 
-            "GAUgASgIIl8KDlNpbXBsZVJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5n", 
-            "cnBjLnRlc3RpbmcuUGF5bG9hZBIQCgh1c2VybmFtZRgCIAEoCRITCgtvYXV0", 
-            "aF9zY29wZRgDIAEoCSJDChlTdHJlYW1pbmdJbnB1dENhbGxSZXF1ZXN0EiYK", 
-            "B3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3RpbmcuUGF5bG9hZCI9ChpTdHJl", 
-            "YW1pbmdJbnB1dENhbGxSZXNwb25zZRIfChdhZ2dyZWdhdGVkX3BheWxvYWRf", 
-            "c2l6ZRgBIAEoBSI3ChJSZXNwb25zZVBhcmFtZXRlcnMSDAoEc2l6ZRgBIAEo", 
-            "BRITCgtpbnRlcnZhbF91cxgCIAEoBSK1AQoaU3RyZWFtaW5nT3V0cHV0Q2Fs", 
-            "bFJlcXVlc3QSMAoNcmVzcG9uc2VfdHlwZRgBIAEoDjIZLmdycGMudGVzdGlu", 
-            "Zy5QYXlsb2FkVHlwZRI9ChNyZXNwb25zZV9wYXJhbWV0ZXJzGAIgAygLMiAu", 
-            "Z3JwYy50ZXN0aW5nLlJlc3BvbnNlUGFyYW1ldGVycxImCgdwYXlsb2FkGAMg", 
-            "ASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxvYWQiRQobU3RyZWFtaW5nT3V0cHV0", 
-            "Q2FsbFJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3Rpbmcu", 
-            "UGF5bG9hZCo/CgtQYXlsb2FkVHlwZRIQCgxDT01QUkVTU0FCTEUQABISCg5V", 
+            "Cg5tZXNzYWdlcy5wcm90bxIMZ3JwYy50ZXN0aW5nIkAKB1BheWxvYWQSJwoE",
+            "dHlwZRgBIAEoDjIZLmdycGMudGVzdGluZy5QYXlsb2FkVHlwZRIMCgRib2R5",
+            "GAIgASgMIrEBCg1TaW1wbGVSZXF1ZXN0EjAKDXJlc3BvbnNlX3R5cGUYASAB",
+            "KA4yGS5ncnBjLnRlc3RpbmcuUGF5bG9hZFR5cGUSFQoNcmVzcG9uc2Vfc2l6",
+            "ZRgCIAEoBRImCgdwYXlsb2FkGAMgASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxv",
+            "YWQSFQoNZmlsbF91c2VybmFtZRgEIAEoCBIYChBmaWxsX29hdXRoX3Njb3Bl",
+            "GAUgASgIIl8KDlNpbXBsZVJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5n",
+            "cnBjLnRlc3RpbmcuUGF5bG9hZBIQCgh1c2VybmFtZRgCIAEoCRITCgtvYXV0",
+            "aF9zY29wZRgDIAEoCSJDChlTdHJlYW1pbmdJbnB1dENhbGxSZXF1ZXN0EiYK",
+            "B3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3RpbmcuUGF5bG9hZCI9ChpTdHJl",
+            "YW1pbmdJbnB1dENhbGxSZXNwb25zZRIfChdhZ2dyZWdhdGVkX3BheWxvYWRf",
+            "c2l6ZRgBIAEoBSI3ChJSZXNwb25zZVBhcmFtZXRlcnMSDAoEc2l6ZRgBIAEo",
+            "BRITCgtpbnRlcnZhbF91cxgCIAEoBSK1AQoaU3RyZWFtaW5nT3V0cHV0Q2Fs",
+            "bFJlcXVlc3QSMAoNcmVzcG9uc2VfdHlwZRgBIAEoDjIZLmdycGMudGVzdGlu",
+            "Zy5QYXlsb2FkVHlwZRI9ChNyZXNwb25zZV9wYXJhbWV0ZXJzGAIgAygLMiAu",
+            "Z3JwYy50ZXN0aW5nLlJlc3BvbnNlUGFyYW1ldGVycxImCgdwYXlsb2FkGAMg",
+            "ASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxvYWQiRQobU3RyZWFtaW5nT3V0cHV0",
+            "Q2FsbFJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3Rpbmcu",
+            "UGF5bG9hZCo/CgtQYXlsb2FkVHlwZRIQCgxDT01QUkVTU0FCTEUQABISCg5V",
           "TkNPTVBSRVNTQUJMRRABEgoKBlJBTkRPTRAC"));
       pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
         descriptor = root;
         internal__static_grpc_testing_Payload__Descriptor = Descriptor.MessageTypes[0];
-        internal__static_grpc_testing_Payload__FieldAccessorTable = 
+        internal__static_grpc_testing_Payload__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Payload, global::grpc.testing.Payload.Builder>(internal__static_grpc_testing_Payload__Descriptor,
                 new string[] { "Type", "Body", });
         internal__static_grpc_testing_SimpleRequest__Descriptor = Descriptor.MessageTypes[1];
-        internal__static_grpc_testing_SimpleRequest__FieldAccessorTable = 
+        internal__static_grpc_testing_SimpleRequest__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleRequest.Builder>(internal__static_grpc_testing_SimpleRequest__Descriptor,
                 new string[] { "ResponseType", "ResponseSize", "Payload", "FillUsername", "FillOauthScope", });
         internal__static_grpc_testing_SimpleResponse__Descriptor = Descriptor.MessageTypes[2];
-        internal__static_grpc_testing_SimpleResponse__FieldAccessorTable = 
+        internal__static_grpc_testing_SimpleResponse__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.SimpleResponse, global::grpc.testing.SimpleResponse.Builder>(internal__static_grpc_testing_SimpleResponse__Descriptor,
                 new string[] { "Payload", "Username", "OauthScope", });
         internal__static_grpc_testing_StreamingInputCallRequest__Descriptor = Descriptor.MessageTypes[3];
-        internal__static_grpc_testing_StreamingInputCallRequest__FieldAccessorTable = 
+        internal__static_grpc_testing_StreamingInputCallRequest__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallRequest.Builder>(internal__static_grpc_testing_StreamingInputCallRequest__Descriptor,
                 new string[] { "Payload", });
         internal__static_grpc_testing_StreamingInputCallResponse__Descriptor = Descriptor.MessageTypes[4];
-        internal__static_grpc_testing_StreamingInputCallResponse__FieldAccessorTable = 
+        internal__static_grpc_testing_StreamingInputCallResponse__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingInputCallResponse, global::grpc.testing.StreamingInputCallResponse.Builder>(internal__static_grpc_testing_StreamingInputCallResponse__Descriptor,
                 new string[] { "AggregatedPayloadSize", });
         internal__static_grpc_testing_ResponseParameters__Descriptor = Descriptor.MessageTypes[5];
-        internal__static_grpc_testing_ResponseParameters__FieldAccessorTable = 
+        internal__static_grpc_testing_ResponseParameters__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.ResponseParameters, global::grpc.testing.ResponseParameters.Builder>(internal__static_grpc_testing_ResponseParameters__Descriptor,
                 new string[] { "Size", "IntervalUs", });
         internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor = Descriptor.MessageTypes[6];
-        internal__static_grpc_testing_StreamingOutputCallRequest__FieldAccessorTable = 
+        internal__static_grpc_testing_StreamingOutputCallRequest__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallRequest.Builder>(internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor,
                 new string[] { "ResponseType", "ResponseParameters", "Payload", });
         internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor = Descriptor.MessageTypes[7];
-        internal__static_grpc_testing_StreamingOutputCallResponse__FieldAccessorTable = 
+        internal__static_grpc_testing_StreamingOutputCallResponse__FieldAccessorTable =
             new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingOutputCallResponse, global::grpc.testing.StreamingOutputCallResponse.Builder>(internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor,
                 new string[] { "Payload", });
         return null;
@@ -103,7 +103,7 @@ namespace grpc.testing {
           }, assigner);
     }
     #endregion
-    
+
   }
   #region Enums
   public enum PayloadType {
@@ -111,9 +111,9 @@ namespace grpc.testing {
     UNCOMPRESSABLE = 1,
     RANDOM = 2,
   }
-  
+
   #endregion
-  
+
   #region Messages
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Payload : pb::GeneratedMessage<Payload, Payload.Builder> {
@@ -124,23 +124,23 @@ namespace grpc.testing {
     public static Payload DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override Payload DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override Payload ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_Payload__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<Payload, Payload.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_Payload__FieldAccessorTable; }
     }
-    
+
     public const int TypeFieldNumber = 1;
     private bool hasType;
     private global::grpc.testing.PayloadType type_ = global::grpc.testing.PayloadType.COMPRESSABLE;
@@ -150,7 +150,7 @@ namespace grpc.testing {
     public global::grpc.testing.PayloadType Type {
       get { return type_; }
     }
-    
+
     public const int BodyFieldNumber = 2;
     private bool hasBody;
     private pb::ByteString body_ = pb::ByteString.Empty;
@@ -160,13 +160,13 @@ namespace grpc.testing {
     public pb::ByteString Body {
       get { return body_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _payloadFieldNames;
@@ -178,13 +178,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasType) {
           size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Type);
@@ -197,7 +197,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static Payload ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -231,14 +231,14 @@ namespace grpc.testing {
     private Payload MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(Payload prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<Payload, Builder> {
       protected override Builder ThisBuilder {
@@ -252,10 +252,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private Payload result;
-      
+
       private Payload PrepareBuilder() {
         if (resultIsReadOnly) {
           Payload original = result;
@@ -265,21 +265,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override Payload MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -287,15 +287,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.Payload.Descriptor; }
       }
-      
+
       public override Payload DefaultInstanceForType {
         get { return global::grpc.testing.Payload.DefaultInstance; }
       }
-      
+
       public override Payload BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -303,7 +303,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is Payload) {
           return MergeFrom((Payload) other);
@@ -312,7 +312,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(Payload other) {
         if (other == global::grpc.testing.Payload.DefaultInstance) return this;
         PrepareBuilder();
@@ -325,11 +325,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -383,14 +383,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasType {
        get { return result.hasType; }
       }
@@ -410,7 +410,7 @@ namespace grpc.testing {
         result.type_ = global::grpc.testing.PayloadType.COMPRESSABLE;
         return this;
       }
-      
+
       public bool HasBody {
         get { return result.hasBody; }
       }
@@ -436,7 +436,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SimpleRequest : pb::GeneratedMessage<SimpleRequest, SimpleRequest.Builder> {
     private SimpleRequest() { }
@@ -446,23 +446,23 @@ namespace grpc.testing {
     public static SimpleRequest DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override SimpleRequest DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override SimpleRequest ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleRequest__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<SimpleRequest, SimpleRequest.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleRequest__FieldAccessorTable; }
     }
-    
+
     public const int ResponseTypeFieldNumber = 1;
     private bool hasResponseType;
     private global::grpc.testing.PayloadType responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
@@ -472,7 +472,7 @@ namespace grpc.testing {
     public global::grpc.testing.PayloadType ResponseType {
       get { return responseType_; }
     }
-    
+
     public const int ResponseSizeFieldNumber = 2;
     private bool hasResponseSize;
     private int responseSize_;
@@ -482,7 +482,7 @@ namespace grpc.testing {
     public int ResponseSize {
       get { return responseSize_; }
     }
-    
+
     public const int PayloadFieldNumber = 3;
     private bool hasPayload;
     private global::grpc.testing.Payload payload_;
@@ -492,7 +492,7 @@ namespace grpc.testing {
     public global::grpc.testing.Payload Payload {
       get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
     }
-    
+
     public const int FillUsernameFieldNumber = 4;
     private bool hasFillUsername;
     private bool fillUsername_;
@@ -502,7 +502,7 @@ namespace grpc.testing {
     public bool FillUsername {
       get { return fillUsername_; }
     }
-    
+
     public const int FillOauthScopeFieldNumber = 5;
     private bool hasFillOauthScope;
     private bool fillOauthScope_;
@@ -512,13 +512,13 @@ namespace grpc.testing {
     public bool FillOauthScope {
       get { return fillOauthScope_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _simpleRequestFieldNames;
@@ -539,13 +539,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasResponseType) {
           size += pb::CodedOutputStream.ComputeEnumSize(1, (int) ResponseType);
@@ -567,7 +567,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static SimpleRequest ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -601,14 +601,14 @@ namespace grpc.testing {
     private SimpleRequest MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(SimpleRequest prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<SimpleRequest, Builder> {
       protected override Builder ThisBuilder {
@@ -622,10 +622,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private SimpleRequest result;
-      
+
       private SimpleRequest PrepareBuilder() {
         if (resultIsReadOnly) {
           SimpleRequest original = result;
@@ -635,21 +635,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override SimpleRequest MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -657,15 +657,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.SimpleRequest.Descriptor; }
       }
-      
+
       public override SimpleRequest DefaultInstanceForType {
         get { return global::grpc.testing.SimpleRequest.DefaultInstance; }
       }
-      
+
       public override SimpleRequest BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -673,7 +673,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is SimpleRequest) {
           return MergeFrom((SimpleRequest) other);
@@ -682,7 +682,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(SimpleRequest other) {
         if (other == global::grpc.testing.SimpleRequest.DefaultInstance) return this;
         PrepareBuilder();
@@ -704,11 +704,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -779,14 +779,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasResponseType {
        get { return result.hasResponseType; }
       }
@@ -806,7 +806,7 @@ namespace grpc.testing {
         result.responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
         return this;
       }
-      
+
       public bool HasResponseSize {
         get { return result.hasResponseSize; }
       }
@@ -826,7 +826,7 @@ namespace grpc.testing {
         result.responseSize_ = 0;
         return this;
       }
-      
+
       public bool HasPayload {
        get { return result.hasPayload; }
       }
@@ -866,7 +866,7 @@ namespace grpc.testing {
         result.payload_ = null;
         return this;
       }
-      
+
       public bool HasFillUsername {
         get { return result.hasFillUsername; }
       }
@@ -886,7 +886,7 @@ namespace grpc.testing {
         result.fillUsername_ = false;
         return this;
       }
-      
+
       public bool HasFillOauthScope {
         get { return result.hasFillOauthScope; }
       }
@@ -911,7 +911,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SimpleResponse : pb::GeneratedMessage<SimpleResponse, SimpleResponse.Builder> {
     private SimpleResponse() { }
@@ -921,23 +921,23 @@ namespace grpc.testing {
     public static SimpleResponse DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override SimpleResponse DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override SimpleResponse ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleResponse__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<SimpleResponse, SimpleResponse.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleResponse__FieldAccessorTable; }
     }
-    
+
     public const int PayloadFieldNumber = 1;
     private bool hasPayload;
     private global::grpc.testing.Payload payload_;
@@ -947,7 +947,7 @@ namespace grpc.testing {
     public global::grpc.testing.Payload Payload {
       get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
     }
-    
+
     public const int UsernameFieldNumber = 2;
     private bool hasUsername;
     private string username_ = "";
@@ -957,7 +957,7 @@ namespace grpc.testing {
     public string Username {
       get { return username_; }
     }
-    
+
     public const int OauthScopeFieldNumber = 3;
     private bool hasOauthScope;
     private string oauthScope_ = "";
@@ -967,13 +967,13 @@ namespace grpc.testing {
     public string OauthScope {
       get { return oauthScope_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _simpleResponseFieldNames;
@@ -988,13 +988,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasPayload) {
           size += pb::CodedOutputStream.ComputeMessageSize(1, Payload);
@@ -1010,7 +1010,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static SimpleResponse ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -1044,14 +1044,14 @@ namespace grpc.testing {
     private SimpleResponse MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(SimpleResponse prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<SimpleResponse, Builder> {
       protected override Builder ThisBuilder {
@@ -1065,10 +1065,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private SimpleResponse result;
-      
+
       private SimpleResponse PrepareBuilder() {
         if (resultIsReadOnly) {
           SimpleResponse original = result;
@@ -1078,21 +1078,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override SimpleResponse MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -1100,15 +1100,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.SimpleResponse.Descriptor; }
       }
-      
+
       public override SimpleResponse DefaultInstanceForType {
         get { return global::grpc.testing.SimpleResponse.DefaultInstance; }
       }
-      
+
       public override SimpleResponse BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -1116,7 +1116,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is SimpleResponse) {
           return MergeFrom((SimpleResponse) other);
@@ -1125,7 +1125,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(SimpleResponse other) {
         if (other == global::grpc.testing.SimpleResponse.DefaultInstance) return this;
         PrepareBuilder();
@@ -1141,11 +1141,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -1200,14 +1200,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasPayload {
        get { return result.hasPayload; }
       }
@@ -1247,7 +1247,7 @@ namespace grpc.testing {
         result.payload_ = null;
         return this;
       }
-      
+
       public bool HasUsername {
         get { return result.hasUsername; }
       }
@@ -1268,7 +1268,7 @@ namespace grpc.testing {
         result.username_ = "";
         return this;
       }
-      
+
       public bool HasOauthScope {
         get { return result.hasOauthScope; }
       }
@@ -1294,7 +1294,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingInputCallRequest : pb::GeneratedMessage<StreamingInputCallRequest, StreamingInputCallRequest.Builder> {
     private StreamingInputCallRequest() { }
@@ -1304,23 +1304,23 @@ namespace grpc.testing {
     public static StreamingInputCallRequest DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override StreamingInputCallRequest DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override StreamingInputCallRequest ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallRequest__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<StreamingInputCallRequest, StreamingInputCallRequest.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallRequest__FieldAccessorTable; }
     }
-    
+
     public const int PayloadFieldNumber = 1;
     private bool hasPayload;
     private global::grpc.testing.Payload payload_;
@@ -1330,13 +1330,13 @@ namespace grpc.testing {
     public global::grpc.testing.Payload Payload {
       get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _streamingInputCallRequestFieldNames;
@@ -1345,13 +1345,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasPayload) {
           size += pb::CodedOutputStream.ComputeMessageSize(1, Payload);
@@ -1361,7 +1361,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static StreamingInputCallRequest ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -1395,14 +1395,14 @@ namespace grpc.testing {
     private StreamingInputCallRequest MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(StreamingInputCallRequest prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<StreamingInputCallRequest, Builder> {
       protected override Builder ThisBuilder {
@@ -1416,10 +1416,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private StreamingInputCallRequest result;
-      
+
       private StreamingInputCallRequest PrepareBuilder() {
         if (resultIsReadOnly) {
           StreamingInputCallRequest original = result;
@@ -1429,21 +1429,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override StreamingInputCallRequest MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -1451,15 +1451,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.StreamingInputCallRequest.Descriptor; }
       }
-      
+
       public override StreamingInputCallRequest DefaultInstanceForType {
         get { return global::grpc.testing.StreamingInputCallRequest.DefaultInstance; }
       }
-      
+
       public override StreamingInputCallRequest BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -1467,7 +1467,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is StreamingInputCallRequest) {
           return MergeFrom((StreamingInputCallRequest) other);
@@ -1476,7 +1476,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(StreamingInputCallRequest other) {
         if (other == global::grpc.testing.StreamingInputCallRequest.DefaultInstance) return this;
         PrepareBuilder();
@@ -1486,11 +1486,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -1537,14 +1537,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasPayload {
        get { return result.hasPayload; }
       }
@@ -1589,7 +1589,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingInputCallResponse : pb::GeneratedMessage<StreamingInputCallResponse, StreamingInputCallResponse.Builder> {
     private StreamingInputCallResponse() { }
@@ -1599,23 +1599,23 @@ namespace grpc.testing {
     public static StreamingInputCallResponse DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override StreamingInputCallResponse DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override StreamingInputCallResponse ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallResponse__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<StreamingInputCallResponse, StreamingInputCallResponse.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallResponse__FieldAccessorTable; }
     }
-    
+
     public const int AggregatedPayloadSizeFieldNumber = 1;
     private bool hasAggregatedPayloadSize;
     private int aggregatedPayloadSize_;
@@ -1625,13 +1625,13 @@ namespace grpc.testing {
     public int AggregatedPayloadSize {
       get { return aggregatedPayloadSize_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _streamingInputCallResponseFieldNames;
@@ -1640,13 +1640,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasAggregatedPayloadSize) {
           size += pb::CodedOutputStream.ComputeInt32Size(1, AggregatedPayloadSize);
@@ -1656,7 +1656,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static StreamingInputCallResponse ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -1690,14 +1690,14 @@ namespace grpc.testing {
     private StreamingInputCallResponse MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(StreamingInputCallResponse prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<StreamingInputCallResponse, Builder> {
       protected override Builder ThisBuilder {
@@ -1711,10 +1711,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private StreamingInputCallResponse result;
-      
+
       private StreamingInputCallResponse PrepareBuilder() {
         if (resultIsReadOnly) {
           StreamingInputCallResponse original = result;
@@ -1724,21 +1724,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override StreamingInputCallResponse MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -1746,15 +1746,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.StreamingInputCallResponse.Descriptor; }
       }
-      
+
       public override StreamingInputCallResponse DefaultInstanceForType {
         get { return global::grpc.testing.StreamingInputCallResponse.DefaultInstance; }
       }
-      
+
       public override StreamingInputCallResponse BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -1762,7 +1762,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is StreamingInputCallResponse) {
           return MergeFrom((StreamingInputCallResponse) other);
@@ -1771,7 +1771,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(StreamingInputCallResponse other) {
         if (other == global::grpc.testing.StreamingInputCallResponse.DefaultInstance) return this;
         PrepareBuilder();
@@ -1781,11 +1781,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -1827,14 +1827,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasAggregatedPayloadSize {
         get { return result.hasAggregatedPayloadSize; }
       }
@@ -1859,7 +1859,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ResponseParameters : pb::GeneratedMessage<ResponseParameters, ResponseParameters.Builder> {
     private ResponseParameters() { }
@@ -1869,23 +1869,23 @@ namespace grpc.testing {
     public static ResponseParameters DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override ResponseParameters DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override ResponseParameters ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_ResponseParameters__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<ResponseParameters, ResponseParameters.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_ResponseParameters__FieldAccessorTable; }
     }
-    
+
     public const int SizeFieldNumber = 1;
     private bool hasSize;
     private int size_;
@@ -1895,7 +1895,7 @@ namespace grpc.testing {
     public int Size {
       get { return size_; }
     }
-    
+
     public const int IntervalUsFieldNumber = 2;
     private bool hasIntervalUs;
     private int intervalUs_;
@@ -1905,13 +1905,13 @@ namespace grpc.testing {
     public int IntervalUs {
       get { return intervalUs_; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _responseParametersFieldNames;
@@ -1923,13 +1923,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasSize) {
           size += pb::CodedOutputStream.ComputeInt32Size(1, Size);
@@ -1942,7 +1942,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static ResponseParameters ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -1976,14 +1976,14 @@ namespace grpc.testing {
     private ResponseParameters MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(ResponseParameters prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<ResponseParameters, Builder> {
       protected override Builder ThisBuilder {
@@ -1997,10 +1997,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private ResponseParameters result;
-      
+
       private ResponseParameters PrepareBuilder() {
         if (resultIsReadOnly) {
           ResponseParameters original = result;
@@ -2010,21 +2010,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override ResponseParameters MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -2032,15 +2032,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.ResponseParameters.Descriptor; }
       }
-      
+
       public override ResponseParameters DefaultInstanceForType {
         get { return global::grpc.testing.ResponseParameters.DefaultInstance; }
       }
-      
+
       public override ResponseParameters BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -2048,7 +2048,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is ResponseParameters) {
           return MergeFrom((ResponseParameters) other);
@@ -2057,7 +2057,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(ResponseParameters other) {
         if (other == global::grpc.testing.ResponseParameters.DefaultInstance) return this;
         PrepareBuilder();
@@ -2070,11 +2070,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -2120,14 +2120,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasSize {
         get { return result.hasSize; }
       }
@@ -2147,7 +2147,7 @@ namespace grpc.testing {
         result.size_ = 0;
         return this;
       }
-      
+
       public bool HasIntervalUs {
         get { return result.hasIntervalUs; }
       }
@@ -2172,7 +2172,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingOutputCallRequest : pb::GeneratedMessage<StreamingOutputCallRequest, StreamingOutputCallRequest.Builder> {
     private StreamingOutputCallRequest() { }
@@ -2182,23 +2182,23 @@ namespace grpc.testing {
     public static StreamingOutputCallRequest DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override StreamingOutputCallRequest DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override StreamingOutputCallRequest ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<StreamingOutputCallRequest, StreamingOutputCallRequest.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallRequest__FieldAccessorTable; }
     }
-    
+
     public const int ResponseTypeFieldNumber = 1;
     private bool hasResponseType;
     private global::grpc.testing.PayloadType responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
@@ -2208,7 +2208,7 @@ namespace grpc.testing {
     public global::grpc.testing.PayloadType ResponseType {
       get { return responseType_; }
     }
-    
+
     public const int ResponseParametersFieldNumber = 2;
     private pbc::PopsicleList<global::grpc.testing.ResponseParameters> responseParameters_ = new pbc::PopsicleList<global::grpc.testing.ResponseParameters>();
     public scg::IList<global::grpc.testing.ResponseParameters> ResponseParametersList {
@@ -2220,7 +2220,7 @@ namespace grpc.testing {
     public global::grpc.testing.ResponseParameters GetResponseParameters(int index) {
       return responseParameters_[index];
     }
-    
+
     public const int PayloadFieldNumber = 3;
     private bool hasPayload;
     private global::grpc.testing.Payload payload_;
@@ -2230,13 +2230,13 @@ namespace grpc.testing {
     public global::grpc.testing.Payload Payload {
       get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _streamingOutputCallRequestFieldNames;
@@ -2251,13 +2251,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasResponseType) {
           size += pb::CodedOutputStream.ComputeEnumSize(1, (int) ResponseType);
@@ -2273,7 +2273,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static StreamingOutputCallRequest ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -2308,14 +2308,14 @@ namespace grpc.testing {
       responseParameters_.MakeReadOnly();
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(StreamingOutputCallRequest prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<StreamingOutputCallRequest, Builder> {
       protected override Builder ThisBuilder {
@@ -2329,10 +2329,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private StreamingOutputCallRequest result;
-      
+
       private StreamingOutputCallRequest PrepareBuilder() {
         if (resultIsReadOnly) {
           StreamingOutputCallRequest original = result;
@@ -2342,21 +2342,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override StreamingOutputCallRequest MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -2364,15 +2364,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.StreamingOutputCallRequest.Descriptor; }
       }
-      
+
       public override StreamingOutputCallRequest DefaultInstanceForType {
         get { return global::grpc.testing.StreamingOutputCallRequest.DefaultInstance; }
       }
-      
+
       public override StreamingOutputCallRequest BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -2380,7 +2380,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is StreamingOutputCallRequest) {
           return MergeFrom((StreamingOutputCallRequest) other);
@@ -2389,7 +2389,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(StreamingOutputCallRequest other) {
         if (other == global::grpc.testing.StreamingOutputCallRequest.DefaultInstance) return this;
         PrepareBuilder();
@@ -2405,11 +2405,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -2472,14 +2472,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasResponseType {
        get { return result.hasResponseType; }
       }
@@ -2499,7 +2499,7 @@ namespace grpc.testing {
         result.responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
         return this;
       }
-      
+
       public pbc::IPopsicleList<global::grpc.testing.ResponseParameters> ResponseParametersList {
         get { return PrepareBuilder().responseParameters_; }
       }
@@ -2543,7 +2543,7 @@ namespace grpc.testing {
         result.responseParameters_.Clear();
         return this;
       }
-      
+
       public bool HasPayload {
        get { return result.hasPayload; }
       }
@@ -2588,7 +2588,7 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingOutputCallResponse : pb::GeneratedMessage<StreamingOutputCallResponse, StreamingOutputCallResponse.Builder> {
     private StreamingOutputCallResponse() { }
@@ -2598,23 +2598,23 @@ namespace grpc.testing {
     public static StreamingOutputCallResponse DefaultInstance {
       get { return defaultInstance; }
     }
-    
+
     public override StreamingOutputCallResponse DefaultInstanceForType {
       get { return DefaultInstance; }
     }
-    
+
     protected override StreamingOutputCallResponse ThisMessage {
       get { return this; }
     }
-    
+
     public static pbd::MessageDescriptor Descriptor {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor; }
     }
-    
+
     protected override pb::FieldAccess.FieldAccessorTable<StreamingOutputCallResponse, StreamingOutputCallResponse.Builder> InternalFieldAccessors {
       get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallResponse__FieldAccessorTable; }
     }
-    
+
     public const int PayloadFieldNumber = 1;
     private bool hasPayload;
     private global::grpc.testing.Payload payload_;
@@ -2624,13 +2624,13 @@ namespace grpc.testing {
     public global::grpc.testing.Payload Payload {
       get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
     }
-    
+
     public override bool IsInitialized {
       get {
         return true;
       }
     }
-    
+
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
       string[] field_names = _streamingOutputCallResponseFieldNames;
@@ -2639,13 +2639,13 @@ namespace grpc.testing {
       }
       UnknownFields.WriteTo(output);
     }
-    
+
     private int memoizedSerializedSize = -1;
     public override int SerializedSize {
       get {
         int size = memoizedSerializedSize;
         if (size != -1) return size;
-        
+
         size = 0;
         if (hasPayload) {
           size += pb::CodedOutputStream.ComputeMessageSize(1, Payload);
@@ -2655,7 +2655,7 @@ namespace grpc.testing {
         return size;
       }
     }
-    
+
     public static StreamingOutputCallResponse ParseFrom(pb::ByteString data) {
       return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
     }
@@ -2689,14 +2689,14 @@ namespace grpc.testing {
     private StreamingOutputCallResponse MakeReadOnly() {
       return this;
     }
-    
+
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(StreamingOutputCallResponse prototype) {
       return new Builder(prototype);
     }
-    
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public sealed partial class Builder : pb::GeneratedBuilder<StreamingOutputCallResponse, Builder> {
       protected override Builder ThisBuilder {
@@ -2710,10 +2710,10 @@ namespace grpc.testing {
         result = cloneFrom;
         resultIsReadOnly = true;
       }
-      
+
       private bool resultIsReadOnly;
       private StreamingOutputCallResponse result;
-      
+
       private StreamingOutputCallResponse PrepareBuilder() {
         if (resultIsReadOnly) {
           StreamingOutputCallResponse original = result;
@@ -2723,21 +2723,21 @@ namespace grpc.testing {
         }
         return result;
       }
-      
+
       public override bool IsInitialized {
         get { return result.IsInitialized; }
       }
-      
+
       protected override StreamingOutputCallResponse MessageBeingBuilt {
         get { return PrepareBuilder(); }
       }
-      
+
       public override Builder Clear() {
         result = DefaultInstance;
         resultIsReadOnly = true;
         return this;
       }
-      
+
       public override Builder Clone() {
         if (resultIsReadOnly) {
           return new Builder(result);
@@ -2745,15 +2745,15 @@ namespace grpc.testing {
           return new Builder().MergeFrom(result);
         }
       }
-      
+
       public override pbd::MessageDescriptor DescriptorForType {
         get { return global::grpc.testing.StreamingOutputCallResponse.Descriptor; }
       }
-      
+
       public override StreamingOutputCallResponse DefaultInstanceForType {
         get { return global::grpc.testing.StreamingOutputCallResponse.DefaultInstance; }
       }
-      
+
       public override StreamingOutputCallResponse BuildPartial() {
         if (resultIsReadOnly) {
           return result;
@@ -2761,7 +2761,7 @@ namespace grpc.testing {
         resultIsReadOnly = true;
         return result.MakeReadOnly();
       }
-      
+
       public override Builder MergeFrom(pb::IMessage other) {
         if (other is StreamingOutputCallResponse) {
           return MergeFrom((StreamingOutputCallResponse) other);
@@ -2770,7 +2770,7 @@ namespace grpc.testing {
           return this;
         }
       }
-      
+
       public override Builder MergeFrom(StreamingOutputCallResponse other) {
         if (other == global::grpc.testing.StreamingOutputCallResponse.DefaultInstance) return this;
         PrepareBuilder();
@@ -2780,11 +2780,11 @@ namespace grpc.testing {
         this.MergeUnknownFields(other.UnknownFields);
         return this;
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input) {
         return MergeFrom(input, pb::ExtensionRegistry.Empty);
       }
-      
+
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
         PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
@@ -2831,14 +2831,14 @@ namespace grpc.testing {
             }
           }
         }
-        
+
         if (unknownFields != null) {
           this.UnknownFields = unknownFields.Build();
         }
         return this;
       }
-      
-      
+
+
       public bool HasPayload {
        get { return result.hasPayload; }
       }
@@ -2883,9 +2883,9 @@ namespace grpc.testing {
       object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
     }
   }
-  
+
   #endregion
-  
+
 }
 
 #endregion Designer generated code
diff --git a/src/csharp/GrpcApi/Properties/AssemblyInfo.cs b/src/csharp/GrpcApi/Properties/AssemblyInfo.cs
index 725f12c48606d2eabcdb06a7bb1ad6218570fdff..96f142dae9a798c8a85be34e3aee2094f7b4ca8d 100644
--- a/src/csharp/GrpcApi/Properties/AssemblyInfo.cs
+++ b/src/csharp/GrpcApi/Properties/AssemblyInfo.cs
@@ -1,21 +1,21 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-// Information about this assembly is defined by the following attributes. 
+// Information about this assembly is defined by the following attributes.
 // Change them to the values specific to your project.
 [assembly: AssemblyTitle ("GrpcApi")]
 [assembly: AssemblyDescription ("")]
 [assembly: AssemblyConfiguration ("")]
 [assembly: AssemblyCompany ("")]
 [assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("jtattermusch")]
+[assembly: AssemblyCopyright ("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark ("")]
 [assembly: AssemblyCulture ("")]
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion ("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly, 
+[assembly: AssemblyVersion ("0.9.*")]
+// The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
diff --git a/src/csharp/GrpcApi/TestServiceGrpc.cs b/src/csharp/GrpcApi/TestServiceGrpc.cs
index 067b21c252c64343764e6f0be6ab0cd6b6e68e89..15700e40ac58e3eee775b6ab14ba271a305d89a4 100644
--- a/src/csharp/GrpcApi/TestServiceGrpc.cs
+++ b/src/csharp/GrpcApi/TestServiceGrpc.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -30,12 +30,13 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #endregion
+
 using System;
-using System.Threading;
-using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Reactive.Linq;
-using Google.GRPC.Core;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
 
 namespace grpc.testing
 {
@@ -99,7 +100,7 @@ namespace grpc.testing
 
             Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken));
 
-            Task StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken));
+            void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken));
 
             ClientStreamingAsyncResult<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken));
 
@@ -119,49 +120,49 @@ namespace grpc.testing
 
             public Empty EmptyCall(Empty request, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<Empty, Empty>(emptyCallMethod, channel);
+                var call = new Grpc.Core.Call<Empty, Empty>(emptyCallMethod, channel);
                 return Calls.BlockingUnaryCall(call, request, token);
             }
 
             public Task<Empty> EmptyCallAsync(Empty request, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<Empty, Empty>(emptyCallMethod, channel);
+                var call = new Grpc.Core.Call<Empty, Empty>(emptyCallMethod, channel);
                 return Calls.AsyncUnaryCall(call, request, token);
             }
 
             public SimpleResponse UnaryCall(SimpleRequest request, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
+                var call = new Grpc.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
                 return Calls.BlockingUnaryCall(call, request, token);
             }
 
             public Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
+                var call = new Grpc.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
                 return Calls.AsyncUnaryCall(call, request, token);
             }
 
-            public Task StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)) {
-                var call = new Google.GRPC.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(streamingOutputCallMethod, channel);
-                return Calls.AsyncServerStreamingCall(call, request, responseObserver, token);
+            public void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)) {
+                var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(streamingOutputCallMethod, channel);
+                Calls.AsyncServerStreamingCall(call, request, responseObserver, token);
             }
 
             public ClientStreamingAsyncResult<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<StreamingInputCallRequest, StreamingInputCallResponse>(streamingInputCallMethod, channel);
+                var call = new Grpc.Core.Call<StreamingInputCallRequest, StreamingInputCallResponse>(streamingInputCallMethod, channel);
                 return Calls.AsyncClientStreamingCall(call, token);
             }
 
             public IObserver<StreamingOutputCallRequest> FullDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(fullDuplexCallMethod, channel);
+                var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(fullDuplexCallMethod, channel);
                 return Calls.DuplexStreamingCall(call, responseObserver, token);
             }
 
 
             public IObserver<StreamingOutputCallRequest> HalfDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken))
             {
-                var call = new Google.GRPC.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(halfDuplexCallMethod, channel);
+                var call = new Grpc.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(halfDuplexCallMethod, channel);
                 return Calls.DuplexStreamingCall(call, responseObserver, token);
             }
         }
diff --git a/src/csharp/GrpcApi/proto/empty.proto b/src/csharp/GrpcApi/proto/empty.proto
index c3bb940075bafcf8f5c2dbeb938b90c93d008a3e..4295a0a960c0a07a7cf1df88438d3a8715a1b48b 100644
--- a/src/csharp/GrpcApi/proto/empty.proto
+++ b/src/csharp/GrpcApi/proto/empty.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/csharp/GrpcApi/proto/math.proto b/src/csharp/GrpcApi/proto/math.proto
index 074efadf8935a32871350bf52590b13694131172..5485d580c322233b33442258966e9b7cabf3522c 100644
--- a/src/csharp/GrpcApi/proto/math.proto
+++ b/src/csharp/GrpcApi/proto/math.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/csharp/GrpcApi/proto/messages.proto b/src/csharp/GrpcApi/proto/messages.proto
index e3814da406e705b30a0a855ab49b6a382971c817..65a81404652520a211940cd4af81968620ea8dc2 100644
--- a/src/csharp/GrpcApi/proto/messages.proto
+++ b/src/csharp/GrpcApi/proto/messages.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/csharp/GrpcApi/proto/test.proto b/src/csharp/GrpcApi/proto/test.proto
index c2437630b7d407b59eb74f9e7e38ddcf4f2f242e..927a3a83aa26772075a9602012cab791071e41f8 100644
--- a/src/csharp/GrpcApi/proto/test.proto
+++ b/src/csharp/GrpcApi/proto/test.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/csharp/GrpcApiTests/MathClientServerTests.cs b/src/csharp/GrpcApiTests/MathClientServerTests.cs
index bb3f75d4acb0e57bd4afe228f91c9477a4c62980..767340d6f2b287a8af169eb07e6c7ce0c7c0aa50 100644
--- a/src/csharp/GrpcApiTests/MathClientServerTests.cs
+++ b/src/csharp/GrpcApiTests/MathClientServerTests.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,12 +32,12 @@
 #endregion
 
 using System;
-using NUnit.Framework;
-using Google.GRPC.Core;
+using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
-using Google.GRPC.Core.Utils;
-using System.Collections.Generic;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
 
 namespace math.Tests
 {
@@ -64,6 +64,15 @@ namespace math.Tests
             client = MathGrpc.NewStub(channel);
         }
 
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            channel.Dispose();
+
+            server.ShutdownAsync().Wait();
+            GrpcEnvironment.Shutdown();
+        }
+
         [Test]
         public void Div1()
         {
@@ -96,7 +105,7 @@ namespace math.Tests
             var recorder = new RecordingObserver<Num>();
             client.Fib(new FibArgs.Builder { Limit = 6 }.Build(), recorder);
 
-            CollectionAssert.AreEqual(new List<long>{1, 1, 2, 3, 5, 8}, 
+            CollectionAssert.AreEqual(new List<long>{1, 1, 2, 3, 5, 8},
                 recorder.ToList().Result.ConvertAll((n) => n.Num_));
         }
 
@@ -136,15 +145,6 @@ namespace math.Tests
             CollectionAssert.AreEqual(new long[] {3, 4, 3}, result.ConvertAll((divReply) => divReply.Quotient));
             CollectionAssert.AreEqual(new long[] {1, 16, 1}, result.ConvertAll((divReply) => divReply.Remainder));
         }
-
-        [TestFixtureTearDown]
-        public void Cleanup()
-        {
-            channel.Dispose();
-
-            server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
-        }
     }
 }
 
diff --git a/src/csharp/GrpcApiTests/Properties/AssemblyInfo.cs b/src/csharp/GrpcApiTests/Properties/AssemblyInfo.cs
index 0928404429fe045ddea1a75e796abb2c227eefed..ac3cfca52e13f3cc90550e119f2071684b64858c 100644
--- a/src/csharp/GrpcApiTests/Properties/AssemblyInfo.cs
+++ b/src/csharp/GrpcApiTests/Properties/AssemblyInfo.cs
@@ -1,21 +1,21 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-// Information about this assembly is defined by the following attributes. 
+// Information about this assembly is defined by the following attributes.
 // Change them to the values specific to your project.
 [assembly: AssemblyTitle("GrpcApiTests")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("jtattermusch")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly, 
+[assembly: AssemblyVersion("0.9.*")]
+// The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
diff --git a/src/csharp/GrpcCore/Call.cs b/src/csharp/GrpcCore/Call.cs
index 181210902f7d7915c849610f516aa2b4daa540c3..72dca688952ccd78fd87ae329c3c5dbc43808bda 100644
--- a/src/csharp/GrpcCore/Call.cs
+++ b/src/csharp/GrpcCore/Call.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,9 +32,9 @@
 #endregion
 
 using System;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     public class Call<TRequest, TResponse>
     {
@@ -43,7 +43,7 @@ namespace Google.GRPC.Core
         readonly Func<byte[], TResponse> responseDeserializer;
         readonly Channel channel;
 
-        public Call(string methodName, 
+        public Call(string methodName,
                     Func<TRequest, byte[]> requestSerializer,
                     Func<byte[], TResponse> responseDeserializer,
                     TimeSpan timeout,
diff --git a/src/csharp/GrpcCore/Calls.cs b/src/csharp/GrpcCore/Calls.cs
index 101965600e049ebc47ee33089bb4c1dfb77f1c12..b67332676aca75ecb0c7c8b8738e5320f851155b 100644
--- a/src/csharp/GrpcCore/Calls.cs
+++ b/src/csharp/GrpcCore/Calls.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -34,9 +34,9 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     // NOTE: this class is work-in-progress
 
@@ -47,50 +47,42 @@ namespace Google.GRPC.Core
     {
         public static TResponse BlockingUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
         {
-            //TODO: implement this in real synchronous style once new GRPC C core API is available.
-            return AsyncUnaryCall(call, req, token).Result;
+            //TODO: implement this in real synchronous style.
+            try {
+                return AsyncUnaryCall(call, req, token).Result;
+            } catch(AggregateException ae) {
+                foreach (var e in ae.InnerExceptions)
+                {
+                    if (e is RpcException)
+                    {
+                        throw e;
+                    }
+                }
+                throw;
+            }
         }
 
         public static async Task<TResponse> AsyncUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
         {
             var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestSerializer, call.ResponseDeserializer);
-            asyncCall.Initialize(call.Channel, call.MethodName);
-            asyncCall.Start(false, GetCompletionQueue());
-
-            await asyncCall.WriteAsync(req);
-            await asyncCall.WritesCompletedAsync();
-
-            TResponse response = await asyncCall.ReadAsync();
-
-            Status status = await asyncCall.Finished;
-
-            if (status.StatusCode != StatusCode.GRPC_STATUS_OK)
-            {
-                throw new RpcException(status);
-            }
-            return response;
+            asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.MethodName);
+            return await asyncCall.UnaryCallAsync(req);
         }
 
-        public static async Task AsyncServerStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, IObserver<TResponse> outputs, CancellationToken token)
+        public static void AsyncServerStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, IObserver<TResponse> outputs, CancellationToken token)
         {
             var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestSerializer, call.ResponseDeserializer);
-            asyncCall.Initialize(call.Channel, call.MethodName);
-            asyncCall.Start(false, GetCompletionQueue());
 
-            asyncCall.StartReadingToStream(outputs);
-
-            await asyncCall.WriteAsync(req);
-            await asyncCall.WritesCompletedAsync();
+            asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.MethodName);
+            asyncCall.StartServerStreamingCall(req, outputs);
         }
 
         public static ClientStreamingAsyncResult<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
         {
             var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestSerializer, call.ResponseDeserializer);
-            asyncCall.Initialize(call.Channel, call.MethodName);
-            asyncCall.Start(false, GetCompletionQueue());
-
-            var task = asyncCall.ReadAsync();
-            var inputs = new StreamingInputObserver<TRequest, TResponse>(asyncCall);
+            asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.MethodName);
+            var task = asyncCall.ClientStreamingCallAsync();
+            var inputs = new ClientStreamingInputObserver<TRequest, TResponse>(asyncCall);
             return new ClientStreamingAsyncResult<TRequest, TResponse>(task, inputs);
         }
 
@@ -102,12 +94,10 @@ namespace Google.GRPC.Core
         public static IObserver<TRequest> DuplexStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, IObserver<TResponse> outputs, CancellationToken token)
         {
             var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestSerializer, call.ResponseDeserializer);
-            asyncCall.Initialize(call.Channel, call.MethodName);
-            asyncCall.Start(false, GetCompletionQueue());
+            asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.MethodName);
 
-            asyncCall.StartReadingToStream(outputs);
-            var inputs = new StreamingInputObserver<TRequest, TResponse>(asyncCall);
-            return inputs;
+            asyncCall.StartDuplexStreamingCall(outputs);
+            return new ClientStreamingInputObserver<TRequest, TResponse>(asyncCall);
         }
 
         private static CompletionQueueSafeHandle GetCompletionQueue() {
diff --git a/src/csharp/GrpcCore/Channel.cs b/src/csharp/GrpcCore/Channel.cs
index cd4f151f49fe33cc5754ea66761b68e260f3e87c..942651cf3935a3cf3a567573e5c87aa5c35fd64a 100644
--- a/src/csharp/GrpcCore/Channel.cs
+++ b/src/csharp/GrpcCore/Channel.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -35,9 +35,9 @@ using System;
 using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
 	public class Channel : IDisposable
 	{
@@ -82,4 +82,4 @@ namespace Google.GRPC.Core
             }
         }
 	}
-}
\ No newline at end of file
+}
diff --git a/src/csharp/GrpcCore/ClientStreamingAsyncResult.cs b/src/csharp/GrpcCore/ClientStreamingAsyncResult.cs
index 507d0dd8ad30d2e60f83d35bd97ace7413f44298..44580a115424110c78adc13ca11618b54320727c 100644
--- a/src/csharp/GrpcCore/ClientStreamingAsyncResult.cs
+++ b/src/csharp/GrpcCore/ClientStreamingAsyncResult.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -34,7 +34,7 @@
 using System;
 using System.Threading.Tasks;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     /// <summary>
     /// Return type for client streaming async method.
diff --git a/src/csharp/GrpcCore/GrpcCore.csproj b/src/csharp/GrpcCore/GrpcCore.csproj
index 34b9f6dfb82ff66d945488cd68b465b949877ded..ee76b742ce4af4cc2c1ee61ab691de9651ee1cfd 100644
--- a/src/csharp/GrpcCore/GrpcCore.csproj
+++ b/src/csharp/GrpcCore/GrpcCore.csproj
@@ -47,21 +47,21 @@
     <Compile Include="Internal\ChannelSafeHandle.cs" />
     <Compile Include="Internal\CompletionQueueSafeHandle.cs" />
     <Compile Include="Internal\Enums.cs" />
-    <Compile Include="Internal\Event.cs" />
     <Compile Include="Internal\SafeHandleZeroIsInvalid.cs" />
     <Compile Include="Internal\Timespec.cs" />
     <Compile Include="Internal\GrpcThreadPool.cs" />
     <Compile Include="Internal\AsyncCall.cs" />
     <Compile Include="Internal\ServerSafeHandle.cs" />
-    <Compile Include="Internal\StreamingInputObserver.cs" />
     <Compile Include="Method.cs" />
     <Compile Include="ServerCalls.cs" />
     <Compile Include="ServerCallHandler.cs" />
-    <Compile Include="Internal\ServerWritingObserver.cs" />
     <Compile Include="Marshaller.cs" />
     <Compile Include="ServerServiceDefinition.cs" />
     <Compile Include="Utils\RecordingObserver.cs" />
     <Compile Include="Utils\RecordingQueue.cs" />
+    <Compile Include="Internal\ClientStreamingInputObserver.cs" />
+    <Compile Include="Internal\ServerStreamingOutputObserver.cs" />
+    <Compile Include="Internal\BatchContextSafeHandleNotOwned.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/GrpcCore/GrpcEnvironment.cs b/src/csharp/GrpcCore/GrpcEnvironment.cs
index ee1168621d01b1d143de1eb51f2025c35e276da2..0e3a0a581cd8a71717bcfa318f429d64e4c65a0c 100644
--- a/src/csharp/GrpcCore/GrpcEnvironment.cs
+++ b/src/csharp/GrpcCore/GrpcEnvironment.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,17 +32,17 @@
 #endregion
 
 using System;
-using Google.GRPC.Core.Internal;
 using System.Runtime.InteropServices;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     /// <summary>
     /// Encapsulates initialization and shutdown of gRPC library.
     /// </summary>
     public class GrpcEnvironment
     {
-        const int THREAD_POOL_SIZE = 1;
+        const int THREAD_POOL_SIZE = 4;
 
         [DllImport("grpc_csharp_ext.dll")]
         static extern void grpcsharp_init();
@@ -52,7 +52,7 @@ namespace Google.GRPC.Core
 
         static object staticLock = new object();
         static volatile GrpcEnvironment instance;
-       
+
         readonly GrpcThreadPool threadPool;
         bool isClosed;
 
@@ -60,7 +60,7 @@ namespace Google.GRPC.Core
         /// Makes sure GRPC environment is initialized. Subsequent invocations don't have any
         /// effect unless you call Shutdown first.
         /// Although normal use cases assume you will call this just once in your application's
-        /// lifetime (and call Shutdown once you're done), for the sake of easier testing it's 
+        /// lifetime (and call Shutdown once you're done), for the sake of easier testing it's
         /// allowed to initialize the environment again after it has been successfully shutdown.
         /// </summary>
         public static void Initialize() {
diff --git a/src/csharp/GrpcCore/Internal/AsyncCall.cs b/src/csharp/GrpcCore/Internal/AsyncCall.cs
index a3b40e512c817228e172b7cb9b016f8c9baf983e..5e96092e27030c0964a6977797dcbd71eeddd466 100644
--- a/src/csharp/GrpcCore/Internal/AsyncCall.cs
+++ b/src/csharp/GrpcCore/Internal/AsyncCall.cs
@@ -32,181 +32,187 @@
 #endregion
 
 using System;
-using System.Runtime.InteropServices;
 using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
-using System.Runtime.CompilerServices;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
-    /// Listener for call events that can be delivered from a completion queue.
-    /// </summary>
-    internal interface ICallEventListener {
-    
-        void OnClientMetadata();
-
-        void OnRead(byte[] payload);
-
-        void OnWriteAccepted(GRPCOpError error);
-
-        void OnFinishAccepted(GRPCOpError error);
-
-        // ignore the status on server
-        void OnFinished(Status status);
-    }
-
-    /// <summary>
-    /// Handle native call lifecycle and provides convenience methods.
+    /// Handles native call lifecycle and provides convenience methods.
     /// </summary>
-    internal class AsyncCall<TWrite, TRead>: ICallEventListener, IDisposable
+    internal class AsyncCall<TWrite, TRead>
     {
         readonly Func<TWrite, byte[]> serializer;
         readonly Func<byte[], TRead> deserializer;
 
-        // TODO: make sure the delegate doesn't get garbage collected while 
-        // native callbacks are in the completion queue.
-        readonly EventCallbackDelegate callbackHandler;
+        readonly CompletionCallbackDelegate unaryResponseHandler;
+        readonly CompletionCallbackDelegate finishedHandler;
+        readonly CompletionCallbackDelegate writeFinishedHandler;
+        readonly CompletionCallbackDelegate readFinishedHandler;
+        readonly CompletionCallbackDelegate halfclosedHandler;
+        readonly CompletionCallbackDelegate finishedServersideHandler;
 
         object myLock = new object();
-        bool disposed;
+        GCHandle gchandle;
         CallSafeHandle call;
+        bool disposed;
+
+        bool server;
 
         bool started;
         bool errorOccured;
-
         bool cancelRequested;
+        bool readingDone;
         bool halfcloseRequested;
         bool halfclosed;
-        bool doneWithReading;
-        Nullable<Status> finishedStatus;
+        bool finished;
 
+        // Completion of a pending write if not null.
         TaskCompletionSource<object> writeTcs;
+
+        // Completion of a pending read if not null.
         TaskCompletionSource<TRead> readTcs;
-        TaskCompletionSource<object> halfcloseTcs = new TaskCompletionSource<object>();
-        TaskCompletionSource<Status> finishedTcs = new TaskCompletionSource<Status>();
 
+        // Completion of a pending halfclose if not null.
+        TaskCompletionSource<object> halfcloseTcs;
+
+        // Completion of a pending unary response if not null.
+        TaskCompletionSource<TRead> unaryResponseTcs;
+
+        // Set after status is received on client. Only used for server streaming and duplex streaming calls.
+        Nullable<Status> finishedStatus;
+        TaskCompletionSource<object> finishedServersideTcs = new TaskCompletionSource<object>();
+
+        // For streaming, the reads will be delivered to this observer.
         IObserver<TRead> readObserver;
 
         public AsyncCall(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer)
         {
             this.serializer = serializer;
             this.deserializer = deserializer;
-            this.callbackHandler = HandleEvent;
+            this.unaryResponseHandler = HandleUnaryResponse;
+            this.finishedHandler = HandleFinished;
+            this.writeFinishedHandler = HandleWriteFinished;
+            this.readFinishedHandler = HandleReadFinished;
+            this.halfclosedHandler = HandleHalfclosed;
+            this.finishedServersideHandler = HandleFinishedServerside;
         }
 
-        public Task WriteAsync(TWrite msg)
+        public void Initialize(Channel channel, CompletionQueueSafeHandle cq, String methodName)
         {
-            return StartWrite(msg, false).Task;
+            InitializeInternal(CallSafeHandle.Create(channel.Handle, cq, methodName, channel.Target, Timespec.InfFuture), false);
         }
 
-        public Task WritesCompletedAsync()
+        public void InitializeServer(CallSafeHandle call)
         {
-            WritesDone();
-            return halfcloseTcs.Task;
+            InitializeInternal(call, true);
         }
 
-        public Task WriteStatusAsync(Status status)
+        public Task<TRead> UnaryCallAsync(TWrite msg)
         {
-            WriteStatus(status);
-            return halfcloseTcs.Task;
-        }
+            lock (myLock)
+            {
+                started = true;
+                halfcloseRequested = true;
+                readingDone = true;
 
-        public Task<TRead> ReadAsync()
-        {
-            return StartRead().Task;
-        }
+                // TODO: handle serialization error...
+                byte[] payload = serializer(msg);
 
-        public Task Halfclosed
-        {
-            get
-            {
-                return halfcloseTcs.Task;
+                unaryResponseTcs = new TaskCompletionSource<TRead>();
+                call.StartUnary(payload, unaryResponseHandler);
+
+                return unaryResponseTcs.Task;
             }
         }
 
-        public Task<Status> Finished
+        public Task<TRead> ClientStreamingCallAsync()
         {
-            get
+            lock (myLock)
             {
-                return finishedTcs.Task;
+                started = true;
+                readingDone = true;
+
+                unaryResponseTcs = new TaskCompletionSource<TRead>();
+                call.StartClientStreaming(unaryResponseHandler);
+
+                return unaryResponseTcs.Task;
             }
         }
 
-        /// <summary>
-        /// Initiates reading to given observer.
-        /// </summary>
-        public void StartReadingToStream(IObserver<TRead> readObserver) {
+        public void StartServerStreamingCall(TWrite msg, IObserver<TRead> readObserver)
+        {
             lock (myLock)
             {
-                CheckStarted();
-                if (this.readObserver != null)
-                {
-                    throw new InvalidOperationException("Already registered an observer.");
-                }
+                started = true;
+                halfcloseRequested = true;
+        
                 this.readObserver = readObserver;
-                StartRead();
-            }
-        }
 
-        public void Initialize(Channel channel, String methodName) {
-            lock (myLock)
-            {
-               this.call = CallSafeHandle.Create(channel.Handle, methodName, channel.Target, Timespec.InfFuture);
+                // TODO: handle serialization error...
+                byte[] payload = serializer(msg);
+        
+                call.StartServerStreaming(payload, finishedHandler);
+
+                ReceiveMessageAsync();
             }
         }
 
-        public void InitializeServer(CallSafeHandle call)
+        public void StartDuplexStreamingCall(IObserver<TRead> readObserver)
         {
-            lock(myLock)
+            lock (myLock)
             {
-                this.call = call;
+                started = true;
+
+                this.readObserver = readObserver;
+
+                call.StartDuplexStreaming(finishedHandler);
+
+                ReceiveMessageAsync();
             }
         }
 
-        // Client only
-        public void Start(bool buffered, CompletionQueueSafeHandle cq)
+        public Task ServerSideUnaryRequestCallAsync()
         {
             lock (myLock)
             {
-                if (started)
-                {
-                    throw new InvalidOperationException("Already started.");
-                }
-
-                call.Invoke(cq, buffered, callbackHandler, callbackHandler);
                 started = true;
+                call.StartServerSide(finishedServersideHandler);
+                return finishedServersideTcs.Task;
             }
         }
 
-        // Server only
-        public void Accept(CompletionQueueSafeHandle cq)
+        public Task ServerSideStreamingRequestCallAsync(IObserver<TRead> readObserver)
         {
             lock (myLock)
             {
-                if (started)
+                started = true;
+                call.StartServerSide(finishedServersideHandler);
+               
+                if (this.readObserver != null)
                 {
-                    throw new InvalidOperationException("Already started.");
+                    throw new InvalidOperationException("Already registered an observer.");
                 }
+                this.readObserver = readObserver;
+                ReceiveMessageAsync();
 
-                call.ServerAccept(cq, callbackHandler);
-                call.ServerEndInitialMetadata(0);
-                started = true;
+                return finishedServersideTcs.Task;
             }
         }
 
-        public TaskCompletionSource<object> StartWrite(TWrite msg, bool buffered)
+        public Task SendMessageAsync(TWrite msg)
         {
             lock (myLock)
             {
+                CheckNotDisposed();
                 CheckStarted();
-                CheckNotFinished();
                 CheckNoError();
-                CheckCancelNotRequested();
-               
-                if (halfcloseRequested || halfclosed)
+
+                if (halfcloseRequested)
                 {
                     throw new InvalidOperationException("Already halfclosed.");
                 }
@@ -218,64 +224,63 @@ namespace Google.GRPC.Core.Internal
 
                 // TODO: wrap serialization...
                 byte[] payload = serializer(msg);
-               
-                call.StartWrite(payload, buffered, callbackHandler);
+
+                call.StartSendMessage(payload, writeFinishedHandler);
                 writeTcs = new TaskCompletionSource<object>();
-                return writeTcs;
+                return writeTcs.Task;
             }
         }
 
-        // client only
-        public void WritesDone()
+        public Task SendCloseFromClientAsync()
         {
             lock (myLock)
             {
+                CheckNotDisposed();
                 CheckStarted();
-                CheckNotFinished();
                 CheckNoError();
-                CheckCancelNotRequested();
 
-                if (halfcloseRequested || halfclosed)
+                if (halfcloseRequested)
                 {
                     throw new InvalidOperationException("Already halfclosed.");
                 }
 
-                call.WritesDone(callbackHandler);
+                call.StartSendCloseFromClient(halfclosedHandler);
+
                 halfcloseRequested = true;
+                halfcloseTcs = new TaskCompletionSource<object>();
+                return halfcloseTcs.Task;
             }
         }
 
-        // server only
-        public void WriteStatus(Status status)
+        public Task SendStatusFromServerAsync(Status status)
         {
             lock (myLock)
             {
+                CheckNotDisposed();
                 CheckStarted();
-                CheckNotFinished();
                 CheckNoError();
-                CheckCancelNotRequested();
 
-                if (halfcloseRequested || halfclosed)
+                if (halfcloseRequested)
                 {
                     throw new InvalidOperationException("Already halfclosed.");
                 }
 
-                call.StartWriteStatus(status, callbackHandler);
+                call.StartSendStatusFromServer(status, halfclosedHandler);
                 halfcloseRequested = true;
+                halfcloseTcs = new TaskCompletionSource<object>();
+                return halfcloseTcs.Task;
             }
         }
 
-        public TaskCompletionSource<TRead> StartRead()
+        public Task<TRead> ReceiveMessageAsync()
         {
             lock (myLock)
             {
+                CheckNotDisposed();
                 CheckStarted();
-                CheckNotFinished();
                 CheckNoError();
 
-                // TODO: add check for not cancelled?
-
-                if (doneWithReading)
+                if (readingDone)
                 {
                     throw new InvalidOperationException("Already read the last message.");
                 }
@@ -285,10 +290,10 @@ namespace Google.GRPC.Core.Internal
                     throw new InvalidOperationException("Only one read can be pending at a time");
                 }
 
-                call.StartRead(callbackHandler);
+                call.StartReceiveMessage(readFinishedHandler);
 
                 readTcs = new TaskCompletionSource<TRead>();
-                return readTcs;
+                return readTcs.Task;
             }
         }
 
@@ -296,9 +301,8 @@ namespace Google.GRPC.Core.Internal
         {
             lock (myLock)
             {
+                CheckNotDisposed();
                 CheckStarted();
-                CheckNotFinished();
-
                 cancelRequested = true;
             }
             // grpc_call_cancel is threadsafe
@@ -309,216 +313,302 @@ namespace Google.GRPC.Core.Internal
         {
             lock (myLock)
             {
+                CheckNotDisposed();
                 CheckStarted();
-                CheckNotFinished();
-
                 cancelRequested = true;
             }
             // grpc_call_cancel_with_status is threadsafe
             call.CancelWithStatus(status);
         }
-       
-        public void OnClientMetadata()
+
+        private void InitializeInternal(CallSafeHandle call, bool server)
         {
-            // TODO: implement....
+            lock (myLock)
+            {
+                // Make sure this object and the delegated held by it will not be garbage collected
+                // before we release this handle.
+                gchandle = GCHandle.Alloc(this);
+                this.call = call;
+                this.server = server;
+            }
         }
 
-        public void OnRead(byte[] payload)
+        private void CheckStarted()
         {
-            TaskCompletionSource<TRead> oldTcs = null;
-            IObserver<TRead> observer = null;
-            lock (myLock)
+            if (!started)
+            {
+                throw new InvalidOperationException("Call not started");
+            }
+        }
+
+        private void CheckNotDisposed()
+        {
+            if (disposed)
+            {
+                throw new InvalidOperationException("Call has already been disposed.");
+            }
+        }
+
+        private void CheckNoError()
+        {
+            if (errorOccured)
+            {
+                throw new InvalidOperationException("Error occured when processing call.");
+            }
+        }
+
+        private bool ReleaseResourcesIfPossible()
+        {
+            if (!disposed && call != null)
             {
-                oldTcs = readTcs;
-                readTcs = null;
-                if (payload == null)
+                if (halfclosed && readingDone && finished)
                 {
-                    doneWithReading = true;
+                    ReleaseResources();
+                    return true;
                 }
-                observer = readObserver;
             }
+            return false;
+        }
 
-            // TODO: wrap deserialization...
-            TRead msg = payload != null ? deserializer(payload) : default(TRead);
-
-            oldTcs.SetResult(msg);
+        private void ReleaseResources()
+        {
+            if (call != null) {
+                call.Dispose();
+            }
+            gchandle.Free();
+            disposed = true;
+        }
 
-            // TODO: make sure we deliver reads in the right order.
+        private void CompleteStreamObserver(Status status)
+        {
+            if (status.StatusCode != StatusCode.OK)
+            {
+                // TODO: wrap to handle exceptions;
+                readObserver.OnError(new RpcException(status));
+            } else {
+                // TODO: wrap to handle exceptions;
+                readObserver.OnCompleted();
+            }
+        }
 
-            if (observer != null)
+        /// <summary>
+        /// Handler for unary response completion.
+        /// </summary>
+        private void HandleUnaryResponse(GRPCOpError error, IntPtr batchContextPtr)
+        {
+            try
             {
-                if (payload != null)
+                TaskCompletionSource<TRead> tcs;
+                lock(myLock)
                 {
-                    // TODO: wrap to handle exceptions
-                    observer.OnNext(msg);
+                    finished = true;
+                    halfclosed = true;
+                    tcs = unaryResponseTcs;
 
-                    // start a new read
-                    StartRead();
+                    ReleaseResourcesIfPossible();
                 }
-                else
+
+                var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
+
+                if (error != GRPCOpError.GRPC_OP_OK)
                 {
-                    // TODO: wrap to handle exceptions;
-                    observer.OnCompleted();
+                    tcs.SetException(new RpcException(
+                        new Status(StatusCode.Internal, "Internal error occured.")
+                    ));
+                    return;
                 }
 
+                var status = ctx.GetReceivedStatus();
+                if (status.StatusCode != StatusCode.OK)
+                {
+                    tcs.SetException(new RpcException(status));
+                    return;
+                }
+
+                // TODO: handle deserialize error...
+                var msg = deserializer(ctx.GetReceivedMessage());
+                tcs.SetResult(msg);
+            } 
+            catch(Exception e)
+            {
+                Console.WriteLine("Caught exception in a native handler: " + e);
             }
         }
 
-        public void OnWriteAccepted(GRPCOpError error)
+        private void HandleWriteFinished(GRPCOpError error, IntPtr batchContextPtr)
         {
-            TaskCompletionSource<object> oldTcs = null;
-            lock (myLock)
+            try
             {
-                UpdateErrorOccured(error);
-                oldTcs = writeTcs;
-                writeTcs = null;
-            }
+                TaskCompletionSource<object> oldTcs = null;
+                lock (myLock)
+                {
+                    oldTcs = writeTcs;
+                    writeTcs = null;
+                }
+
+                if (errorOccured)
+                {
+                    // TODO: use the right type of exception...
+                    oldTcs.SetException(new Exception("Write failed"));
+                }
+                else
+                {
+                    // TODO: where does the continuation run?
+                    oldTcs.SetResult(null);
+                }
 
-            if (errorOccured)
-            {
-                // TODO: use the right type of exception...
-                oldTcs.SetException(new Exception("Write failed"));
             }
-            else
+            catch(Exception e)
             {
-                // TODO: where does the continuation run?
-                oldTcs.SetResult(null);
+                Console.WriteLine("Caught exception in a native handler: " + e);
             }
         }
 
-        public void OnFinishAccepted(GRPCOpError error)
+        private void HandleHalfclosed(GRPCOpError error, IntPtr batchContextPtr)
         {
-            lock (myLock)
+            try
             {
-                UpdateErrorOccured(error);
-                halfclosed = true;
-            }
+                lock (myLock)
+                {
+                    halfclosed = true;
 
-            if (errorOccured)
-            {
-                halfcloseTcs.SetException(new Exception("Halfclose failed"));
+                    ReleaseResourcesIfPossible();
+                }
 
+                if (error != GRPCOpError.GRPC_OP_OK)
+                {
+                    halfcloseTcs.SetException(new Exception("Halfclose failed"));
+
+                }
+                else
+                {
+                    halfcloseTcs.SetResult(null);
+                }
             }
-            else
+            catch(Exception e)
             {
-                halfcloseTcs.SetResult(null);
+                Console.WriteLine("Caught exception in a native handler: " + e);
             }
-
         }
 
-        public void OnFinished(Status status)
+        private void HandleReadFinished(GRPCOpError error, IntPtr batchContextPtr)
         {
-            lock (myLock)
+            try
             {
-                finishedStatus = status;
+                var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
+                var payload = ctx.GetReceivedMessage();
 
-                DisposeResourcesIfNeeded();
-            }
-            finishedTcs.SetResult(status);
+                TaskCompletionSource<TRead> oldTcs = null;
+                IObserver<TRead> observer = null;
 
-        }
+                Nullable<Status> status = null;
 
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
+                lock (myLock)
+                {
+                    oldTcs = readTcs;
+                    readTcs = null;
+                    if (payload == null)
+                    {
+                        readingDone = true;
+                    }
+                    observer = readObserver;
+                    status = finishedStatus;
+                }
 
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!disposed)
-            {
-                if (disposing)
+                // TODO: wrap deserialization...
+                TRead msg = payload != null ? deserializer(payload) : default(TRead);
+
+                oldTcs.SetResult(msg);
+
+                // TODO: make sure we deliver reads in the right order.
+
+                if (observer != null)
                 {
-                    if (call != null)
+                    if (payload != null)
                     {
-                        call.Dispose();
+                        // TODO: wrap to handle exceptions
+                        observer.OnNext(msg);
+
+                        // start a new read
+                        ReceiveMessageAsync();
                     }
-                } 
-                disposed = true;
+                    else
+                    {
+                        if (!server)
+                        {
+                            if (status.HasValue)
+                            {
+                                CompleteStreamObserver(status.Value);
+                            }
+                        } 
+                        else 
+                        {
+                            // TODO: wrap to handle exceptions..
+                            observer.OnCompleted();
+                        }
+                        // TODO: completeStreamObserver serverside...
+                    }
+               }
             }
-        }
-
-        private void UpdateErrorOccured(GRPCOpError error)
-        {
-            if (error == GRPCOpError.GRPC_OP_ERROR)
+            catch(Exception e)
             {
-                errorOccured = true;
+                Console.WriteLine("Caught exception in a native handler: " + e);
             }
         }
 
-        private void CheckStarted()
+        private void HandleFinished(GRPCOpError error, IntPtr batchContextPtr)
         {
-            if (!started)
+            try
             {
-                throw new InvalidOperationException("Call not started");
-            }
-        }
+                var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
+                var status = ctx.GetReceivedStatus();
 
-        private void CheckNoError()
-        {
-            if (errorOccured)
-            {
-                throw new InvalidOperationException("Error occured when processing call.");
-            }
-        }
+                bool wasReadingDone;
 
-        private void CheckNotFinished()
-        {
-            if (finishedStatus.HasValue)
-            {
-                throw new InvalidOperationException("Already finished.");
-            }
-        }
+                lock (myLock)
+                {
+                    finished = true;
+                    finishedStatus = status;
 
-        private void CheckCancelNotRequested()
-        {
-            if (cancelRequested)
+                    wasReadingDone = readingDone;
+
+                    ReleaseResourcesIfPossible();
+                }
+
+                if (wasReadingDone) {
+                    CompleteStreamObserver(status);
+                }
+
+            }
+            catch(Exception e)
             {
-                throw new InvalidOperationException("Cancel has been requested.");
+                Console.WriteLine("Caught exception in a native handler: " + e);
             }
         }
 
-        private void DisposeResourcesIfNeeded()
+        private void HandleFinishedServerside(GRPCOpError error, IntPtr batchContextPtr)
         {
-            if (call != null && started && finishedStatus.HasValue)
+            try
             {
-                // TODO: should we also wait for all the pending events to finish?
+                var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
 
-                call.Dispose();
-            }
-        }
-
-        private void HandleEvent(IntPtr eventPtr) {
-            try {
-                var ev = new EventSafeHandleNotOwned(eventPtr);
-                switch (ev.GetCompletionType())
+                lock(myLock)
                 {
-                case GRPCCompletionType.GRPC_CLIENT_METADATA_READ:
-                    OnClientMetadata();
-                    break;
-
-                case GRPCCompletionType.GRPC_READ:
-                    byte[] payload = ev.GetReadData();
-                    OnRead(payload);
-                    break;
+                    finished = true;
 
-                case GRPCCompletionType.GRPC_WRITE_ACCEPTED:
-                    OnWriteAccepted(ev.GetWriteAccepted());
-                    break;
+                    // TODO: because of the way server calls are implemented, we need to set
+                    // reading done to true here. Should be fixed in the future.
+                    readingDone = true;
 
-                case GRPCCompletionType.GRPC_FINISH_ACCEPTED:
-                    OnFinishAccepted(ev.GetFinishAccepted());
-                    break;
+                    ReleaseResourcesIfPossible();
+                }
+                // TODO: handle error ...
 
-                case GRPCCompletionType.GRPC_FINISHED:
-                    OnFinished(ev.GetFinished());
-                    break;
+                finishedServersideTcs.SetResult(null);
 
-                default:
-                    throw new ArgumentException("Unexpected completion type");
-                }
-            } catch(Exception e) {
+            }
+            catch(Exception e)
+            {
                 Console.WriteLine("Caught exception in a native handler: " + e);
             }
         }
diff --git a/src/csharp/GrpcCore/Internal/BatchContextSafeHandleNotOwned.cs b/src/csharp/GrpcCore/Internal/BatchContextSafeHandleNotOwned.cs
new file mode 100644
index 0000000000000000000000000000000000000000..75cd30e1a2d5f463c1d0e3f4d47091815e142db5
--- /dev/null
+++ b/src/csharp/GrpcCore/Internal/BatchContextSafeHandleNotOwned.cs
@@ -0,0 +1,96 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// 
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using Grpc.Core;
+
+namespace Grpc.Core.Internal
+{
+    /// <summary>
+    /// Not owned version of 
+    /// grpcsharp_batch_context
+    /// </summary>
+    internal class BatchContextSafeHandleNotOwned : SafeHandleZeroIsInvalid
+    {
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandleNotOwned ctx);
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandleNotOwned ctx, byte[] buffer, UIntPtr bufferLen);
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandleNotOwned ctx);
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandleNotOwned ctx);  // returns const char*
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandleNotOwned ctx);
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandleNotOwned ctx);  // returns const char*
+
+        public BatchContextSafeHandleNotOwned(IntPtr handle) : base(false)
+        {
+            SetHandle(handle);
+        }
+
+        public Status GetReceivedStatus()
+        {
+            // TODO: can the native method return string directly?
+            string details = Marshal.PtrToStringAnsi(grpcsharp_batch_context_recv_status_on_client_details(this));
+            return new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details);
+        }
+
+        public byte[] GetReceivedMessage()
+        {
+            IntPtr len = grpcsharp_batch_context_recv_message_length(this);
+            if (len == new IntPtr(-1))
+            {
+                return null;
+            }
+            byte[] data = new byte[(int) len];
+            grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length));
+            return data;
+        }
+
+        public CallSafeHandle GetServerRpcNewCall() {
+            return grpcsharp_batch_context_server_rpc_new_call(this);
+        }
+
+        public string GetServerRpcNewMethod() {
+            return Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/csharp/GrpcCore/Internal/CallSafeHandle.cs b/src/csharp/GrpcCore/Internal/CallSafeHandle.cs
index d91d2ac6cbfe8fe80ec38d9d5f9e0bc693772517..659a383b4bd71cef6005fd27ea6500232b340b15 100644
--- a/src/csharp/GrpcCore/Internal/CallSafeHandle.cs
+++ b/src/csharp/GrpcCore/Internal/CallSafeHandle.cs
@@ -32,14 +32,14 @@
 #endregion
 
 using System;
-using System.Runtime.InteropServices;
 using System.Diagnostics;
-using Google.GRPC.Core;
+using System.Runtime.InteropServices;
+using Grpc.Core;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
-    // TODO: we need to make sure that the delegates are not collected before invoked.
-    internal delegate void EventCallbackDelegate(IntPtr eventPtr);
+    //TODO: rename the delegate
+    internal delegate void CompletionCallbackDelegate(GRPCOpError error, IntPtr batchContextPtr);
 
     /// <summary>
     /// grpc_call from <grpc/grpc.h>
@@ -49,142 +49,108 @@ namespace Google.GRPC.Core.Internal
         const UInt32 GRPC_WRITE_BUFFER_HINT = 1;
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern CallSafeHandle grpcsharp_channel_create_call_old(ChannelSafeHandle channel, string method, string host, Timespec deadline);
+        static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_add_metadata(CallSafeHandle call, IntPtr metadata, UInt32 flags);
+        static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_invoke_old(CallSafeHandle call, CompletionQueueSafeHandle cq, IntPtr metadataReadTag, IntPtr finishedTag, UInt32 flags);
-
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_invoke_old")]
-        static extern GRPCCallError grpcsharp_call_invoke_old_CALLBACK(CallSafeHandle call, CompletionQueueSafeHandle cq,
-                                                              [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate metadataReadCallback, 
-                                                              [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate finishedCallback, 
-                                                              UInt32 flags);
+        static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_server_accept_old(CallSafeHandle call, CompletionQueueSafeHandle completionQueue, IntPtr finishedTag);
-
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_server_accept_old")]
-        static extern GRPCCallError grpcsharp_call_server_accept_old_CALLBACK(CallSafeHandle call, CompletionQueueSafeHandle completionQueue, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate finishedCallback);
+        static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
+                                                                        [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
+                                                                        byte[] send_buffer, UIntPtr send_buffer_len);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_server_end_initial_metadata_old(CallSafeHandle call, UInt32 flags);
+        static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
+                                                                      [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
+        static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
+                                                                      [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
+                                                                      byte[] send_buffer, UIntPtr send_buffer_len);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
+        static extern GRPCCallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call,
+                                                                          [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_start_write_status_old(CallSafeHandle call, StatusCode statusCode, string statusMessage, IntPtr tag);
-
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_start_write_status_old")]
-        static extern GRPCCallError grpcsharp_call_start_write_status_old_CALLBACK(CallSafeHandle call, StatusCode statusCode, string statusMessage, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
+        static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
+                                                                      [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
+                                                                      byte[] send_buffer, UIntPtr send_buffer_len);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_writes_done_old(CallSafeHandle call, IntPtr tag);
-
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_writes_done_old")]
-        static extern GRPCCallError grpcsharp_call_writes_done_old_CALLBACK(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
+        static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
+                                                                             [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_start_read_old(CallSafeHandle call, IntPtr tag);
-
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_start_read_old")]
-        static extern GRPCCallError grpcsharp_call_start_read_old_CALLBACK(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
+        static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback, StatusCode statusCode, string statusMessage);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpcsharp_call_start_write_from_copied_buffer(CallSafeHandle call,
-                                                                    byte[] buffer, UIntPtr length,
-                                                                    IntPtr tag, UInt32 flags);
+        static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
+                                                               [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_call_start_write_from_copied_buffer")]
-        static extern void grpcsharp_call_start_write_from_copied_buffer_CALLBACK(CallSafeHandle call,
-                                                                             byte[] buffer, UIntPtr length,
-                                                                             [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback,
-                                                                             UInt32 flags);
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
+                                                                [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
-		[DllImport("grpc_csharp_ext.dll")]
+        [DllImport("grpc_csharp_ext.dll")]
         static extern void grpcsharp_call_destroy(IntPtr call);
 
-        private CallSafeHandle()
-        {
-        }
-
-        /// <summary>
-        /// Creates a client call.
-        /// </summary>
-        public static CallSafeHandle Create(ChannelSafeHandle channel, string method, string host, Timespec deadline)
-        {
-            return grpcsharp_channel_create_call_old(channel, method, host, deadline);
-        }
-
-        public void Invoke(CompletionQueueSafeHandle cq, IntPtr metadataReadTag, IntPtr finishedTag, bool buffered)
-        {   
-            AssertCallOk(grpcsharp_call_invoke_old(this, cq, metadataReadTag, finishedTag, GetFlags(buffered)));
-        }
-
-        public void Invoke(CompletionQueueSafeHandle cq, bool buffered, EventCallbackDelegate metadataReadCallback, EventCallbackDelegate finishedCallback)
-        {   
-            AssertCallOk(grpcsharp_call_invoke_old_CALLBACK(this, cq, metadataReadCallback, finishedCallback, GetFlags(buffered)));
-        }
 
-        public void ServerAccept(CompletionQueueSafeHandle cq, IntPtr finishedTag)
+        private CallSafeHandle()
         {
-            AssertCallOk(grpcsharp_call_server_accept_old(this, cq, finishedTag));
         }
 
-        public void ServerAccept(CompletionQueueSafeHandle cq, EventCallbackDelegate callback)
+        public static CallSafeHandle Create(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)
         {
-            AssertCallOk(grpcsharp_call_server_accept_old_CALLBACK(this, cq, callback));
+            return grpcsharp_channel_create_call(channel, cq, method, host, deadline);
         }
 
-        public void ServerEndInitialMetadata(UInt32 flags)
+        public void StartUnary(byte[] payload, CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_server_end_initial_metadata_old(this, flags));
+            AssertCallOk(grpcsharp_call_start_unary(this, callback, payload, new UIntPtr((ulong) payload.Length)));
         }
 
-        public void StartWrite(byte[] payload, IntPtr tag, bool buffered)
+        public void StartClientStreaming(CompletionCallbackDelegate callback)
         {
-            grpcsharp_call_start_write_from_copied_buffer(this, payload, new UIntPtr((ulong) payload.Length), tag, GetFlags(buffered));
+            AssertCallOk(grpcsharp_call_start_client_streaming(this, callback));
         }
 
-        public void StartWrite(byte[] payload, bool buffered, EventCallbackDelegate callback)
+        public void StartServerStreaming(byte[] payload, CompletionCallbackDelegate callback)
         {
-            grpcsharp_call_start_write_from_copied_buffer_CALLBACK(this, payload, new UIntPtr((ulong) payload.Length), callback, GetFlags(buffered));
+            AssertCallOk(grpcsharp_call_start_server_streaming(this, callback, payload, new UIntPtr((ulong) payload.Length)));
         }
 
-        public void StartWriteStatus(Status status, IntPtr tag)
+        public void StartDuplexStreaming(CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_start_write_status_old(this, status.StatusCode, status.Detail, tag));
+            AssertCallOk(grpcsharp_call_start_duplex_streaming(this, callback));
         }
 
-        public void StartWriteStatus(Status status, EventCallbackDelegate callback)
+        public void StartSendMessage(byte[] payload, CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_start_write_status_old_CALLBACK(this, status.StatusCode, status.Detail, callback));
+            AssertCallOk(grpcsharp_call_send_message(this, callback, payload, new UIntPtr((ulong) payload.Length)));
         }
 
-        public void WritesDone(IntPtr tag)
+        public void StartSendCloseFromClient(CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_writes_done_old(this, tag));
+            AssertCallOk(grpcsharp_call_send_close_from_client(this, callback));
         }
 
-        public void WritesDone(EventCallbackDelegate callback)
+        public void StartSendStatusFromServer(Status status, CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_writes_done_old_CALLBACK(this, callback));
+            AssertCallOk(grpcsharp_call_send_status_from_server(this, callback, status.StatusCode, status.Detail));
         }
 
-        public void StartRead(IntPtr tag)
+        public void StartReceiveMessage(CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_start_read_old(this, tag));
+            AssertCallOk(grpcsharp_call_recv_message(this, callback));
         }
 
-        public void StartRead(EventCallbackDelegate callback)
+        public void StartServerSide(CompletionCallbackDelegate callback)
         {
-            AssertCallOk(grpcsharp_call_start_read_old_CALLBACK(this, callback));
+            AssertCallOk(grpcsharp_call_start_serverside(this, callback));
         }
 
         public void Cancel()
diff --git a/src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs b/src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs
index f6af64c96796add5a57bc9188b4be6997b90a3aa..f15ead35724d94ee4bc6b11b71543d7afa46bf5a 100644
--- a/src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/GrpcCore/Internal/ChannelSafeHandle.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -36,7 +36,7 @@ using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
     /// grpc_channel from <grpc/grpc.h>
@@ -64,4 +64,4 @@ namespace Google.GRPC.Core.Internal
 			return true;
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/src/csharp/GrpcCore/Internal/StreamingInputObserver.cs b/src/csharp/GrpcCore/Internal/ClientStreamingInputObserver.cs
similarity index 86%
rename from src/csharp/GrpcCore/Internal/StreamingInputObserver.cs
rename to src/csharp/GrpcCore/Internal/ClientStreamingInputObserver.cs
index 49410961cb4b4dbf9659717da349f85564bef094..fb59e86e2d7f8e0d017abc4b26910ac8cc2fcb65 100644
--- a/src/csharp/GrpcCore/Internal/StreamingInputObserver.cs
+++ b/src/csharp/GrpcCore/Internal/ClientStreamingInputObserver.cs
@@ -32,23 +32,24 @@
 #endregion
 
 using System;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
-    internal class StreamingInputObserver<TWrite, TRead> : IObserver<TWrite>
+    internal class ClientStreamingInputObserver<TWrite, TRead> : IObserver<TWrite>
 	{
         readonly AsyncCall<TWrite, TRead> call;
 
-        public StreamingInputObserver(AsyncCall<TWrite, TRead> call)
+        public ClientStreamingInputObserver(AsyncCall<TWrite, TRead> call)
 		{
             this.call = call;
 		}
 
 		public void OnCompleted()
 		{
+
             // TODO: how bad is the Wait here?
-            call.WritesCompletedAsync().Wait();
+            call.SendCloseFromClientAsync().Wait();
 		}
 
 		public void OnError(Exception error)
@@ -59,7 +60,7 @@ namespace Google.GRPC.Core.Internal
 		public void OnNext(TWrite value)
 		{
             // TODO: how bad is the Wait here?
-            call.WriteAsync(value).Wait();
+            call.SendMessageAsync(value).Wait();
 		}
 	}
 }
diff --git a/src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs b/src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs
index fc2b1d542100793c8989c573757698dc9214f446..3f01fdbfd05c70d4ac130681d6af1ab91a6530c7 100644
--- a/src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/GrpcCore/Internal/CompletionQueueSafeHandle.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -35,7 +35,7 @@ using System;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
     /// grpc_completion_queue from <grpc/grpc.h>
@@ -45,12 +45,6 @@ namespace Google.GRPC.Core.Internal
         [DllImport("grpc_csharp_ext.dll")]
         static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create();
 
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern EventSafeHandle grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag, Timespec deadline);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern EventSafeHandle grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq, Timespec deadline);
-
         [DllImport("grpc_csharp_ext.dll")]
         static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
 
@@ -69,21 +63,11 @@ namespace Google.GRPC.Core.Internal
             return grpcsharp_completion_queue_create();
         }
 
-        public EventSafeHandle Next(Timespec deadline)
-        {
-            return grpcsharp_completion_queue_next(this, deadline);
-        }
-
         public GRPCCompletionType NextWithCallback()
         {
             return grpcsharp_completion_queue_next_with_callback(this);
         }
 
-        public EventSafeHandle Pluck(IntPtr tag, Timespec deadline)
-        {
-            return grpcsharp_completion_queue_pluck(this, tag, deadline);
-        }
-
         public void Shutdown()
         {
             grpcsharp_completion_queue_shutdown(this);
diff --git a/src/csharp/GrpcCore/Internal/Enums.cs b/src/csharp/GrpcCore/Internal/Enums.cs
index c2eb1327b3f9f5e846d589c75d68d754a2d272c4..f363050b07e592583d0e34e681e367c54c4feb25 100644
--- a/src/csharp/GrpcCore/Internal/Enums.cs
+++ b/src/csharp/GrpcCore/Internal/Enums.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -34,7 +34,7 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
     /// from grpc/grpc.h
@@ -73,7 +73,7 @@ namespace Google.GRPC.Core.Internal
         GRPC_QUEUE_SHUTDOWN,
 
         /* operation completion */
-        GRPC_OP_COMPLETE,  
+        GRPC_OP_COMPLETE,
 
         /* A read has completed */
         GRPC_READ,
@@ -87,7 +87,7 @@ namespace Google.GRPC.Core.Internal
         /* The metadata array sent by server received at client */
         GRPC_CLIENT_METADATA_READ,
 
-        /* An RPC has finished. The event contains status. 
+        /* An RPC has finished. The event contains status.
          * On the server this will be OK or Cancelled. */
         GRPC_FINISHED,
 
diff --git a/src/csharp/GrpcCore/Internal/Event.cs b/src/csharp/GrpcCore/Internal/Event.cs
deleted file mode 100644
index 9229472ccd70ffbc1ba3465b3d5ce0d0a88c94e1..0000000000000000000000000000000000000000
--- a/src/csharp/GrpcCore/Internal/Event.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-#region Copyright notice and license
-
-// Copyright 2015, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using System;
-using System.Runtime.InteropServices;
-using Google.GRPC.Core;
-
-namespace Google.GRPC.Core.Internal
-{
-    /// <summary>
-    /// grpc_event from grpc/grpc.h
-    /// </summary>
-    internal class EventSafeHandle : SafeHandleZeroIsInvalid
-    {
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpcsharp_event_finish(IntPtr ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCompletionType grpcsharp_event_type(EventSafeHandle ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern CallSafeHandle grpcsharp_event_call(EventSafeHandle ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCOpError grpcsharp_event_write_accepted(EventSafeHandle ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCOpError grpcsharp_event_finish_accepted(EventSafeHandle ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern StatusCode grpcsharp_event_finished_status(EventSafeHandle ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_event_finished_details(EventSafeHandle ev);  // returns const char*
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_event_read_length(EventSafeHandle ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpcsharp_event_read_copy_to_buffer(EventSafeHandle ev, byte[] buffer, UIntPtr bufferLen);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_event_server_rpc_new_method(EventSafeHandle ev); // returns const char*
-
-        public GRPCCompletionType GetCompletionType()
-        {
-            return grpcsharp_event_type(this);
-        }
-
-        public GRPCOpError GetWriteAccepted()
-        {
-            return grpcsharp_event_write_accepted(this);
-        }
-
-        public GRPCOpError GetFinishAccepted()
-        {
-            return grpcsharp_event_finish_accepted(this);
-        }
-
-        public Status GetFinished()
-        {
-            // TODO: can the native method return string directly?
-            string details = Marshal.PtrToStringAnsi(grpcsharp_event_finished_details(this));
-            return new Status(grpcsharp_event_finished_status(this), details);
-        }
-
-        public byte[] GetReadData()
-        {
-            IntPtr len = grpcsharp_event_read_length(this);
-            if (len == new IntPtr(-1))
-            {
-                return null;
-            }
-            byte[] data = new byte[(int) len];
-            grpcsharp_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
-            return data;
-        }
-
-        public CallSafeHandle GetCall() {
-            return grpcsharp_event_call(this);
-        }
-
-        public string GetServerRpcNewMethod() {
-            // TODO: can the native method return string directly?
-            return Marshal.PtrToStringAnsi(grpcsharp_event_server_rpc_new_method(this));
-        }
-
-        //TODO: client_metadata_read event type
-
-        protected override bool ReleaseHandle()
-        {
-            grpcsharp_event_finish(handle);
-            return true;
-        }
-    }
-
-    // TODO: this is basically c&p of EventSafeHandle. Unify!
-    /// <summary>
-    /// Not owned version of 
-    /// grpc_event from grpc/grpc.h
-    /// </summary>
-    internal class EventSafeHandleNotOwned : SafeHandleZeroIsInvalid
-    {
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpcsharp_event_finish(IntPtr ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCompletionType grpcsharp_event_type(EventSafeHandleNotOwned ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern CallSafeHandle grpcsharp_event_call(EventSafeHandleNotOwned ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCOpError grpcsharp_event_write_accepted(EventSafeHandleNotOwned ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCOpError grpcsharp_event_finish_accepted(EventSafeHandleNotOwned ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern StatusCode grpcsharp_event_finished_status(EventSafeHandleNotOwned ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_event_finished_details(EventSafeHandleNotOwned ev);  // returns const char*
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_event_read_length(EventSafeHandleNotOwned ev);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpcsharp_event_read_copy_to_buffer(EventSafeHandleNotOwned ev, byte[] buffer, UIntPtr bufferLen);
-
-        [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_event_server_rpc_new_method(EventSafeHandleNotOwned ev); // returns const char*
-
-        public EventSafeHandleNotOwned() : base(false)
-        {
-        }
-
-        public EventSafeHandleNotOwned(IntPtr handle) : base(false)
-        {
-            SetHandle(handle);
-        }
-
-        public GRPCCompletionType GetCompletionType()
-        {
-            return grpcsharp_event_type(this);
-        }
-
-        public GRPCOpError GetWriteAccepted()
-        {
-            return grpcsharp_event_write_accepted(this);
-        }
-
-        public GRPCOpError GetFinishAccepted()
-        {
-            return grpcsharp_event_finish_accepted(this);
-        }
-
-        public Status GetFinished()
-        {
-            // TODO: can the native method return string directly?
-            string details = Marshal.PtrToStringAnsi(grpcsharp_event_finished_details(this));
-            return new Status(grpcsharp_event_finished_status(this), details);
-        }
-
-        public byte[] GetReadData()
-        {
-            IntPtr len = grpcsharp_event_read_length(this);
-            if (len == new IntPtr(-1))
-            {
-                return null;
-            }
-            byte[] data = new byte[(int) len];
-            grpcsharp_event_read_copy_to_buffer(this, data, new UIntPtr((ulong)data.Length));
-            return data;
-        }
-
-        public CallSafeHandle GetCall() {
-            return grpcsharp_event_call(this);
-        }
-
-        public string GetServerRpcNewMethod() {
-            // TODO: can the native method return string directly?
-            return Marshal.PtrToStringAnsi(grpcsharp_event_server_rpc_new_method(this));
-        }
-
-        //TODO: client_metadata_read event type
-
-        protected override bool ReleaseHandle()
-        {
-            grpcsharp_event_finish(handle);
-            return true;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/csharp/GrpcCore/Internal/GrpcThreadPool.cs b/src/csharp/GrpcCore/Internal/GrpcThreadPool.cs
index b768decc8c6add78b273b9cec11d24fb5bc700ce..9e69fe2f43090a51c4ef1f1b430f2c56050cd27e 100644
--- a/src/csharp/GrpcCore/Internal/GrpcThreadPool.cs
+++ b/src/csharp/GrpcCore/Internal/GrpcThreadPool.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,13 +32,13 @@
 #endregion
 
 using System;
-using Google.GRPC.Core.Internal;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
-using System.Collections.Generic;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
     /// Pool of threads polling on the same completion queue.
@@ -48,7 +48,6 @@ namespace Google.GRPC.Core.Internal
         readonly object myLock = new object();
         readonly List<Thread> threads = new List<Thread>();
         readonly int poolSize;
-        readonly Action<EventSafeHandle> eventHandler;
 
         CompletionQueueSafeHandle cq;
 
@@ -56,11 +55,6 @@ namespace Google.GRPC.Core.Internal
             this.poolSize = poolSize;
         }
 
-        internal GrpcThreadPool(int poolSize, Action<EventSafeHandle> eventHandler) {
-            this.poolSize = poolSize;
-            this.eventHandler = eventHandler;
-        }
-
         public void Start() {
 
             lock (myLock)
@@ -104,34 +98,19 @@ namespace Google.GRPC.Core.Internal
             }
         }
 
-        private Thread CreateAndStartThread(int i) {
-            Action body;
-            if (eventHandler != null)
-            {
-                body = ThreadBodyWithHandler;
-            }
-            else
-            {
-                body = ThreadBodyNoHandler;
-            }
-            var thread = new Thread(new ThreadStart(body));
+        private Thread CreateAndStartThread(int i)
+        {
+            var thread = new Thread(new ThreadStart(RunHandlerLoop));
             thread.IsBackground = false;
             thread.Start();
-            if (eventHandler != null)
-            {
-                thread.Name = "grpc_server_newrpc " + i;
-            }
-            else
-            {
-                thread.Name = "grpc " + i;
-            }
+            thread.Name = "grpc " + i;
             return thread;
         }
 
         /// <summary>
         /// Body of the polling thread.
         /// </summary>
-        private void ThreadBodyNoHandler()
+        private void RunHandlerLoop()
         {
             GRPCCompletionType completionType;
             do
@@ -140,22 +119,6 @@ namespace Google.GRPC.Core.Internal
             } while(completionType != GRPCCompletionType.GRPC_QUEUE_SHUTDOWN);
             Console.WriteLine("Completion queue has shutdown successfully, thread " + Thread.CurrentThread.Name + " exiting.");
         }
-
-        /// <summary>
-        /// Body of the polling thread.
-        /// </summary>
-        private void ThreadBodyWithHandler()
-        {
-            GRPCCompletionType completionType;
-            do
-            {
-                using (EventSafeHandle ev = cq.Next(Timespec.InfFuture)) {
-                    completionType = ev.GetCompletionType();
-                    eventHandler(ev);
-                }
-            } while(completionType != GRPCCompletionType.GRPC_QUEUE_SHUTDOWN);
-            Console.WriteLine("Completion queue has shutdown successfully, thread " + Thread.CurrentThread.Name + " exiting.");
-        }
     }
 
 }
diff --git a/src/csharp/GrpcCore/Internal/SafeHandleZeroIsInvalid.cs b/src/csharp/GrpcCore/Internal/SafeHandleZeroIsInvalid.cs
index c7d8a0a3c3887d1e98623fbed8bc583cbe4f6469..aa6fce2e969ec4dc097fc07d0e6dc5c5491a9e4d 100644
--- a/src/csharp/GrpcCore/Internal/SafeHandleZeroIsInvalid.cs
+++ b/src/csharp/GrpcCore/Internal/SafeHandleZeroIsInvalid.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -34,7 +34,7 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
     /// Safe handle to wrap native objects.
@@ -56,6 +56,12 @@ namespace Google.GRPC.Core.Internal
                 return handle == IntPtr.Zero;
             }
         }
+
+        protected override bool ReleaseHandle()
+        {
+            // handle is not owned.
+            return true;
+        }
     }
 }
 
diff --git a/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs b/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
index 2ae0ad237d86fa663f19414b26e3def6962a9699..de9bbaf7c123587e495f6bcfc17c2238ec41c75b 100644
--- a/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
+++ b/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,30 +32,28 @@
 #endregion
 
 using System;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
 using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
+    // TODO: we need to make sure that the delegates are not collected before invoked.
+    internal delegate void ServerShutdownCallbackDelegate(IntPtr eventPtr);
+
     /// <summary>
     /// grpc_server from grpc/grpc.h
     /// </summary>
     internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
     {
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_request_call_old")]
-        static extern GRPCCallError grpcsharp_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
-
         [DllImport("grpc_csharp_ext.dll")]
-        static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
+        static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
-        // TODO: check int representation size
         [DllImport("grpc_csharp_ext.dll")]
-        static extern int grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
+        static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
 
-        // TODO: check int representation size
         [DllImport("grpc_csharp_ext.dll")]
-        static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr);
+        static extern Int32 grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
 
         [DllImport("grpc_csharp_ext.dll")]
         static extern void grpcsharp_server_start(ServerSafeHandle server);
@@ -63,8 +61,9 @@ namespace Google.GRPC.Core.Internal
         [DllImport("grpc_csharp_ext.dll")]
         static extern void grpcsharp_server_shutdown(ServerSafeHandle server);
 
+        // TODO: get rid of the old callback style
         [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_shutdown_and_notify")]
-        static extern void grpcsharp_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
+        static extern void grpcsharp_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] ServerShutdownCallbackDelegate callback);
 
         [DllImport("grpc_csharp_ext.dll")]
         static extern void grpcsharp_server_destroy(IntPtr server);
@@ -81,7 +80,6 @@ namespace Google.GRPC.Core.Internal
 
         public int AddPort(string addr)
         {
-            // TODO: also grpc_server_add_secure_http2_port...
             return grpcsharp_server_add_http2_port(this, addr);
         }
 
@@ -95,14 +93,14 @@ namespace Google.GRPC.Core.Internal
             grpcsharp_server_shutdown(this);
         }
 
-        public void ShutdownAndNotify(EventCallbackDelegate callback)
+        public void ShutdownAndNotify(ServerShutdownCallbackDelegate callback)
         {
             grpcsharp_server_shutdown_and_notify_CALLBACK(this, callback);
         }
 
-        public GRPCCallError RequestCall(EventCallbackDelegate callback)
+        public GRPCCallError RequestCall(CompletionQueueSafeHandle cq, CompletionCallbackDelegate callback)
         {
-            return grpcsharp_server_request_call_old_CALLBACK(this, callback);
+            return grpcsharp_server_request_call(this, cq, callback);
         }
 
         protected override bool ReleaseHandle()
@@ -111,4 +109,4 @@ namespace Google.GRPC.Core.Internal
             return true;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/GrpcCore/Internal/ServerWritingObserver.cs b/src/csharp/GrpcCore/Internal/ServerStreamingOutputObserver.cs
similarity index 84%
rename from src/csharp/GrpcCore/Internal/ServerWritingObserver.cs
rename to src/csharp/GrpcCore/Internal/ServerStreamingOutputObserver.cs
index 11207918426cc01679f5bc65153b15fa155defb1..08d99214754bd9316a75f5a252fc0861694bbe7a 100644
--- a/src/csharp/GrpcCore/Internal/ServerWritingObserver.cs
+++ b/src/csharp/GrpcCore/Internal/ServerStreamingOutputObserver.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,19 +32,19 @@
 #endregion
 
 using System;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
     /// <summary>
     /// Observer that writes all arriving messages to a call abstraction (in blocking fashion)
     /// and then halfcloses the call. Used for server-side call handling.
     /// </summary>
-    internal class ServerWritingObserver<TWrite, TRead> : IObserver<TWrite>
+    internal class ServerStreamingOutputObserver<TWrite, TRead> : IObserver<TWrite>
 	{
         readonly AsyncCall<TWrite, TRead> call;
 
-        public ServerWritingObserver(AsyncCall<TWrite, TRead> call)
+        public ServerStreamingOutputObserver(AsyncCall<TWrite, TRead> call)
 		{
             this.call = call;
 		}
@@ -52,19 +52,19 @@ namespace Google.GRPC.Core.Internal
 		public void OnCompleted()
 		{
             // TODO: how bad is the Wait here?
-            call.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_OK, "")).Wait();
+            call.SendStatusFromServerAsync(new Status(StatusCode.OK, "")).Wait();
 		}
 
 		public void OnError(Exception error)
 		{
-            // TODO: handle this...
+            // TODO: implement this...
 			throw new InvalidOperationException("This should never be called.");
 		}
 
 		public void OnNext(TWrite value)
 		{
             // TODO: how bad is the Wait here?
-            call.WriteAsync(value).Wait();
+            call.SendMessageAsync(value).Wait();
 		}
 	}
 }
diff --git a/src/csharp/GrpcCore/Internal/Timespec.cs b/src/csharp/GrpcCore/Internal/Timespec.cs
index 651003dae8b7be9e5260aaa56873de3cc041d809..b191ecde94cc6e3e96cf966de8fe6813ab5b2628 100644
--- a/src/csharp/GrpcCore/Internal/Timespec.cs
+++ b/src/csharp/GrpcCore/Internal/Timespec.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -35,7 +35,7 @@ using System;
 using System.Runtime.InteropServices;
 using System.Threading;
 
-namespace Google.GRPC.Core.Internal
+namespace Grpc.Core.Internal
 {
 	/// <summary>
 	/// gpr_timespec from grpc/support/time.h
@@ -106,7 +106,7 @@ namespace Google.GRPC.Core.Internal
 
             Timespec result;
             result.tv_nsec = new IntPtr(nanos % nanosPerSecond);
-            result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec); 
+            result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec);
             return result;
         }
 	}
diff --git a/src/csharp/GrpcCore/Marshaller.cs b/src/csharp/GrpcCore/Marshaller.cs
index 21bd26650b5c7771893c465b6bd93179a818f6ad..602e0eb8240f4e3e7b258d3f1e370fe35ee437bc 100644
--- a/src/csharp/GrpcCore/Marshaller.cs
+++ b/src/csharp/GrpcCore/Marshaller.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,7 +33,7 @@
 
 using System;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     /// <summary>
     /// For serializing and deserializing messages.
@@ -77,7 +77,7 @@ namespace Google.GRPC.Core
         {
             get
             {
-                return new Marshaller<string>(System.Text.Encoding.UTF8.GetBytes, 
+                return new Marshaller<string>(System.Text.Encoding.UTF8.GetBytes,
                                               System.Text.Encoding.UTF8.GetString);
             }
         }
diff --git a/src/csharp/GrpcCore/Method.cs b/src/csharp/GrpcCore/Method.cs
index a8c647035d826c016ed265038317f61988c6f07b..c94aa8161fe7fb7aa2deb488ce003c88ce937d1c 100644
--- a/src/csharp/GrpcCore/Method.cs
+++ b/src/csharp/GrpcCore/Method.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,7 +33,7 @@
 
 using System;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     public enum MethodType
     {
diff --git a/src/csharp/GrpcCore/Properties/AssemblyInfo.cs b/src/csharp/GrpcCore/Properties/AssemblyInfo.cs
index 74aba25767844a4c7f8b5df55c67ab59b8b9c38a..ed3a7af8f409b1a508aab6e5896efa8c32a3dd48 100644
--- a/src/csharp/GrpcCore/Properties/AssemblyInfo.cs
+++ b/src/csharp/GrpcCore/Properties/AssemblyInfo.cs
@@ -1,21 +1,21 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-// Information about this assembly is defined by the following attributes. 
+// Information about this assembly is defined by the following attributes.
 // Change them to the values specific to your project.
 [assembly: AssemblyTitle ("GrpcCore")]
 [assembly: AssemblyDescription ("")]
 [assembly: AssemblyConfiguration ("")]
 [assembly: AssemblyCompany ("")]
 [assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("jtattermusch")]
+[assembly: AssemblyCopyright ("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark ("")]
 [assembly: AssemblyCulture ("")]
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion ("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly, 
+[assembly: AssemblyVersion ("0.9.*")]
+// The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
diff --git a/src/csharp/GrpcCore/RpcException.cs b/src/csharp/GrpcCore/RpcException.cs
index 5d1ca3bcdf35cbaa814181111c1281e2e69d0a63..5a9d0039bc9129c781e207d301f857d780574675 100644
--- a/src/csharp/GrpcCore/RpcException.cs
+++ b/src/csharp/GrpcCore/RpcException.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,7 +33,7 @@
 
 using System;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     public class RpcException : Exception
     {
diff --git a/src/csharp/GrpcCore/Server.cs b/src/csharp/GrpcCore/Server.cs
index 62ffa70b713b17383b014d1e624e7e270739ffa1..002592a3d888e9630f58a3fa7730ef7b130f7897 100644
--- a/src/csharp/GrpcCore/Server.cs
+++ b/src/csharp/GrpcCore/Server.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,14 +32,14 @@
 #endregion
 
 using System;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
-using System.Threading.Tasks;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
-using Google.GRPC.Core.Internal;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     /// <summary>
     /// Server is implemented only to be able to do
@@ -47,10 +47,10 @@ namespace Google.GRPC.Core
     /// </summary>
     public class Server
     {
-        // TODO: make sure the delegate doesn't get garbage collected while 
+        // TODO: make sure the delegate doesn't get garbage collected while
         // native callbacks are in the completion queue.
-        readonly EventCallbackDelegate newRpcHandler;
-        readonly EventCallbackDelegate serverShutdownHandler;
+        readonly ServerShutdownCallbackDelegate serverShutdownHandler;
+        readonly CompletionCallbackDelegate newServerRpcHandler;
 
         readonly BlockingCollection<NewRpcInfo> newRpcQueue = new BlockingCollection<NewRpcInfo>();
         readonly ServerSafeHandle handle;
@@ -61,9 +61,8 @@ namespace Google.GRPC.Core
 
         public Server()
         {
-            // TODO: what is the tag for server shutdown?
             this.handle = ServerSafeHandle.NewServer(GetCompletionQueue(), IntPtr.Zero);
-            this.newRpcHandler = HandleNewRpc;
+            this.newServerRpcHandler = HandleNewServerRpc;
             this.serverShutdownHandler = HandleServerShutdown;
         }
 
@@ -94,18 +93,18 @@ namespace Google.GRPC.Core
         internal void RunRpc()
         {
             AllowOneRpc();
-         
+
             try
             {
                 var rpcInfo = newRpcQueue.Take();
 
-                Console.WriteLine("Server received RPC " + rpcInfo.Method);
+                //Console.WriteLine("Server received RPC " + rpcInfo.Method);
 
                 IServerCallHandler callHandler;
                 if (!callHandlers.TryGetValue(rpcInfo.Method, out callHandler))
                 {
                     callHandler = new NoSuchMethodCallHandler();
-                } 
+                }
                 callHandler.StartCall(rpcInfo.Method, rpcInfo.Call, GetCompletionQueue());
             }
             catch(Exception e)
@@ -138,23 +137,25 @@ namespace Google.GRPC.Core
 
         private void AllowOneRpc()
         {
-            AssertCallOk(handle.RequestCall(newRpcHandler));
+            AssertCallOk(handle.RequestCall(GetCompletionQueue(), newServerRpcHandler));
         }
 
-        private void HandleNewRpc(IntPtr eventPtr)
-        {
-            try
-            {
-                var ev = new EventSafeHandleNotOwned(eventPtr);
-                var rpcInfo = new NewRpcInfo(ev.GetCall(), ev.GetServerRpcNewMethod());
+        private void HandleNewServerRpc(GRPCOpError error, IntPtr batchContextPtr) {
+            try {
+                var ctx = new BatchContextSafeHandleNotOwned(batchContextPtr);
+
+                if (error != GRPCOpError.GRPC_OP_OK) {
+                    // TODO: handle error
+                }
+
+                var rpcInfo = new NewRpcInfo(ctx.GetServerRpcNewCall(), ctx.GetServerRpcNewMethod());
 
                 // after server shutdown, the callback returns with null call
                 if (!rpcInfo.Call.IsInvalid) {
                     newRpcQueue.Add(rpcInfo);
                 }
-            }
-            catch (Exception e)
-            {
+
+            } catch(Exception e) {
                 Console.WriteLine("Caught exception in a native handler: " + e);
             }
         }
@@ -209,4 +210,4 @@ namespace Google.GRPC.Core
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/GrpcCore/ServerCallHandler.cs b/src/csharp/GrpcCore/ServerCallHandler.cs
index 12d0c936348b42b3264a90c2eeaa92e861653d6f..1296947f34d56569039593d2bc3d7a2aeb61652c 100644
--- a/src/csharp/GrpcCore/ServerCallHandler.cs
+++ b/src/csharp/GrpcCore/ServerCallHandler.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,9 +32,9 @@
 #endregion
 
 using System;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     internal interface IServerCallHandler
     {
@@ -59,15 +59,16 @@ namespace Google.GRPC.Core
                 method.RequestMarshaller.Deserializer);
 
             asyncCall.InitializeServer(call);
-            asyncCall.Accept(cq);
            
-            var request = asyncCall.ReadAsync().Result;
+            var finishedTask = asyncCall.ServerSideUnaryRequestCallAsync();
 
-            var responseObserver = new ServerWritingObserver<TResponse, TRequest>(asyncCall);
+            var request = asyncCall.ReceiveMessageAsync().Result;
+
+            var responseObserver = new ServerStreamingOutputObserver<TResponse, TRequest>(asyncCall);
             handler(request, responseObserver);
 
-            asyncCall.Halfclosed.Wait();
-            asyncCall.Finished.Wait();
+            finishedTask.Wait();
+
         }
     }
 
@@ -89,16 +90,11 @@ namespace Google.GRPC.Core
                 method.RequestMarshaller.Deserializer);
 
             asyncCall.InitializeServer(call);
-            asyncCall.Accept(cq);
 
-            var responseObserver = new ServerWritingObserver<TResponse, TRequest>(asyncCall);
+            var responseObserver = new ServerStreamingOutputObserver<TResponse, TRequest>(asyncCall);
             var requestObserver = handler(responseObserver);
-
-            // feed the requests
-            asyncCall.StartReadingToStream(requestObserver);
-
-            asyncCall.Halfclosed.Wait();
-            asyncCall.Finished.Wait();
+            var finishedTask = asyncCall.ServerSideStreamingRequestCallAsync(requestObserver);
+            finishedTask.Wait();
         }
     }
 
@@ -110,12 +106,31 @@ namespace Google.GRPC.Core
             AsyncCall<byte[], byte[]> asyncCall = new AsyncCall<byte[], byte[]>(
                 (payload) => payload, (payload) => payload);
 
+
             asyncCall.InitializeServer(call);
-            asyncCall.Accept(cq);
-            asyncCall.WriteStatusAsync(new Status(StatusCode.GRPC_STATUS_UNIMPLEMENTED, "No such method.")).Wait();
 
-            asyncCall.Finished.Wait();
+            var finishedTask = asyncCall.ServerSideStreamingRequestCallAsync(new NullObserver<byte[]>());
+
+            asyncCall.SendStatusFromServerAsync(new Status(StatusCode.Unimplemented, "No such method.")).Wait();
+
+            finishedTask.Wait();
         }
     }
+
+    internal class NullObserver<T> : IObserver<T>
+    {
+        public void OnCompleted()
+        {
+        }
+
+        public void OnError(Exception error)
+        {
+        }
+
+        public void OnNext(T value)
+        {
+        }
+
+    }
 }
 
diff --git a/src/csharp/GrpcCore/ServerCalls.cs b/src/csharp/GrpcCore/ServerCalls.cs
index b95a0d97b4fcd86c20d7d52cd569860c4f4e2214..bed77796de10e7bedc3962326660d0eabd45afcf 100644
--- a/src/csharp/GrpcCore/ServerCalls.cs
+++ b/src/csharp/GrpcCore/ServerCalls.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,7 +33,7 @@
 
 using System;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     // TODO: perhaps add also serverSideStreaming and clientSideStreaming
 
diff --git a/src/csharp/GrpcCore/ServerServiceDefinition.cs b/src/csharp/GrpcCore/ServerServiceDefinition.cs
index f0b4daf0719689336b510d36e47be8d488da1db9..231c37606205fca9aa2fa700c40422bb90bd0dc4 100644
--- a/src/csharp/GrpcCore/ServerServiceDefinition.cs
+++ b/src/csharp/GrpcCore/ServerServiceDefinition.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -34,7 +34,7 @@
 using System;
 using System.Collections.Generic;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     public class ServerServiceDefinition
     {
@@ -73,7 +73,7 @@ namespace Google.GRPC.Core
             }
 
             public Builder AddMethod<TRequest, TResponse>(
-                Method<TRequest, TResponse> method, 
+                Method<TRequest, TResponse> method,
                 UnaryRequestServerMethod<TRequest, TResponse> handler)
             {
                 callHandlers.Add(method.Name, ServerCalls.UnaryRequestCall(method, handler));
@@ -81,7 +81,7 @@ namespace Google.GRPC.Core
             }
 
             public Builder AddMethod<TRequest, TResponse>(
-                Method<TRequest, TResponse> method, 
+                Method<TRequest, TResponse> method,
                 StreamingRequestServerMethod<TRequest, TResponse> handler)
             {
                 callHandlers.Add(method.Name, ServerCalls.StreamingRequestCall(method, handler));
diff --git a/src/csharp/GrpcCore/Status.cs b/src/csharp/GrpcCore/Status.cs
index dce1e24d7ea265751421aeac833e35b386648341..5ea1df7b481c2bec149fb0550f04b152a427b336 100644
--- a/src/csharp/GrpcCore/Status.cs
+++ b/src/csharp/GrpcCore/Status.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -34,7 +34,7 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
 	/// <summary>
 	/// Represents RPC result.
@@ -66,4 +66,4 @@ namespace Google.GRPC.Core
 			}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/src/csharp/GrpcCore/StatusCode.cs b/src/csharp/GrpcCore/StatusCode.cs
index eccaae72f6d70b5ccbb857cc0737148825e7ba55..1fbf9c1b68762a8068496fae9c9d78c897d74acb 100644
--- a/src/csharp/GrpcCore/StatusCode.cs
+++ b/src/csharp/GrpcCore/StatusCode.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,22 +33,22 @@
 
 using System;
 
-namespace Google.GRPC.Core
+namespace Grpc.Core
 {
     // TODO: element names should changed to comply with C# naming conventions.
     /// <summary>
-    /// grpc_status_code from grpc/status.h
+    /// based on grpc_status_code from grpc/status.h
     /// </summary>
     public enum StatusCode
     {
         /* Not an error; returned on success
 
      HTTP Mapping: 200 OK */
-        GRPC_STATUS_OK = 0,
+        OK = 0,
         /* The operation was cancelled (typically by the caller).
 
      HTTP Mapping: 499 Client Closed Request */
-        GRPC_STATUS_CANCELLED = 1,
+        Cancelled = 1,
         /* Unknown error.  An example of where this error may be returned is
      if a Status value received from another address space belongs to
      an error-space that is not known in this address space.  Also
@@ -56,14 +56,14 @@ namespace Google.GRPC.Core
      may be converted to this error.
 
      HTTP Mapping: 500 Internal Server Error */
-        GRPC_STATUS_UNKNOWN = 2,
+        Unknown = 2,
         /* Client specified an invalid argument.  Note that this differs
      from FAILED_PRECONDITION.  INVALID_ARGUMENT indicates arguments
      that are problematic regardless of the state of the system
      (e.g., a malformed file name).
 
      HTTP Mapping: 400 Bad Request */
-        GRPC_STATUS_INVALID_ARGUMENT = 3,
+        InvalidArgument = 3,
         /* Deadline expired before operation could complete.  For operations
      that change the state of the system, this error may be returned
      even if the operation has completed successfully.  For example, a
@@ -71,16 +71,16 @@ namespace Google.GRPC.Core
      enough for the deadline to expire.
 
      HTTP Mapping: 504 Gateway Timeout */
-        GRPC_STATUS_DEADLINE_EXCEEDED = 4,
+        DeadlineExceeded = 4,
         /* Some requested entity (e.g., file or directory) was not found.
 
      HTTP Mapping: 404 Not Found */
-        GRPC_STATUS_NOT_FOUND = 5,
+        NotFound = 5,
         /* Some entity that we attempted to create (e.g., file or directory)
      already exists.
 
      HTTP Mapping: 409 Conflict */
-        GRPC_STATUS_ALREADY_EXISTS = 6,
+        AlreadyExists = 6,
         /* The caller does not have permission to execute the specified
      operation.  PERMISSION_DENIED must not be used for rejections
      caused by exhausting some resource (use RESOURCE_EXHAUSTED
@@ -89,17 +89,17 @@ namespace Google.GRPC.Core
      instead for those errors).
 
      HTTP Mapping: 403 Forbidden */
-        GRPC_STATUS_PERMISSION_DENIED = 7,
+        PermissionDenied = 7,
         /* The request does not have valid authentication credentials for the
      operation.
 
      HTTP Mapping: 401 Unauthorized */
-        GRPC_STATUS_UNAUTHENTICATED = 16,
+        Unauthenticated = 16,
         /* Some resource has been exhausted, perhaps a per-user quota, or
      perhaps the entire file system is out of space.
 
      HTTP Mapping: 429 Too Many Requests */
-        GRPC_STATUS_RESOURCE_EXHAUSTED = 8,
+        ResourceExhausted = 8,
         /* Operation was rejected because the system is not in a state
      required for the operation's execution.  For example, directory
      to be deleted may be non-empty, an rmdir operation is applied to
@@ -126,7 +126,7 @@ namespace Google.GRPC.Core
      the request contains Etag related headers. So if the server does see
      Etag related headers in the request, it may choose to return 412
      instead of 400 for this error code. */
-        GRPC_STATUS_FAILED_PRECONDITION = 9,
+        FailedPrecondition = 9,
         /* The operation was aborted, typically due to a concurrency issue
      like sequencer check failures, transaction aborts, etc.
 
@@ -134,7 +134,7 @@ namespace Google.GRPC.Core
      ABORTED, and UNAVAILABLE.
 
      HTTP Mapping: 409 Conflict */
-        GRPC_STATUS_ABORTED = 10,
+        Aborted = 10,
         /* Operation was attempted past the valid range.  E.g., seeking or
      reading past end of file.
 
@@ -152,17 +152,17 @@ namespace Google.GRPC.Core
      they are done.
 
      HTTP Mapping: 400 Bad Request */
-        GRPC_STATUS_OUT_OF_RANGE = 11,
+        OutOfRange = 11,
         /* Operation is not implemented or not supported/enabled in this service.
 
      HTTP Mapping: 501 Not Implemented */
-        GRPC_STATUS_UNIMPLEMENTED = 12,
+        Unimplemented = 12,
         /* Internal errors.  Means some invariants expected by underlying
      system has been broken.  If you see one of these errors,
      something is very broken.
 
      HTTP Mapping: 500 Internal Server Error */
-        GRPC_STATUS_INTERNAL = 13,
+        Internal = 13,
         /* The service is currently unavailable.  This is a most likely a
      transient condition and may be corrected by retrying with
      a backoff.
@@ -171,13 +171,11 @@ namespace Google.GRPC.Core
      ABORTED, and UNAVAILABLE.
 
      HTTP Mapping: 503 Service Unavailable */
-        GRPC_STATUS_UNAVAILABLE = 14,
+        Unavailable = 14,
         /* Unrecoverable data loss or corruption.
 
      HTTP Mapping: 500 Internal Server Error */
-        GRPC_STATUS_DATA_LOSS = 15,
-        /* Force users to include a default branch: */
-        GRPC_STATUS__DO_NOT_USE = -1
+        DataLoss = 15
     }
 }
 
diff --git a/src/csharp/GrpcCore/Utils/RecordingObserver.cs b/src/csharp/GrpcCore/Utils/RecordingObserver.cs
index 0cadfc0e4a04974f2bef145613a045388d05cd8b..99d2725b70eda679b4c0679eb5d40365c67279a2 100644
--- a/src/csharp/GrpcCore/Utils/RecordingObserver.cs
+++ b/src/csharp/GrpcCore/Utils/RecordingObserver.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,10 +32,10 @@
 #endregion
 
 using System;
-using System.Threading.Tasks;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 
-namespace Google.GRPC.Core.Utils
+namespace Grpc.Core.Utils
 {
     public class RecordingObserver<T> : IObserver<T>
     {
diff --git a/src/csharp/GrpcCore/Utils/RecordingQueue.cs b/src/csharp/GrpcCore/Utils/RecordingQueue.cs
index d73fc0fc78599bef7e8180683896c4dd0889b44e..63992da6a95d8aa24ca72f5cf951ef7a87fe90ee 100644
--- a/src/csharp/GrpcCore/Utils/RecordingQueue.cs
+++ b/src/csharp/GrpcCore/Utils/RecordingQueue.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -36,12 +36,12 @@ using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Collections.Concurrent;
 
-namespace Google.GRPC.Core.Utils
+namespace Grpc.Core.Utils
 {
     // TODO: replace this by something that implements IAsyncEnumerator.
     /// <summary>
     /// Observer that allows us to await incoming messages one-by-one.
-    /// The implementation is not ideal and class will be probably replaced 
+    /// The implementation is not ideal and class will be probably replaced
     /// by something more versatile in the future.
     /// </summary>
     public class RecordingQueue<T> : IObserver<T>
diff --git a/src/csharp/GrpcCoreTests/ClientServerTest.cs b/src/csharp/GrpcCoreTests/ClientServerTest.cs
index 1472db6e07e6ea47331eb43e0c90afdd15e92c3d..7e564a2fba59b190f54be1970ae785187ac2c1fd 100644
--- a/src/csharp/GrpcCoreTests/ClientServerTest.cs
+++ b/src/csharp/GrpcCoreTests/ClientServerTest.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,14 +32,15 @@
 #endregion
 
 using System;
-using NUnit.Framework;
-using Google.GRPC.Core;
-using Google.GRPC.Core.Internal;
+using System.Diagnostics;
 using System.Threading;
 using System.Threading.Tasks;
-using Google.GRPC.Core.Utils;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
 
-namespace Google.GRPC.Core.Tests
+namespace Grpc.Core.Tests
 {
     public class ClientServerTest
     {
@@ -51,11 +52,21 @@ namespace Google.GRPC.Core.Tests
             Marshallers.StringMarshaller,
             Marshallers.StringMarshaller);
 
-        [Test]
-        public void EmptyCall()
+        [TestFixtureSetUp]
+        public void Init()
         {
             GrpcEnvironment.Initialize();
+        }
 
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            GrpcEnvironment.Shutdown();
+        }
+
+        [Test]
+        public void UnaryCall()
+        {
             Server server = new Server();
             server.AddServiceDefinition(
                 ServerServiceDefinition.CreateBuilder("someService")
@@ -69,19 +80,71 @@ namespace Google.GRPC.Core.Tests
                 var call = new Call<string, string>(unaryEchoStringMethod, channel);
 
                 Assert.AreEqual("ABC", Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken)));
+
                 Assert.AreEqual("abcdef", Calls.BlockingUnaryCall(call, "abcdef", default(CancellationToken)));
             }
-         
+
             server.ShutdownAsync().Wait();
+        }
 
-            GrpcEnvironment.Shutdown();
+        [Test]
+        public void UnaryCallPerformance()
+        {
+            Server server = new Server();
+            server.AddServiceDefinition(
+                ServerServiceDefinition.CreateBuilder("someService")
+                .AddMethod(unaryEchoStringMethod, HandleUnaryEchoString).Build());
+
+            int port = server.AddPort(host + ":0");
+            server.Start();
+
+            using (Channel channel = new Channel(host + ":" + port))
+            {
+                var call = new Call<string, string>(unaryEchoStringMethod, channel);
+
+                var stopwatch = new Stopwatch();
+                stopwatch.Start();
+                for (int i = 0; i < 1000; i++)
+                {
+                    Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken));
+                }
+                stopwatch.Stop();
+                Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms");
+            }
+
+            server.ShutdownAsync().Wait();
+        }
+
+        [Test]
+        public void UnknownMethodHandler()
+        {
+            Server server = new Server();
+            server.AddServiceDefinition(
+                ServerServiceDefinition.CreateBuilder("someService").Build());
+
+            int port = server.AddPort(host + ":0");
+            server.Start();
+
+            using (Channel channel = new Channel(host + ":" + port))
+            {
+                var call = new Call<string, string>(unaryEchoStringMethod, channel);
+
+                try {
+                    Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken));
+                    Assert.Fail();
+                } catch(RpcException e) {
+                    Assert.AreEqual(StatusCode.Unimplemented, e.Status.StatusCode);
+                }
+            }
+
+            server.ShutdownAsync().Wait();
         }
 
-        private void HandleUnaryEchoString(string request, IObserver<string> responseObserver) {
+        private void HandleUnaryEchoString(string request, IObserver<string> responseObserver)
+        {
             responseObserver.OnNext(request);
             responseObserver.OnCompleted();
         }
-
     }
 }
 
diff --git a/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs b/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs
index 1bc6cce401770a9d4fdea09e76e426dfdad36b9c..8d3aef946a6358cb3cce15eddd8d11094debc2d3 100644
--- a/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs
+++ b/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,11 +32,11 @@
 #endregion
 
 using System;
-using NUnit.Framework;
-using Google.GRPC.Core;
 using System.Threading;
+using Grpc.Core;
+using NUnit.Framework;
 
-namespace Google.GRPC.Core.Tests
+namespace Grpc.Core.Tests
 {
     public class GrpcEnvironmentTest
     {
diff --git a/src/csharp/GrpcCoreTests/Properties/AssemblyInfo.cs b/src/csharp/GrpcCoreTests/Properties/AssemblyInfo.cs
index 565b1e2bd65b326f5b243e88895df9e64039fc82..07f35556dfe2aaaf0c96ce0ccc31f47b669b55c8 100644
--- a/src/csharp/GrpcCoreTests/Properties/AssemblyInfo.cs
+++ b/src/csharp/GrpcCoreTests/Properties/AssemblyInfo.cs
@@ -1,21 +1,21 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-// Information about this assembly is defined by the following attributes. 
+// Information about this assembly is defined by the following attributes.
 // Change them to the values specific to your project.
 [assembly: AssemblyTitle("GrpcCoreTests")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("jtattermusch")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly, 
+[assembly: AssemblyVersion("0.9.*")]
+// The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
diff --git a/src/csharp/GrpcCoreTests/ServerTest.cs b/src/csharp/GrpcCoreTests/ServerTest.cs
index 1c70a3d6c4421d925fcd5af89d436c0c61e6cfae..dd30366f6a1286684783b72848121238739f8d45 100644
--- a/src/csharp/GrpcCoreTests/ServerTest.cs
+++ b/src/csharp/GrpcCoreTests/ServerTest.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,12 +32,12 @@
 #endregion
 
 using System;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
 using NUnit.Framework;
-using Google.GRPC.Core.Internal;
-using Google.GRPC.Core;
-using Google.GRPC.Core.Utils;
 
-namespace Google.GRPC.Core.Tests
+namespace Grpc.Core.Tests
 {
     public class ServerTest
     {
@@ -47,7 +47,7 @@ namespace Google.GRPC.Core.Tests
             GrpcEnvironment.Initialize();
 
             Server server = new Server();
-            int port = server.AddPort("localhost:0");
+            server.AddPort("localhost:0");
             server.Start();
             server.ShutdownAsync().Wait();
 
diff --git a/src/csharp/GrpcCoreTests/TestResult.xml b/src/csharp/GrpcCoreTests/TestResult.xml
index a5a6abd7b958c05ca4d263d7053fbc62fd18cc66..13da80739ceead3bd6e8477089ed94a9165d0a9b 100644
--- a/src/csharp/GrpcCoreTests/TestResult.xml
+++ b/src/csharp/GrpcCoreTests/TestResult.xml
@@ -15,17 +15,17 @@
                     <results>
                       <test-suite type="TestFixture" name="CallsTest" executed="True" result="Success" success="True" time="0.009" asserts="0">
                         <results>
-                          <test-case name="Google.GRPC.Core.Tests.CallsTest.Test1" executed="True" result="Success" success="True" time="0.004" asserts="0" />
+                          <test-case name="Grpc.Core.Tests.CallsTest.Test1" executed="True" result="Success" success="True" time="0.004" asserts="0" />
                         </results>
                       </test-suite>
                       <test-suite type="TestFixture" name="ClientServerTest" executed="True" result="Success" success="True" time="0.149" asserts="0">
                         <results>
-                          <test-case name="Google.GRPC.Core.Tests.ClientServerTest.EmptyCall" executed="True" result="Success" success="True" time="0.111" asserts="0" />
+                          <test-case name="Grpc.Core.Tests.ClientServerTest.EmptyCall" executed="True" result="Success" success="True" time="0.111" asserts="0" />
                         </results>
                       </test-suite>
                       <test-suite type="TestFixture" name="ServerTest" executed="True" result="Success" success="True" time="0.001" asserts="0">
                         <results>
-                          <test-case name="Google.GRPC.Core.Tests.ServerTest.StartAndShutdownServer" executed="True" result="Success" success="True" time="0.001" asserts="0" />
+                          <test-case name="Grpc.Core.Tests.ServerTest.StartAndShutdownServer" executed="True" result="Success" success="True" time="0.001" asserts="0" />
                         </results>
                       </test-suite>
                     </results>
diff --git a/src/csharp/GrpcCoreTests/TimespecTest.cs b/src/csharp/GrpcCoreTests/TimespecTest.cs
index 2b03513cb7affbaa2e891b194e2b0e3cdd649af3..0ca84ec44bfcdf38dec68e4c5dc360997fc96c06 100644
--- a/src/csharp/GrpcCoreTests/TimespecTest.cs
+++ b/src/csharp/GrpcCoreTests/TimespecTest.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -32,11 +32,11 @@
 #endregion
 
 using System;
-using NUnit.Framework;
 using System.Runtime.InteropServices;
-using Google.GRPC.Core.Internal;
+using Grpc.Core.Internal;
+using NUnit.Framework;
 
-namespace Google.GRPC.Core.Internal.Tests
+namespace Grpc.Core.Internal.Tests
 {
     public class TimespecTest
     {
diff --git a/src/csharp/InteropClient/Client.cs b/src/csharp/InteropClient/Client.cs
index fcc6a572e401b4959dbbc4127bcd671f5ac53713..fdec6efd2ef2a3b26aad5a1afef7da2a6e5ec56d 100644
--- a/src/csharp/InteropClient/Client.cs
+++ b/src/csharp/InteropClient/Client.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,14 +33,14 @@
 
 using System;
 using System.Collections.Generic;
-using NUnit.Framework;
 using System.Text.RegularExpressions;
-using Google.GRPC.Core;
-using Google.GRPC.Core.Utils;
 using Google.ProtocolBuffers;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
 using grpc.testing;
 
-namespace Google.GRPC.Interop
+namespace Grpc.Interop
 {
     class Client
     {
@@ -83,7 +83,7 @@ namespace Google.GRPC.Interop
                 Console.WriteLine("  --test_case=TESTCASE");
                 Console.WriteLine("  --use_tls=BOOLEAN");
                 Console.WriteLine("  --use_test_ca=BOOLEAN");
-                Console.WriteLine();  
+                Console.WriteLine();
                 Environment.Exit(1);
             }
 
@@ -149,7 +149,7 @@ namespace Google.GRPC.Interop
                     .SetResponseSize(314159)
                     .SetPayload(CreateZerosPayload(271828))
                     .Build();
-             
+
             var response = client.UnaryCall(request);
 
             Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
@@ -214,8 +214,8 @@ namespace Google.GRPC.Interop
                 .SetResponseType(PayloadType.COMPRESSABLE)
                 .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
                 .SetPayload(CreateZerosPayload(27182)).Build());
-           
-            response = recorder.Queue.Take();             
+
+            response = recorder.Queue.Take();
             Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
             Assert.AreEqual(31415, response.Payload.Body.Length);
 
@@ -224,7 +224,7 @@ namespace Google.GRPC.Interop
                           .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
                           .SetPayload(CreateZerosPayload(8)).Build());
 
-            response = recorder.Queue.Take();             
+            response = recorder.Queue.Take();
             Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
             Assert.AreEqual(9, response.Payload.Body.Length);
 
@@ -233,7 +233,7 @@ namespace Google.GRPC.Interop
                           .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2635))
                           .SetPayload(CreateZerosPayload(1828)).Build());
 
-            response = recorder.Queue.Take();             
+            response = recorder.Queue.Take();
             Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
             Assert.AreEqual(2653, response.Payload.Body.Length);
 
@@ -243,7 +243,7 @@ namespace Google.GRPC.Interop
                           .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
                           .SetPayload(CreateZerosPayload(45904)).Build());
 
-            response = recorder.Queue.Take();             
+            response = recorder.Queue.Take();
             Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
             Assert.AreEqual(58979, response.Payload.Body.Length);
 
diff --git a/src/csharp/InteropClient/InteropClient.csproj b/src/csharp/InteropClient/InteropClient.csproj
index a450f3a2febb5d0818a4783f84548f3536f2c44a..29590f4950854927e98bb21a2b51ce1b30c710e9 100644
--- a/src/csharp/InteropClient/InteropClient.csproj
+++ b/src/csharp/InteropClient/InteropClient.csproj
@@ -9,7 +9,7 @@
     <OutputType>Exe</OutputType>
     <RootNamespace>InteropClient</RootNamespace>
     <AssemblyName>InteropClient</AssemblyName>
-    <StartupObject>Google.GRPC.Interop.Client</StartupObject>
+    <StartupObject>Grpc.Interop.Client</StartupObject>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
@@ -33,14 +33,13 @@
     <PlatformTarget>x86</PlatformTarget>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.ProtocolBuffers, Version=2.4.1.521, Culture=neutral, PublicKeyToken=55f7125234beb589, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
     </Reference>
     <Reference Include="System" />
+    <Reference Include="Google.ProtocolBuffers">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />
diff --git a/src/csharp/InteropClient/Properties/AssemblyInfo.cs b/src/csharp/InteropClient/Properties/AssemblyInfo.cs
index 1f3cc19a9def7df199ad97752baaa2cc67a75be9..3a13173ac77d66a3bdfcc232e67bda94a22abc95 100644
--- a/src/csharp/InteropClient/Properties/AssemblyInfo.cs
+++ b/src/csharp/InteropClient/Properties/AssemblyInfo.cs
@@ -1,21 +1,21 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-// Information about this assembly is defined by the following attributes. 
+// Information about this assembly is defined by the following attributes.
 // Change them to the values specific to your project.
 [assembly: AssemblyTitle("InteropClient")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("jtattermusch")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly, 
+[assembly: AssemblyVersion("0.9.*")]
+// The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
diff --git a/src/csharp/MathClient/MathClient.cs b/src/csharp/MathClient/MathClient.cs
index a54c8e3809931da11862805c74f39ee5a3306f65..95a4678bb8f63e623bd0c3a3c78688922fe7e07a 100644
--- a/src/csharp/MathClient/MathClient.cs
+++ b/src/csharp/MathClient/MathClient.cs
@@ -2,11 +2,11 @@
 
 // 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
@@ -16,7 +16,7 @@
 //     * 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
@@ -33,8 +33,8 @@
 
 using System;
 using System.Runtime.InteropServices;
-using Google.GRPC.Core;
 using System.Threading;
+using Grpc.Core;
 
 namespace math
 {
@@ -55,7 +55,7 @@ namespace math
 
 				MathExamples.DivManyExample(stub);
 			}
-           
+
             GrpcEnvironment.Shutdown();
 		}
 	}
diff --git a/src/csharp/MathClient/Properties/AssemblyInfo.cs b/src/csharp/MathClient/Properties/AssemblyInfo.cs
index f521cd63f0c6bf1a18559f524e8d504a2990e434..d24412f497801c8ab0bdd87fc8aa0bafb8275dd5 100644
--- a/src/csharp/MathClient/Properties/AssemblyInfo.cs
+++ b/src/csharp/MathClient/Properties/AssemblyInfo.cs
@@ -1,21 +1,21 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-// Information about this assembly is defined by the following attributes. 
+// Information about this assembly is defined by the following attributes.
 // Change them to the values specific to your project.
 [assembly: AssemblyTitle ("MathClient")]
 [assembly: AssemblyDescription ("")]
 [assembly: AssemblyConfiguration ("")]
 [assembly: AssemblyCompany ("")]
 [assembly: AssemblyProduct ("")]
-[assembly: AssemblyCopyright ("jtattermusch")]
+[assembly: AssemblyCopyright ("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark ("")]
 [assembly: AssemblyCulture ("")]
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion ("1.0.*")]
-// The following attributes are used to specify the signing key for the assembly, 
+[assembly: AssemblyVersion ("0.9.*")]
+// The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]
 //[assembly: AssemblyKeyFile("")]
diff --git a/src/csharp/README.md b/src/csharp/README.md
index a16f1e719e1d5adbe0b8cf87754dace700d3257d..9967af22b3bc4dbdeff853dc8b7297a11bd33c95 100755
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -1,9 +1,9 @@
 gRPC C#
 =======
 
-A C# implementation of gRPC, Google's RPC library.
+A C# implementation of gRPC.
 
-EXPERIMENTAL ONLY
+Status
 -----------------
 
 **This gRPC C# implementation is work-in-progress and is not expected to work yet.**
@@ -25,10 +25,11 @@ INSTALLATION AND USAGE: WINDOWS
 INSTALLATION AND USAGE: LINUX & MONO
 ------------------------------------
 
-- Compile and install the gRPC C Core library
+- Compile and install the gRPC C# extension library (that will be used via
+  P/Invoke from C#).
 ```
-make shared_c
-sudo make install
+make grpc_csharp_ext
+sudo make install_grpc_csharp_ext
 ```
 
 - Prerequisites for development: Mono framework, MonoDevelop (IDE)
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index c7949af44ec955d369deb4a76cc5bde318b0ec6e..5f9f22cab10052f45e7b1f71770197ee98fd1976 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -31,7 +31,10 @@
  *
  */
 
+#include "src/core/support/string.h"
+
 #include <grpc/support/port_platform.h>
+#include <grpc/support/alloc.h>
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/slice.h>
@@ -58,6 +61,139 @@ grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) {
   return bb;
 }
 
+typedef void(GPR_CALLTYPE *callback_funcptr)(grpc_op_error op_error,
+                                             void *batch_context);
+
+/*
+ * Helper to maintain lifetime of batch op inputs and store batch op outputs.
+ */
+typedef struct gprcsharp_batch_context {
+  grpc_metadata_array send_initial_metadata;
+  grpc_byte_buffer *send_message;
+  struct {
+    grpc_metadata_array trailing_metadata;
+    char *status_details;
+  } send_status_from_server;
+  grpc_metadata_array recv_initial_metadata;
+  grpc_byte_buffer *recv_message;
+  struct {
+    grpc_metadata_array trailing_metadata;
+    grpc_status_code status;
+    char *status_details;
+    size_t status_details_capacity;
+  } recv_status_on_client;
+  int recv_close_on_server_cancelled;
+  struct {
+    grpc_call *call;
+    grpc_call_details call_details;
+    grpc_metadata_array request_metadata;
+  } server_rpc_new;
+
+  /* callback will be called upon completion */
+  callback_funcptr callback;
+
+} grpcsharp_batch_context;
+
+grpcsharp_batch_context *grpcsharp_batch_context_create() {
+  grpcsharp_batch_context *ctx = gpr_malloc(sizeof(grpcsharp_batch_context));
+  memset(ctx, 0, sizeof(grpcsharp_batch_context));
+  return ctx;
+}
+
+/**
+ * Destroys metadata array including keys and values.
+ */
+void grpcsharp_metadata_array_destroy_recursive(grpc_metadata_array *array) {
+  if (!array->metadata) {
+    return;
+  }
+  /* TODO: destroy also keys and values */
+  grpc_metadata_array_destroy(array);
+}
+
+void grpcsharp_batch_context_destroy(grpcsharp_batch_context *ctx) {
+  if (!ctx) {
+    return;
+  }
+  grpcsharp_metadata_array_destroy_recursive(&(ctx->send_initial_metadata));
+
+  grpc_byte_buffer_destroy(ctx->send_message);
+
+  grpcsharp_metadata_array_destroy_recursive(
+      &(ctx->send_status_from_server.trailing_metadata));
+  gpr_free(ctx->send_status_from_server.status_details);
+
+  grpc_metadata_array_destroy(&(ctx->recv_initial_metadata));
+
+  grpc_byte_buffer_destroy(ctx->recv_message);
+
+  grpc_metadata_array_destroy(&(ctx->recv_status_on_client.trailing_metadata));
+  gpr_free((void *)ctx->recv_status_on_client.status_details);
+
+  /* NOTE: ctx->server_rpc_new.call is not destroyed because callback handler is
+     supposed
+     to take its ownership. */
+
+  grpc_call_details_destroy(&(ctx->server_rpc_new.call_details));
+  grpc_metadata_array_destroy(&(ctx->server_rpc_new.request_metadata));
+
+  gpr_free(ctx);
+}
+
+GPR_EXPORT gpr_intptr GPR_CALLTYPE grpcsharp_batch_context_recv_message_length(
+    const grpcsharp_batch_context *ctx) {
+  if (!ctx->recv_message) {
+    return -1;
+  }
+  return grpc_byte_buffer_length(ctx->recv_message);
+}
+
+/*
+ * Copies data from recv_message to a buffer. Fatal error occurs if
+ * buffer is too small.
+ */
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer(
+    const grpcsharp_batch_context *ctx, char *buffer, size_t buffer_len) {
+  grpc_byte_buffer_reader *reader;
+  gpr_slice slice;
+  size_t offset = 0;
+
+  reader = grpc_byte_buffer_reader_create(ctx->recv_message);
+
+  while (grpc_byte_buffer_reader_next(reader, &slice)) {
+    size_t len = GPR_SLICE_LENGTH(slice);
+    GPR_ASSERT(offset + len <= buffer_len);
+    memcpy(buffer + offset, GPR_SLICE_START_PTR(slice),
+           GPR_SLICE_LENGTH(slice));
+    offset += len;
+    gpr_slice_unref(slice);
+  }
+  grpc_byte_buffer_reader_destroy(reader);
+}
+
+GPR_EXPORT grpc_status_code GPR_CALLTYPE
+grpcsharp_batch_context_recv_status_on_client_status(
+    const grpcsharp_batch_context *ctx) {
+  return ctx->recv_status_on_client.status;
+}
+
+GPR_EXPORT const char *GPR_CALLTYPE
+grpcsharp_batch_context_recv_status_on_client_details(
+    const grpcsharp_batch_context *ctx) {
+  return ctx->recv_status_on_client.status_details;
+}
+
+GPR_EXPORT grpc_call *GPR_CALLTYPE grpcsharp_batch_context_server_rpc_new_call(
+    const grpcsharp_batch_context *ctx) {
+  return ctx->server_rpc_new.call;
+}
+
+GPR_EXPORT const char *GPR_CALLTYPE
+grpcsharp_batch_context_server_rpc_new_method(
+    const grpcsharp_batch_context *ctx) {
+  return ctx->server_rpc_new.call_details.method;
+}
+
 /* Init & shutdown */
 
 GPR_EXPORT void GPR_CALLTYPE grpcsharp_init(void) { grpc_init(); }
@@ -71,18 +207,6 @@ grpcsharp_completion_queue_create(void) {
   return grpc_completion_queue_create();
 }
 
-GPR_EXPORT grpc_event *GPR_CALLTYPE
-grpcsharp_completion_queue_next(grpc_completion_queue *cq,
-                                gpr_timespec deadline) {
-  return grpc_completion_queue_next(cq, deadline);
-}
-
-GPR_EXPORT grpc_event *GPR_CALLTYPE
-grpcsharp_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
-                                 gpr_timespec deadline) {
-  return grpc_completion_queue_pluck(cq, tag, deadline);
-}
-
 GPR_EXPORT void GPR_CALLTYPE
 grpcsharp_completion_queue_shutdown(grpc_completion_queue *cq) {
   grpc_completion_queue_shutdown(cq);
@@ -96,12 +220,18 @@ grpcsharp_completion_queue_destroy(grpc_completion_queue *cq) {
 GPR_EXPORT grpc_completion_type GPR_CALLTYPE
 grpcsharp_completion_queue_next_with_callback(grpc_completion_queue *cq) {
   grpc_event *ev;
+  grpcsharp_batch_context *batch_context;
   grpc_completion_type t;
   void(GPR_CALLTYPE * callback)(grpc_event *);
 
   ev = grpc_completion_queue_next(cq, gpr_inf_future);
   t = ev->type;
-  if (ev->tag) {
+  if (t == GRPC_OP_COMPLETE && ev->tag) {
+    /* NEW API handler */
+    batch_context = (grpcsharp_batch_context *)ev->tag;
+    batch_context->callback(ev->data.op_complete, batch_context);
+    grpcsharp_batch_context_destroy(batch_context);
+  } else if (ev->tag) {
     /* call the callback in ev->tag */
     /* C forbids to cast object pointers to function pointers, so
      * we cast to intptr first.
@@ -129,204 +259,286 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_destroy(grpc_channel *channel) {
 }
 
 GPR_EXPORT grpc_call *GPR_CALLTYPE
-grpcsharp_channel_create_call_old(grpc_channel *channel, const char *method,
-                                  const char *host, gpr_timespec deadline) {
-  return grpc_channel_create_call_old(channel, method, host, deadline);
+grpcsharp_channel_create_call(grpc_channel *channel, grpc_completion_queue *cq,
+                              const char *method, const char *host,
+                              gpr_timespec deadline) {
+  return grpc_channel_create_call(channel, cq, method, host, deadline);
 }
 
-/* Event */
+/* Timespec */
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_event_finish(grpc_event *event) {
-  grpc_event_finish(event);
-}
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); }
 
-GPR_EXPORT grpc_completion_type GPR_CALLTYPE
-grpcsharp_event_type(const grpc_event *event) {
-  return event->type;
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(void) {
+  return gpr_inf_future;
 }
 
-GPR_EXPORT grpc_op_error GPR_CALLTYPE
-grpcsharp_event_write_accepted(const grpc_event *event) {
-  GPR_ASSERT(event->type == GRPC_WRITE_ACCEPTED);
-  return event->data.invoke_accepted;
+GPR_EXPORT gpr_int32 GPR_CALLTYPE gprsharp_sizeof_timespec(void) {
+  return sizeof(gpr_timespec);
 }
 
-GPR_EXPORT grpc_op_error GPR_CALLTYPE
-grpcsharp_event_finish_accepted(const grpc_event *event) {
-  GPR_ASSERT(event->type == GRPC_FINISH_ACCEPTED);
-  return event->data.finish_accepted;
-}
+/* Call */
 
-GPR_EXPORT grpc_status_code GPR_CALLTYPE
-grpcsharp_event_finished_status(const grpc_event *event) {
-  GPR_ASSERT(event->type == GRPC_FINISHED);
-  return event->data.finished.status;
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel(grpc_call *call) {
+  return grpc_call_cancel(call);
 }
 
-GPR_EXPORT const char *GPR_CALLTYPE
-grpcsharp_event_finished_details(const grpc_event *event) {
-  GPR_ASSERT(event->type == GRPC_FINISHED);
-  return event->data.finished.details;
+GPR_EXPORT grpc_call_error GPR_CALLTYPE
+grpcsharp_call_cancel_with_status(grpc_call *call, grpc_status_code status,
+                                  const char *description) {
+  return grpc_call_cancel_with_status(call, status, description);
 }
 
-GPR_EXPORT gpr_intptr GPR_CALLTYPE
-grpcsharp_event_read_length(const grpc_event *event) {
-  GPR_ASSERT(event->type == GRPC_READ);
-  if (!event->data.read) {
-    return -1;
-  }
-  return grpc_byte_buffer_length(event->data.read);
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
+  grpc_call_destroy(call);
 }
 
-/*
- * Copies data from read event to a buffer. Fatal error occurs if
- * buffer is too small.
- */
 GPR_EXPORT void GPR_CALLTYPE
-grpcsharp_event_read_copy_to_buffer(const grpc_event *event, char *buffer,
-                                    size_t buffer_len) {
-  grpc_byte_buffer_reader *reader;
-  gpr_slice slice;
-  size_t offset = 0;
+grpcsharp_call_start_write_from_copied_buffer(grpc_call *call,
+                                              const char *buffer, size_t len,
+                                              void *tag, gpr_uint32 flags) {
+  grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
+  GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) ==
+             GRPC_CALL_OK);
+  grpc_byte_buffer_destroy(byte_buffer);
+}
 
-  GPR_ASSERT(event->type == GRPC_READ);
-  reader = grpc_byte_buffer_reader_create(event->data.read);
+GPR_EXPORT grpc_call_error GPR_CALLTYPE
+grpcsharp_call_start_unary(grpc_call *call, callback_funcptr callback,
+                           const char *send_buffer, size_t send_buffer_len) {
+  /* TODO: don't use magic number */
+  grpc_op ops[6];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
 
-  GPR_ASSERT(event->data.read);
-  while (grpc_byte_buffer_reader_next(reader, &slice)) {
-    size_t len = GPR_SLICE_LENGTH(slice);
-    GPR_ASSERT(offset + len <= buffer_len);
-    memcpy(buffer + offset, GPR_SLICE_START_PTR(slice),
-           GPR_SLICE_LENGTH(slice));
-    offset += len;
-    gpr_slice_unref(slice);
-  }
-  grpc_byte_buffer_reader_destroy(reader);
-}
+  /* TODO: implement sending the metadata... */
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  /* ctx->send_initial_metadata is already zeroed out. */
+  ops[0].data.send_initial_metadata.count = 0;
+  ops[0].data.send_initial_metadata.metadata = NULL;
 
-GPR_EXPORT grpc_call *GPR_CALLTYPE
-grpcsharp_event_call(const grpc_event *event) {
-  /* we only allow this for newly incoming server calls. */
-  GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
-  return event->call;
-}
+  ops[1].op = GRPC_OP_SEND_MESSAGE;
+  ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
+  ops[1].data.send_message = ctx->send_message;
 
-GPR_EXPORT const char *GPR_CALLTYPE
-grpcsharp_event_server_rpc_new_method(const grpc_event *event) {
-  GPR_ASSERT(event->type == GRPC_SERVER_RPC_NEW);
-  return event->data.server_rpc_new.method;
-}
+  ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
 
-/* Timespec */
+  ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
+  ops[3].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(); }
+  ops[4].op = GRPC_OP_RECV_MESSAGE;
+  ops[4].data.recv_message = &(ctx->recv_message);
 
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(void) {
-  return gpr_inf_future;
-}
+  ops[5].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[5].data.recv_status_on_client.trailing_metadata =
+      &(ctx->recv_status_on_client.trailing_metadata);
+  ops[5].data.recv_status_on_client.status =
+      &(ctx->recv_status_on_client.status);
+  /* not using preallocation for status_details */
+  ops[5].data.recv_status_on_client.status_details =
+      &(ctx->recv_status_on_client.status_details);
+  ops[5].data.recv_status_on_client.status_details_capacity =
+      &(ctx->recv_status_on_client.status_details_capacity);
 
-GPR_EXPORT gpr_int32 GPR_CALLTYPE gprsharp_sizeof_timespec(void) {
-  return sizeof(gpr_timespec);
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
-/* Call */
-
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_add_metadata_old(grpc_call *call, grpc_metadata *metadata,
-                                gpr_uint32 flags) {
-  return grpc_call_add_metadata_old(call, metadata, flags);
+grpcsharp_call_start_client_streaming(grpc_call *call,
+                                      callback_funcptr callback) {
+  /* TODO: don't use magic number */
+  grpc_op ops[4];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  /* TODO: implement sending the metadata... */
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  /* ctx->send_initial_metadata is already zeroed out. */
+  ops[0].data.send_initial_metadata.count = 0;
+  ops[0].data.send_initial_metadata.metadata = NULL;
+
+  ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
+  ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
+
+  ops[2].op = GRPC_OP_RECV_MESSAGE;
+  ops[2].data.recv_message = &(ctx->recv_message);
+
+  ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[3].data.recv_status_on_client.trailing_metadata =
+      &(ctx->recv_status_on_client.trailing_metadata);
+  ops[3].data.recv_status_on_client.status =
+      &(ctx->recv_status_on_client.status);
+  /* not using preallocation for status_details */
+  ops[3].data.recv_status_on_client.status_details =
+      &(ctx->recv_status_on_client.status_details);
+  ops[3].data.recv_status_on_client.status_details_capacity =
+      &(ctx->recv_status_on_client.status_details_capacity);
+
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_invoke_old(grpc_call *call, grpc_completion_queue *cq,
-                          void *metadata_read_tag, void *finished_tag,
-                          gpr_uint32 flags) {
-  return grpc_call_invoke_old(call, cq, metadata_read_tag, finished_tag, flags);
+grpcsharp_call_start_server_streaming(grpc_call *call,
+                                      callback_funcptr callback,
+                                      const char *send_buffer,
+                                      size_t send_buffer_len) {
+  /* TODO: don't use magic number */
+  grpc_op ops[5];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  /* TODO: implement sending the metadata... */
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  /* ctx->send_initial_metadata is already zeroed out. */
+  ops[0].data.send_initial_metadata.count = 0;
+  ops[0].data.send_initial_metadata.metadata = NULL;
+
+  ops[1].op = GRPC_OP_SEND_MESSAGE;
+  ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
+  ops[1].data.send_message = ctx->send_message;
+
+  ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+
+  ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
+  ops[3].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
+
+  ops[4].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[4].data.recv_status_on_client.trailing_metadata =
+      &(ctx->recv_status_on_client.trailing_metadata);
+  ops[4].data.recv_status_on_client.status =
+      &(ctx->recv_status_on_client.status);
+  /* not using preallocation for status_details */
+  ops[4].data.recv_status_on_client.status_details =
+      &(ctx->recv_status_on_client.status_details);
+  ops[4].data.recv_status_on_client.status_details_capacity =
+      &(ctx->recv_status_on_client.status_details_capacity);
+
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_server_accept_old(grpc_call *call, grpc_completion_queue *cq,
-                                 void *finished_tag) {
-  return grpc_call_server_accept_old(call, cq, finished_tag);
+grpcsharp_call_start_duplex_streaming(grpc_call *call,
+                                      callback_funcptr callback) {
+  /* TODO: don't use magic number */
+  grpc_op ops[3];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  /* TODO: implement sending the metadata... */
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  /* ctx->send_initial_metadata is already zeroed out. */
+  ops[0].data.send_initial_metadata.count = 0;
+  ops[0].data.send_initial_metadata.metadata = NULL;
+
+  ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
+  ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
+
+  ops[2].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[2].data.recv_status_on_client.trailing_metadata =
+      &(ctx->recv_status_on_client.trailing_metadata);
+  ops[2].data.recv_status_on_client.status =
+      &(ctx->recv_status_on_client.status);
+  /* not using preallocation for status_details */
+  ops[2].data.recv_status_on_client.status_details =
+      &(ctx->recv_status_on_client.status_details);
+  ops[2].data.recv_status_on_client.status_details_capacity =
+      &(ctx->recv_status_on_client.status_details_capacity);
+
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_server_end_initial_metadata_old(grpc_call *call,
-                                               gpr_uint32 flags) {
-  return grpc_call_server_end_initial_metadata_old(call, flags);
-}
+grpcsharp_call_send_message(grpc_call *call, callback_funcptr callback,
+                            const char *send_buffer, size_t send_buffer_len) {
+  /* TODO: don't use magic number */
+  grpc_op ops[1];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel(grpc_call *call) {
-  return grpc_call_cancel(call);
-}
+  ops[0].op = GRPC_OP_SEND_MESSAGE;
+  ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
+  ops[0].data.send_message = ctx->send_message;
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_cancel_with_status(grpc_call *call, grpc_status_code status,
-                                  const char *description) {
-  return grpc_call_cancel_with_status(call, status, description);
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_write_old(grpc_call *call, grpc_byte_buffer *byte_buffer,
-                               void *tag, gpr_uint32 flags) {
-  return grpc_call_start_write_old(call, byte_buffer, tag, flags);
+grpcsharp_call_send_close_from_client(grpc_call *call,
+                                      callback_funcptr callback) {
+  /* TODO: don't use magic number */
+  grpc_op ops[1];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  ops[0].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_write_status_old(grpc_call *call,
-                                      grpc_status_code status_code,
-                                      const char *status_message, void *tag) {
-  return grpc_call_start_write_status_old(call, status_code, status_message,
-                                          tag);
+grpcsharp_call_send_status_from_server(grpc_call *call,
+                                       callback_funcptr callback,
+                                       grpc_status_code status_code,
+                                       const char *status_details) {
+  /* TODO: don't use magic number */
+  grpc_op ops[1];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  ops[0].data.send_status_from_server.status = status_code;
+  ops[0].data.send_status_from_server.status_details =
+      gpr_strdup(status_details);
+  ops[0].data.send_status_from_server.trailing_metadata = NULL;
+  ops[0].data.send_status_from_server.trailing_metadata_count = 0;
+
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_writes_done_old(grpc_call *call, void *tag) {
-  return grpc_call_writes_done_old(call, tag);
+grpcsharp_call_recv_message(grpc_call *call, callback_funcptr callback) {
+  /* TODO: don't use magic number */
+  grpc_op ops[1];
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  ops[0].op = GRPC_OP_RECV_MESSAGE;
+  ops[0].data.recv_message = &(ctx->recv_message);
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_read_old(grpc_call *call, void *tag) {
-  return grpc_call_start_read_old(call, tag);
-}
+grpcsharp_call_start_serverside(grpc_call *call, callback_funcptr callback) {
+  /* TODO: don't use magic number */
+  grpc_op ops[2];
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
-  grpc_call_destroy(call);
-}
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
 
-GPR_EXPORT void GPR_CALLTYPE
-grpcsharp_call_start_write_from_copied_buffer(grpc_call *call,
-                                              const char *buffer, size_t len,
-                                              void *tag, gpr_uint32 flags) {
-  grpc_byte_buffer *byte_buffer = string_to_byte_buffer(buffer, len);
-  GPR_ASSERT(grpc_call_start_write_old(call, byte_buffer, tag, flags) ==
-             GRPC_CALL_OK);
-  grpc_byte_buffer_destroy(byte_buffer);
-}
+  ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
+  ops[0].data.send_initial_metadata.count = 0;
+  ops[0].data.send_initial_metadata.metadata = NULL;
 
-/* Server */
+  ops[1].op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  ops[1].data.recv_close_on_server.cancelled =
+      (&ctx->recv_close_on_server_cancelled);
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_server_request_call_old(grpc_server *server, void *tag_new) {
-  return grpc_server_request_call_old(server, tag_new);
+  return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
+/* Server */
+
 GPR_EXPORT grpc_server *GPR_CALLTYPE
 grpcsharp_server_create(grpc_completion_queue *cq,
                         const grpc_channel_args *args) {
   return grpc_server_create(cq, args);
 }
 
-GPR_EXPORT int GPR_CALLTYPE
+GPR_EXPORT gpr_int32 GPR_CALLTYPE
 grpcsharp_server_add_http2_port(grpc_server *server, const char *addr) {
   return grpc_server_add_http2_port(server, addr);
 }
 
-GPR_EXPORT int GPR_CALLTYPE
-grpcsharp_server_add_secure_http2_port(grpc_server *server, const char *addr) {
-  return grpc_server_add_secure_http2_port(server, addr);
-}
-
 GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_start(grpc_server *server) {
   grpc_server_start(server);
 }
@@ -343,3 +555,14 @@ grpcsharp_server_shutdown_and_notify(grpc_server *server, void *tag) {
 GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_destroy(grpc_server *server) {
   grpc_server_destroy(server);
 }
+
+GPR_EXPORT grpc_call_error GPR_CALLTYPE
+grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq,
+                              callback_funcptr callback) {
+  grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
+  ctx->callback = callback;
+
+  return grpc_server_request_call(
+      server, &(ctx->server_rpc_new.call), &(ctx->server_rpc_new.call_details),
+      &(ctx->server_rpc_new.request_metadata), cq, ctx);
+}
diff --git a/src/node/.jshintrc b/src/node/.jshintrc
new file mode 100644
index 0000000000000000000000000000000000000000..8237e0d2b6430de7834f13db03a1fe2a01c76fa7
--- /dev/null
+++ b/src/node/.jshintrc
@@ -0,0 +1,28 @@
+{
+  "bitwise": true,
+  "curly": true,
+  "eqeqeq": true,
+  "esnext": true,
+  "freeze": true,
+  "immed": true,
+  "indent": 2,
+  "latedef": "nofunc",
+  "maxlen": 80,
+  "newcap": true,
+  "node": true,
+  "noarg": true,
+  "quotmark": "single",
+  "strict": true,
+  "trailing": true,
+  "undef": true,
+  "unused": "vars",
+  "globals": {
+    /* Mocha-provided globals */
+    "describe": false,
+    "it": false,
+    "before": false,
+    "beforeEach": false,
+    "after": false,
+    "afterEach": false
+  }
+}
diff --git a/src/node/README.md b/src/node/README.md
index c342b7ca575cc325f29b122a364e701b47cc1cf2..8880213e9a9a6585f59a0ba8a5ad1734f6c9278e 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -1,5 +1,9 @@
 # Node.js gRPC Library
 
+## Status
+
+Alpha : Ready for early adopters
+
 ## Installation
 
 First, clone this repository (NPM package coming soon). Then follow the instructions in the `INSTALL` file in the root of the repository to install the C core library that this package depends on.
diff --git a/src/node/examples/math.proto b/src/node/examples/math.proto
index 2cf6a036aa4ce5565925ca5a5e3cb26df18bcfef..e34ad5e9672791f1db5fc1a5e40973f95ab2cc40 100644
--- a/src/node/examples/math.proto
+++ b/src/node/examples/math.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/node/examples/math_server.js b/src/node/examples/math_server.js
index e1bd11b5a6d0c86a5b1023ca8889bdda9fdde8a3..ae548c89e402abe08bc8822339a07c5d5e958fc1 100644
--- a/src/node/examples/math_server.js
+++ b/src/node/examples/math_server.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,8 @@
  *
  */
 
-var _ = require('underscore');
-var ProtoBuf = require('protobufjs');
-var fs = require('fs');
+'use strict';
+
 var util = require('util');
 
 var Transform = require('stream').Transform;
diff --git a/src/node/examples/perf_test.js b/src/node/examples/perf_test.js
index c5e28727369e7095175ed142a721cb675ec0f690..31083e098727d37e4893d3fb2bcde3fb938e4bba 100644
--- a/src/node/examples/perf_test.js
+++ b/src/node/examples/perf_test.js
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var grpc = require('..');
 var testProto = grpc.load(__dirname + '/../interop/test.proto').grpc.testing;
 var _ = require('underscore');
@@ -44,7 +46,6 @@ function runTest(iterations, callback) {
   function runIterations(finish) {
     var start = process.hrtime();
     var intervals = [];
-    var pending = iterations;
     function next(i) {
       if (i >= iterations) {
         testServer.server.shutdown();
@@ -69,28 +70,30 @@ function runTest(iterations, callback) {
 
   function warmUp(num) {
     var pending = num;
+    function startCall() {
+      client.emptyCall({}, function(err, resp) {
+        pending--;
+        if (pending === 0) {
+          runIterations(callback);
+        }
+      });
+    }
     for (var i = 0; i < num; i++) {
-      (function(i) {
-        client.emptyCall({}, function(err, resp) {
-          pending--;
-          if (pending === 0) {
-            runIterations(callback);
-          }
-        });
-      })(i);
+      startCall();
     }
   }
   warmUp(100);
 }
 
-function percentile(arr, percentile) {
-  if (percentile > 99) {
-    percentile = 99;
+function percentile(arr, pct) {
+  if (pct > 99) {
+    pct = 99;
   }
-  if (percentile < 0) {
-    percentile = 0;
+  if (pct < 0) {
+    pct = 0;
   }
-  return arr[(arr.length * percentile / 100)|0];
+  var index = Math.floor(arr.length * pct / 100);
+  return arr[index];
 }
 
 if (require.main === module) {
diff --git a/src/node/examples/stock.proto b/src/node/examples/stock.proto
index 2bc5c29d172487f4eb0a6efc86fb0e15d0ef4609..328e050aefb7025029ce9b6acad62191237cecee 100644
--- a/src/node/examples/stock.proto
+++ b/src/node/examples/stock.proto
@@ -59,4 +59,4 @@ service Stock {
   rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) {
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/node/examples/stock_server.js b/src/node/examples/stock_server.js
index b226a7157320fbb5a327b152daa843db59675c72..e475c9cb4ccff0907cf305d6aa194eabd38991bf 100644
--- a/src/node/examples/stock_server.js
+++ b/src/node/examples/stock_server.js
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var _ = require('underscore');
 var grpc = require('..');
 var examples = grpc.load(__dirname + '/stock.proto').examples;
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index 695ecedd3447518fdfde638b5e37b44bcc4e7ae5..c165d26e47e1161a48cdc9b45ab43d7ebba7acf8 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/byte_buffer.h b/src/node/ext/byte_buffer.h
index 5f1903a42ebc82f1a43d2d9f250cbeacc13bb006..5083674d394a35dcace146d4fbc51737e16a7672 100644
--- a/src/node/ext/byte_buffer.h
+++ b/src/node/ext/byte_buffer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/call.h b/src/node/ext/call.h
index dbdb8e2ff65a3e38f62934a735e18a4ffbcecebd..933541ce5b654aed5bfedd9a91ae373f4d6e2ef1 100644
--- a/src/node/ext/call.h
+++ b/src/node/ext/call.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index 9087d6f919b1426f0841ce97f1e517dfb0b93020..6c7a89e596d09955f0158fd1cab7cf9cd5e94695 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/channel.h b/src/node/ext/channel.h
index 140cbf201a194193160bd514b6f7af8d6188f384..bf793194d9a7ff1cb91bd90b5d15f043f83d983e 100644
--- a/src/node/ext/channel.h
+++ b/src/node/ext/channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/completion_queue_async_worker.cc b/src/node/ext/completion_queue_async_worker.cc
index a1f390f64b622b2602c4871691cf421f6fded3e2..ca22527e6f547a776d49cda075f88ca0272e97a5 100644
--- a/src/node/ext/completion_queue_async_worker.cc
+++ b/src/node/ext/completion_queue_async_worker.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/completion_queue_async_worker.h b/src/node/ext/completion_queue_async_worker.h
index c04a303283a42b923d2dc6936ec73f081f1a567e..0ddb5b4cfd2551a19a1b9421c8dfe7a52829b1aa 100644
--- a/src/node/ext/completion_queue_async_worker.h
+++ b/src/node/ext/completion_queue_async_worker.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/credentials.cc b/src/node/ext/credentials.cc
index b79c3e3019dd239a96abc9ea12d37dc835e4db25..4b95c72bf73a23770f8d702c29d3bfe21a03c50e 100644
--- a/src/node/ext/credentials.cc
+++ b/src/node/ext/credentials.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/credentials.h b/src/node/ext/credentials.h
index 981e5a99bc70f8baeaec3159305b0b1316823e36..e60be3d4e155b7581ff55e2649402cf2bf8e5b45 100644
--- a/src/node/ext/credentials.h
+++ b/src/node/ext/credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 9b0fe82976e63b7a58cc36c1c112d98d7fafd3d1..9f5095839cb7404ffe21a5ee320a11049d1292b2 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,6 @@
 
 #include "call.h"
 #include "channel.h"
-#include "event.h"
 #include "server.h"
 #include "completion_queue_async_worker.h"
 #include "credentials.h"
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index ee3e1087ce7698aadd53fba670a67b7c1a343ee3..ab45da8d199692f0c90ebbcd55d65d76e697639b 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/server.h b/src/node/ext/server.h
index d50f1fb6c5e37f8591789e4bb3ab5fa6a7b7762c..2056fe7d3f8a5b14ff2ae948493c089175ee4c12 100644
--- a/src/node/ext/server.h
+++ b/src/node/ext/server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc
index 3add43c48c9ae1527a3c87407bfcc50c1b84b259..f75a2bf79c8f2cd2ec03e3e69311c43d530a654c 100644
--- a/src/node/ext/server_credentials.cc
+++ b/src/node/ext/server_credentials.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/server_credentials.h b/src/node/ext/server_credentials.h
index 8baae3f185a97984cf5f4f02308ae8ac80cdd024..f09902420c6e6413f02f4bfa086d4827294a66e6 100644
--- a/src/node/ext/server_credentials.h
+++ b/src/node/ext/server_credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/timeval.cc b/src/node/ext/timeval.cc
index 20d52f0963eb5f44370b6bbb656e85bf3f2b2236..bc3237f7a6c2d06794dbdffaa4d3a70a8b5b343a 100644
--- a/src/node/ext/timeval.cc
+++ b/src/node/ext/timeval.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/ext/timeval.h b/src/node/ext/timeval.h
index 1fb0f2c690f110fcab6c995ba6b5a29652ce390d..0cada5ace969d17f7769adb6291329a2283c4a23 100644
--- a/src/node/ext/timeval.h
+++ b/src/node/ext/timeval.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/node/index.js b/src/node/index.js
index baef4d03c68df0d0c16de22220d7a137a2644626..4b5302e4382a7edeb02bd6b727e5f6fda53a5878 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var _ = require('underscore');
 
 var ProtoBuf = require('protobufjs');
@@ -73,6 +75,37 @@ function load(filename) {
   return loadObject(builder.ns);
 }
 
+/**
+ * Get a function that a client can use to update metadata with authentication
+ * information from a Google Auth credential object, which comes from the
+ * googleauth library.
+ * @param {Object} credential The credential object to use
+ * @return {function(Object, callback)} Metadata updater function
+ */
+function getGoogleAuthDelegate(credential) {
+  /**
+   * Update a metadata object with authentication information.
+   * @param {Object} metadata Metadata object
+   * @param {function(Error, Object)} callback
+   */
+  return function updateMetadata(metadata, callback) {
+    metadata = _.clone(metadata);
+    if (metadata.Authorization) {
+      metadata.Authorization = _.clone(metadata.Authorization);
+    } else {
+      metadata.Authorization = [];
+    }
+    credential.getAccessToken(function(err, token) {
+      if (err) {
+        callback(err);
+        return;
+      }
+      metadata.Authorization.push('Bearer ' + token);
+      callback(null, metadata);
+    });
+  };
+}
+
 /**
  * See docs for loadObject
  */
@@ -106,3 +139,5 @@ exports.Credentials = grpc.Credentials;
  * ServerCredentials factories
  */
 exports.ServerCredentials = grpc.ServerCredentials;
+
+exports.getGoogleAuthDelegate = getGoogleAuthDelegate;
diff --git a/src/node/interop/empty.proto b/src/node/interop/empty.proto
index 98fc3a39070507d4c7d430afec0d382e63e90345..f66a108c19b7b46f4afe2b55d09bfc4f03a359a9 100644
--- a/src/node/interop/empty.proto
+++ b/src/node/interop/empty.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index 8737af6cde9ec47db17961a29cd1940928ff09ca..eaf254bcfef0cd493996f87194384148053126cd 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,13 +31,21 @@
  *
  */
 
+'use strict';
+
 var fs = require('fs');
 var path = require('path');
 var grpc = require('..');
 var testProto = grpc.load(__dirname + '/test.proto').grpc.testing;
+var GoogleAuth = require('googleauth');
 
 var assert = require('assert');
 
+var AUTH_SCOPE = 'https://www.googleapis.com/auth/xapi.zoo';
+var AUTH_SCOPE_RESPONSE = 'xapi.zoo';
+var AUTH_USER = ('155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk' +
+    '@developer.gserviceaccount.com');
+
 /**
  * Create a buffer filled with size zeroes
  * @param {number} size The length of the buffer
@@ -255,6 +263,45 @@ function cancelAfterFirstResponse(client, done) {
   });
 }
 
+/**
+ * Run one of the authentication tests.
+ * @param {Client} client The client to test against
+ * @param {function} done Callback to call when the test is completed. Included
+ *     primarily for use with mocha
+ */
+function authTest(client, done) {
+  (new GoogleAuth()).getApplicationDefault(function(err, credential) {
+    assert.ifError(err);
+    if (credential.createScopedRequired()) {
+      credential = credential.createScoped(AUTH_SCOPE);
+    }
+    client.updateMetadata = grpc.getGoogleAuthDelegate(credential);
+    var arg = {
+      response_type: testProto.PayloadType.COMPRESSABLE,
+      response_size: 314159,
+      payload: {
+        body: zeroBuffer(271828)
+      },
+      fill_username: true,
+      fill_oauth_scope: true
+    };
+    var call = client.unaryCall(arg, function(err, resp) {
+      assert.ifError(err);
+      assert.strictEqual(resp.payload.type, testProto.PayloadType.COMPRESSABLE);
+      assert.strictEqual(resp.payload.body.limit - resp.payload.body.offset,
+                         314159);
+      assert.strictEqual(resp.username, AUTH_USER);
+      assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
+    });
+    call.on('status', function(status) {
+      assert.strictEqual(status.code, grpc.status.OK);
+      if (done) {
+        done();
+      }
+    });
+  });
+}
+
 /**
  * Map from test case names to test functions
  */
@@ -266,13 +313,15 @@ var test_cases = {
   ping_pong: pingPong,
   empty_stream: emptyStream,
   cancel_after_begin: cancelAfterBegin,
-  cancel_after_first_response: cancelAfterFirstResponse
+  cancel_after_first_response: cancelAfterFirstResponse,
+  compute_engine_creds: authTest,
+  service_account_creds: authTest
 };
 
 /**
  * Execute a single test case.
  * @param {string} address The address of the server to connect to, in the
- *     format "hostname:port"
+ *     format 'hostname:port'
  * @param {string} host_overrirde The hostname of the server to use as an SSL
  *     override
  * @param {string} test_case The name of the test case to run
@@ -280,11 +329,16 @@ var test_cases = {
  * @param {function} done Callback to call when the test is completed. Included
  *     primarily for use with mocha
  */
-function runTest(address, host_override, test_case, tls, done) {
+function runTest(address, host_override, test_case, tls, test_ca, done) {
   // TODO(mlumish): enable TLS functionality
   var options = {};
   if (tls) {
-    var ca_path = path.join(__dirname, '../test/data/ca.pem');
+    var ca_path;
+    if (test_ca) {
+      ca_path = path.join(__dirname, '../test/data/ca.pem');
+    } else {
+      ca_path = process.env.SSL_CERT_FILE;
+    }
     var ca_data = fs.readFileSync(ca_path);
     var creds = grpc.Credentials.createSsl(ca_data);
     options.credentials = creds;
@@ -304,7 +358,10 @@ if (require.main === module) {
              'use_tls', 'use_test_ca']
   });
   runTest(argv.server_host + ':' + argv.server_port, argv.server_host_override,
-          argv.test_case, argv.use_tls === 'true');
+          argv.test_case, argv.use_tls === 'true', argv.use_test_ca === 'true',
+          function () {
+            console.log('OK:', argv.test_case);
+          });
 }
 
 /**
diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js
index 54e9715d1e38b774aa47fd50db23ba1a3456e492..125ede174642f05bb0ee5f3d0831f5b69b797d7c 100644
--- a/src/node/interop/interop_server.js
+++ b/src/node/interop/interop_server.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var fs = require('fs');
 var path = require('path');
 var _ = require('underscore');
diff --git a/src/node/interop/messages.proto b/src/node/interop/messages.proto
index f53d99ab5b62de13fef889d53ba0182c163d35b8..65a81404652520a211940cd4af81968620ea8dc2 100644
--- a/src/node/interop/messages.proto
+++ b/src/node/interop/messages.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
@@ -66,6 +66,12 @@ message SimpleRequest {
 
   // Optional input payload sent along with the request.
   optional Payload payload = 3;
+
+  // Whether SimpleResponse should include username.
+  optional bool fill_username = 4;
+
+  // Whether SimpleResponse should include OAuth scope.
+  optional bool fill_oauth_scope = 5;
 }
 
 // Unary response, as configured by the request.
@@ -74,7 +80,9 @@ message SimpleResponse {
   optional Payload payload = 1;
   // The user the request came from, for verifying authentication was
   // successful when the client expected it.
-  optional int64 effective_gaia_user_id = 2;
+  optional string username = 2;
+  // OAuth scope.
+  optional string oauth_scope = 3;
 }
 
 // Client-streaming request.
diff --git a/src/node/interop/test.proto b/src/node/interop/test.proto
index c2437630b7d407b59eb74f9e7e38ddcf4f2f242e..927a3a83aa26772075a9602012cab791071e41f8 100644
--- a/src/node/interop/test.proto
+++ b/src/node/interop/test.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/node/package.json b/src/node/package.json
index 8f81014c1e8a22735c2fd89473a2328c2678d5be..a71577fb96620ebdba3d1fa9eb3d021561f5055d 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -3,10 +3,12 @@
   "version": "0.2.0",
   "description": "gRPC Library for Node",
   "scripts": {
-    "test": "./node_modules/mocha/bin/mocha"
+    "lint": "nodejs ./node_modules/jshint/bin/jshint src test examples interop index.js",
+    "test": "nodejs ./node_modules/mocha/bin/mocha && npm run-script lint"
   },
   "dependencies": {
     "bindings": "^1.2.1",
+    "jshint": "^2.5.5",
     "nan": "~1.3.0",
     "protobufjs": "murgatroid99/ProtoBuf.js",
     "underscore": "^1.7.0",
@@ -14,7 +16,18 @@
   },
   "devDependencies": {
     "mocha": "~1.21.0",
-    "minimist": "^1.1.0"
+    "minimist": "^1.1.0",
+    "googleauth": "google/google-auth-library-nodejs"
   },
+  "files": [
+    "README.md",
+    "index.js",
+    "binding.gyp",
+    "examples",
+    "ext",
+    "interop",
+    "src",
+    "test"
+  ],
   "main": "index.js"
 }
diff --git a/src/node/src/client.js b/src/node/src/client.js
index 81fa65eb26398bf4dc35c1e41af6a3a3e92746ca..aaa7be79c9d4898adba04d1f131afa04b7bd7eaa 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var _ = require('underscore');
 
 var capitalize = require('underscore.string/capitalize');
@@ -77,6 +79,7 @@ function ClientWritableStream(call, serialize) {
  * @param {function(Error=)} callback Called when the write is complete
  */
 function _write(chunk, encoding, callback) {
+  /* jshint validthis: true */
   var batch = {};
   batch[grpc.opType.SEND_MESSAGE] = this.serialize(chunk);
   this.call.startBatch(batch, function(err, event) {
@@ -85,7 +88,7 @@ function _write(chunk, encoding, callback) {
     }
     callback();
   });
-};
+}
 
 ClientWritableStream.prototype._write = _write;
 
@@ -111,6 +114,7 @@ function ClientReadableStream(call, deserialize) {
  * @param {*} size Ignored because we use objectMode=true
  */
 function _read(size) {
+  /* jshint validthis: true */
   var self = this;
   /**
    * Callback to be called when a READ event is received. Pushes the data onto
@@ -126,7 +130,7 @@ function _read(size) {
       return;
     }
     var data = event.read;
-    if (self.push(self.deserialize(data)) && data != null) {
+    if (self.push(self.deserialize(data)) && data !== null) {
       var read_batch = {};
       read_batch[grpc.opType.RECV_MESSAGE] = true;
       self.call.startBatch(read_batch, readCallback);
@@ -144,7 +148,7 @@ function _read(size) {
       self.call.startBatch(read_batch, readCallback);
     }
   }
-};
+}
 
 ClientReadableStream.prototype._read = _read;
 
@@ -163,10 +167,6 @@ function ClientDuplexStream(call, serialize, deserialize) {
   Duplex.call(this, {objectMode: true});
   this.serialize = common.wrapIgnoreNull(serialize);
   this.deserialize = common.wrapIgnoreNull(deserialize);
-  var self = this;
-  var finished = false;
-  // Indicates that a read is currently pending
-  var reading = false;
   this.call = call;
   this.on('finish', function() {
     var batch = {};
@@ -182,6 +182,7 @@ ClientDuplexStream.prototype._write = _write;
  * Cancel the ongoing call
  */
 function cancel() {
+  /* jshint validthis: true */
   this.call.cancel();
 }
 
@@ -213,6 +214,7 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
    * @return {EventEmitter} An event emitter for stream related events
    */
   function makeUnaryRequest(argument, callback, metadata, deadline) {
+    /* jshint validthis: true */
     if (deadline === undefined) {
       deadline = Infinity;
     }
@@ -224,25 +226,32 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
     emitter.cancel = function cancel() {
       call.cancel();
     };
-    var client_batch = {};
-    client_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
-    client_batch[grpc.opType.SEND_MESSAGE] = serialize(argument);
-    client_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
-    client_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
-    client_batch[grpc.opType.RECV_MESSAGE] = true;
-    client_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
-    call.startBatch(client_batch, function(err, response) {
-      if (err) {
-        callback(err);
+    this.updateMetadata(metadata, function(error, metadata) {
+      if (error) {
+        call.cancel();
+        callback(error);
         return;
       }
-      if (response.status.code != grpc.status.OK) {
-        callback(response.status);
-        return;
-      }
-      emitter.emit('status', response.status);
-      emitter.emit('metadata', response.metadata);
-      callback(null, deserialize(response.read));
+      var client_batch = {};
+      client_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
+      client_batch[grpc.opType.SEND_MESSAGE] = serialize(argument);
+      client_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
+      client_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
+      client_batch[grpc.opType.RECV_MESSAGE] = true;
+      client_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
+      call.startBatch(client_batch, function(err, response) {
+        if (err) {
+          callback(err);
+          return;
+        }
+        if (response.status.code !== grpc.status.OK) {
+          callback(response.status);
+          return;
+        }
+        emitter.emit('status', response.status);
+        emitter.emit('metadata', response.metadata);
+        callback(null, deserialize(response.read));
+      });
     });
     return emitter;
   }
@@ -271,6 +280,7 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
    * @return {EventEmitter} An event emitter for stream related events
    */
   function makeClientStreamRequest(callback, metadata, deadline) {
+    /* jshint validthis: true */
     if (deadline === undefined) {
       deadline = Infinity;
     }
@@ -279,30 +289,37 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) {
       metadata = {};
     }
     var stream = new ClientWritableStream(call, serialize);
-    var metadata_batch = {};
-    metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
-    metadata_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
-    call.startBatch(metadata_batch, function(err, response) {
-      if (err) {
-        callback(err);
+    this.updateMetadata(metadata, function(error, metadata) {
+      if (error) {
+        call.cancel();
+        callback(error);
         return;
       }
-      stream.emit('metadata', response.metadata);
-    });
-    var client_batch = {};
-    client_batch[grpc.opType.RECV_MESSAGE] = true;
-    client_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
-    call.startBatch(client_batch, function(err, response) {
-      if (err) {
-        callback(err);
-        return;
-      }
-      if (response.status.code != grpc.status.OK) {
-        callback(response.status);
-        return;
-      }
-      stream.emit('status', response.status);
-      callback(null, deserialize(response.read));
+      var metadata_batch = {};
+      metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
+      metadata_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
+      call.startBatch(metadata_batch, function(err, response) {
+        if (err) {
+          callback(err);
+          return;
+        }
+        stream.emit('metadata', response.metadata);
+      });
+      var client_batch = {};
+      client_batch[grpc.opType.RECV_MESSAGE] = true;
+      client_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
+      call.startBatch(client_batch, function(err, response) {
+        if (err) {
+          callback(err);
+          return;
+        }
+        if (response.status.code !== grpc.status.OK) {
+          callback(response.status);
+          return;
+        }
+        stream.emit('status', response.status);
+        callback(null, deserialize(response.read));
+      });
     });
     return stream;
   }
@@ -331,6 +348,7 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
    * @return {EventEmitter} An event emitter for stream related events
    */
   function makeServerStreamRequest(argument, metadata, deadline) {
+    /* jshint validthis: true */
     if (deadline === undefined) {
       deadline = Infinity;
     }
@@ -339,24 +357,31 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) {
       metadata = {};
     }
     var stream = new ClientReadableStream(call, deserialize);
-    var start_batch = {};
-    start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
-    start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
-    start_batch[grpc.opType.SEND_MESSAGE] = serialize(argument);
-    start_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
-    call.startBatch(start_batch, function(err, response) {
-      if (err) {
-        throw err;
-      }
-      stream.emit('metadata', response.metadata);
-    });
-    var status_batch = {};
-    status_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
-    call.startBatch(status_batch, function(err, response) {
-      if (err) {
-        throw err;
+    this.updateMetadata(metadata, function(error, metadata) {
+      if (error) {
+        call.cancel();
+        stream.emit('error', error);
+        return;
       }
-      stream.emit('status', response.status);
+      var start_batch = {};
+      start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
+      start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
+      start_batch[grpc.opType.SEND_MESSAGE] = serialize(argument);
+      start_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
+      call.startBatch(start_batch, function(err, response) {
+        if (err) {
+          throw err;
+        }
+        stream.emit('metadata', response.metadata);
+      });
+      var status_batch = {};
+      status_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
+      call.startBatch(status_batch, function(err, response) {
+        if (err) {
+          throw err;
+        }
+        stream.emit('status', response.status);
+      });
     });
     return stream;
   }
@@ -383,6 +408,7 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
    * @return {EventEmitter} An event emitter for stream related events
    */
   function makeBidiStreamRequest(metadata, deadline) {
+    /* jshint validthis: true */
     if (deadline === undefined) {
       deadline = Infinity;
     }
@@ -391,22 +417,29 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) {
       metadata = {};
     }
     var stream = new ClientDuplexStream(call, serialize, deserialize);
-    var start_batch = {};
-    start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
-    start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
-    call.startBatch(start_batch, function(err, response) {
-      if (err) {
-        throw err;
-      }
-      stream.emit('metadata', response.metadata);
-    });
-    var status_batch = {};
-    status_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
-    call.startBatch(status_batch, function(err, response) {
-      if (err) {
-        throw err;
+    this.updateMetadata(metadata, function(error, metadata) {
+      if (error) {
+        call.cancel();
+        stream.emit('error', error);
+        return;
       }
-      stream.emit('status', response.status);
+      var start_batch = {};
+      start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
+      start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
+      call.startBatch(start_batch, function(err, response) {
+        if (err) {
+          throw err;
+        }
+        stream.emit('metadata', response.metadata);
+      });
+      var status_batch = {};
+      status_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
+      call.startBatch(status_batch, function(err, response) {
+        if (err) {
+          throw err;
+        }
+        stream.emit('status', response.status);
+      });
     });
     return stream;
   }
@@ -438,8 +471,17 @@ function makeClientConstructor(service) {
    * @constructor
    * @param {string} address The address of the server to connect to
    * @param {Object} options Options to pass to the underlying channel
+   * @param {function(Object, function)=} updateMetadata function to update the
+   *     metadata for each request
    */
-  function Client(address, options) {
+  function Client(address, options, updateMetadata) {
+    if (updateMetadata) {
+      this.updateMetadata = updateMetadata;
+    } else {
+      this.updateMetadata = function(metadata, callback) {
+        callback(null, metadata);
+      };
+    }
     this.channel = new grpc.Channel(address, options);
   }
 
@@ -458,11 +500,13 @@ function makeClientConstructor(service) {
         method_type = 'unary';
       }
     }
-    Client.prototype[decapitalize(method.name)] =
-        requester_makers[method_type](
-            prefix + capitalize(method.name),
-            common.serializeCls(method.resolvedRequestType.build()),
-            common.deserializeCls(method.resolvedResponseType.build()));
+    var serialize = common.serializeCls(method.resolvedRequestType.build());
+    var deserialize = common.deserializeCls(
+        method.resolvedResponseType.build());
+    Client.prototype[decapitalize(method.name)] = requester_makers[method_type](
+        prefix + capitalize(method.name), serialize, deserialize);
+    Client.prototype[decapitalize(method.name)].serialize = serialize;
+    Client.prototype[decapitalize(method.name)].deserialize = deserialize;
   });
 
   Client.service = service;
diff --git a/src/node/src/common.js b/src/node/src/common.js
index 7560cf1bddfa91a298f189554799100192283d5c..eec8f0f9878f7f4fa1974d785b0566e55e235e71 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var _ = require('underscore');
 
 var capitalize = require('underscore.string/capitalize');
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 48c349ef99d0a2f56e474b11e35f5fdd2f633c4d..91dde0225181cc9341fd454bbab111723493c313 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var _ = require('underscore');
 
 var capitalize = require('underscore.string/capitalize');
@@ -217,6 +219,7 @@ function ServerWritableStream(call, serialize) {
  *     complete
  */
 function _write(chunk, encoding, callback) {
+  /* jshint validthis: true */
   var batch = {};
   batch[grpc.opType.SEND_MESSAGE] = this.serialize(chunk);
   this.call.startBatch(batch, function(err, value) {
@@ -251,6 +254,7 @@ function ServerReadableStream(call, deserialize) {
  * @param {number} size Ignored
  */
 function _read(size) {
+  /* jshint validthis: true */
   var self = this;
   /**
    * Callback to be called when a READ event is received. Pushes the data onto
@@ -267,7 +271,7 @@ function _read(size) {
       return;
     }
     var data = event.read;
-    if (self.push(self.deserialize(data)) && data != null) {
+    if (self.push(self.deserialize(data)) && data !== null) {
       var read_batch = {};
       read_batch[grpc.opType.RECV_MESSAGE] = true;
       self.call.startBatch(read_batch, readCallback);
@@ -424,7 +428,6 @@ function Server(getMetadata, options) {
   var handlers = this.handlers;
   var server = new grpc.Server(options);
   this._server = server;
-  var started = false;
   /**
    * Start the server and begin handling requests
    * @this Server
@@ -456,8 +459,7 @@ function Server(getMetadata, options) {
         return;
       }
       server.requestCall(handleNewCall);
-      var handler = undefined;
-      var deadline = details.deadline;
+      var handler;
       if (handlers.hasOwnProperty(method)) {
         handler = handlers[method];
       } else {
@@ -465,7 +467,7 @@ function Server(getMetadata, options) {
         batch[grpc.opType.SEND_INITIAL_METADATA] = {};
         batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
           code: grpc.status.UNIMPLEMENTED,
-          details: "This method is not available on this server.",
+          details: 'This method is not available on this server.',
           metadata: {}
         };
         batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js
index c1a7e95fa09ab8ae8f9737715720d9eea405cdcb..7b2b36ae3710add87bcaa6f6d03fe1003bdac167 100644
--- a/src/node/test/call_test.js
+++ b/src/node/test/call_test.js
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var assert = require('assert');
 var grpc = require('bindings')('grpc.node');
 
diff --git a/src/node/test/channel_test.js b/src/node/test/channel_test.js
index 4d8cfc4d89c57f158788500ef08126e9b0650c92..33200c99ee2d8f3305d9efa703c2cbd28ddf4ea4 100644
--- a/src/node/test/channel_test.js
+++ b/src/node/test/channel_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var assert = require('assert');
 var grpc = require('bindings')('grpc.node');
 
diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js
index 4d11e6f5272c2216014e156ac902a0ac5b0e669b..ecc98ec44380942858ec8012451c7c32055bd43b 100644
--- a/src/node/test/constant_test.js
+++ b/src/node/test/constant_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var assert = require('assert');
 var grpc = require('bindings')('grpc.node');
 
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index f8899beae82267854c592cbd69e1e13c3fc1bc37..1cc192869175032399f334a501dc84f6ba0e2ad0 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var assert = require('assert');
 var grpc = require('bindings')('grpc.node');
 
@@ -227,7 +229,7 @@ describe('end-to-end', function() {
         response_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
         server_call.startBatch(response_batch, function(err, response) {
           assert(response['send status']);
-          assert(!response['cancelled']);
+          assert(!response.cancelled);
           done();
         });
       });
diff --git a/src/node/test/interop_sanity_test.js b/src/node/test/interop_sanity_test.js
index 81cd9fa5b95a17ee290ff9233fba5d5bffe45076..8dc933eac563d072c176f64ba27546ebe6b2e5c6 100644
--- a/src/node/test/interop_sanity_test.js
+++ b/src/node/test/interop_sanity_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var interop_server = require('../interop/interop_server.js');
 var interop_client = require('../interop/interop_client.js');
 
@@ -53,30 +55,35 @@ describe('Interop tests', function() {
   });
   // This depends on not using a binary stream
   it('should pass empty_unary', function(done) {
-    interop_client.runTest(port, name_override, 'empty_unary', true, done);
+    interop_client.runTest(port, name_override, 'empty_unary', true, true,
+                           done);
   });
   // This fails due to an unknown bug
   it('should pass large_unary', function(done) {
-    interop_client.runTest(port, name_override, 'large_unary', true, done);
+    interop_client.runTest(port, name_override, 'large_unary', true, true,
+                           done);
   });
   it('should pass client_streaming', function(done) {
-    interop_client.runTest(port, name_override, 'client_streaming', true, done);
+    interop_client.runTest(port, name_override, 'client_streaming', true, true,
+                           done);
   });
   it('should pass server_streaming', function(done) {
-    interop_client.runTest(port, name_override, 'server_streaming', true, done);
+    interop_client.runTest(port, name_override, 'server_streaming', true, true,
+                           done);
   });
   it('should pass ping_pong', function(done) {
-    interop_client.runTest(port, name_override, 'ping_pong', true, done);
+    interop_client.runTest(port, name_override, 'ping_pong', true, true, done);
   });
   it('should pass empty_stream', function(done) {
-    interop_client.runTest(port, name_override, 'empty_stream', true, done);
+    interop_client.runTest(port, name_override, 'empty_stream', true, true,
+                           done);
   });
   it('should pass cancel_after_begin', function(done) {
     interop_client.runTest(port, name_override, 'cancel_after_begin', true,
-                           done);
+                           true, done);
   });
   it('should pass cancel_after_first_response', function(done) {
     interop_client.runTest(port, name_override, 'cancel_after_first_response',
-                           true, done);
+                           true, true, done);
   });
 });
diff --git a/src/node/test/math_client_test.js b/src/node/test/math_client_test.js
index 61b4a2fa2fe2aa31bef4f21808d63dc88268ac36..d83f64116f71672b2ee23f3b32c1fc8df04e12d2 100644
--- a/src/node/test/math_client_test.js
+++ b/src/node/test/math_client_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@
  *
  */
 
+'use strict';
+
 var assert = require('assert');
 
 var grpc = require('..');
@@ -59,7 +61,7 @@ describe('Math client', function() {
   });
   it('should handle a single request', function(done) {
     var arg = {dividend: 7, divisor: 4};
-    var call = math_client.div(arg, function handleDivResult(err, value) {
+    math_client.div(arg, function handleDivResult(err, value) {
       assert.ifError(err);
       assert.equal(value.quotient, 1);
       assert.equal(value.remainder, 3);
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 34e4ab4013cb14db847d163d587e21cf84fcd5d3..91d8197bee1663b2379078e9c1835e0a9adc21d8 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,9 @@
  *
  */
 
-var assert = require('assert');
+'use strict';
 
-var surface_server = require('../src/server.js');
+var assert = require('assert');
 
 var surface_client = require('../src/client.js');
 
diff --git a/src/objective-c/.gitignore b/src/objective-c/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ec839c09ebd8574a052207919dbb218edfb06132
--- /dev/null
+++ b/src/objective-c/.gitignore
@@ -0,0 +1,18 @@
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
new file mode 100644
index 0000000000000000000000000000000000000000..10437cb8bcbb948ce18918d7fb3e8b2c88bbf0d5
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#import <RxLibrary/GRXWriter.h>
+
+@class GRPCMethodName;
+
+@class GRPCCall;
+
+// The gRPC protocol is an RPC protocol on top of HTTP2.
+//
+// While the most common type of RPC receives only one request message and
+// returns only one response message, the protocol also supports RPCs that
+// return multiple individual messages in a streaming fashion, RPCs that
+// accept a stream of request messages, or RPCs with both streaming requests
+// and responses.
+//
+// Conceptually, each gRPC call consists of a bidirectional stream of binary
+// messages, with RPCs of the "non-streaming type" sending only one message in
+// the corresponding direction (the protocol doesn't make any distinction).
+//
+// Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs
+// can be multiplexed transparently on the same TCP connection.
+@interface GRPCCall : NSObject<GRXWriter>
+
+// These HTTP2 headers will be passed to the server as part of this call. Each
+// HTTP2 header is a name-value pair with string names and either string or binary values.
+// The passed dictionary has to use NSString keys, corresponding to the header names. The
+// value associated to each can be a NSString object or a NSData object. E.g.:
+//
+// call.requestMetadata = @{
+//     @"Authorization": @"Bearer ...",
+//     @"SomeBinaryHeader": someData
+// };
+//
+// After the call is started, modifying this won't have any effect.
+@property(nonatomic, readwrite) NSMutableDictionary *requestMetadata;
+
+// This isn't populated until the first event is delivered to the handler.
+@property(atomic, readonly) NSDictionary *responseMetadata;
+
+// The request writer has to write NSData objects into the provided Writeable. The server will
+// receive each of those separately and in order.
+// A gRPC call might not complete until the request writer finishes. On the other hand, the
+// request finishing doesn't necessarily make the call to finish, as the server might continue
+// sending messages to the response side of the call indefinitely (depending on the semantics of
+// the specific remote method called).
+// To finish a call right away, invoke cancel.
+- (instancetype)initWithHost:(NSString *)host
+                      method:(GRPCMethodName *)method
+              requestsWriter:(id<GRXWriter>)requestsWriter NS_DESIGNATED_INITIALIZER;
+
+// Finishes the request side of this call, notifies the server that the RPC
+// should be cancelled, and finishes the response side of the call with an error
+// of code CANCELED.
+- (void)cancel;
+
+// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
+@end
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
new file mode 100644
index 0000000000000000000000000000000000000000..46a1e232e35f215d6d93e09c218bde2948af7f49
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -0,0 +1,406 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCCall.h"
+
+#include <grpc.h>
+#include <support/time.h>
+
+#import "GRPCMethodName.h"
+#import "private/GRPCChannel.h"
+#import "private/GRPCCompletionQueue.h"
+#import "private/GRPCDelegateWrapper.h"
+#import "private/GRPCMethodName+HTTP2Encoding.h"
+#import "private/NSData+GRPC.h"
+#import "private/NSDictionary+GRPC.h"
+#import "private/NSError+GRPC.h"
+
+// A grpc_call_error represents a precondition failure when invoking the
+// grpc_call_* functions. If one ever happens, it's a bug in this library.
+//
+// TODO(jcanizales): Can an application shut down gracefully when a thread other
+// than the main one throws an exception?
+static void AssertNoErrorInCall(grpc_call_error error) {
+  if (error != GRPC_CALL_OK) {
+    @throw [NSException exceptionWithName:NSInternalInconsistencyException
+                                   reason:@"Precondition of grpc_call_* not met."
+                                 userInfo:nil];
+  }
+}
+
+@interface GRPCCall () <GRXWriteable>
+// Makes it readwrite.
+@property(atomic, strong) NSDictionary *responseMetadata;
+@end
+
+// The following methods of a C gRPC call object aren't reentrant, and thus
+// calls to them must be serialized:
+// - add_metadata
+// - invoke
+// - start_write
+// - writes_done
+// - start_read
+// - destroy
+// The first four are called as part of responding to client commands, but
+// start_read we want to call as soon as we're notified that the RPC was
+// successfully established (which happens concurrently in the network queue).
+// Serialization is achieved by using a private serial queue to operate the
+// call object.
+// Because add_metadata and invoke are called and return successfully before
+// any of the other methods is called, they don't need to use the queue.
+//
+// Furthermore, start_write and writes_done can only be called after the
+// WRITE_ACCEPTED event for any previous write is received. This is achieved by
+// pausing the requests writer immediately every time it writes a value, and
+// resuming it again when WRITE_ACCEPTED is received.
+//
+// Similarly, start_read can only be called after the READ event for any
+// previous read is received. This is easier to enforce, as we're writing the
+// received messages into the writeable: start_read is enqueued once upon receiving
+// the CLIENT_METADATA_READ event, and then once after receiving each READ
+// event.
+@implementation GRPCCall {
+  dispatch_queue_t _callQueue;
+
+  grpc_call *_gRPCCall;
+  dispatch_once_t _callAlreadyInvoked;
+
+  GRPCChannel *_channel;
+  GRPCCompletionQueue *_completionQueue;
+
+  // The C gRPC library has less guarantees on the ordering of events than we
+  // do. Particularly, in the face of errors, there's no ordering guarantee at
+  // all. This wrapper over our actual writeable ensures thread-safety and
+  // correct ordering.
+  GRPCDelegateWrapper *_responseWriteable;
+  id<GRXWriter> _requestWriter;
+}
+
+@synthesize state = _state;
+
+- (instancetype)init {
+  return [self initWithHost:nil method:nil requestsWriter:nil];
+}
+
+// Designated initializer
+- (instancetype)initWithHost:(NSString *)host
+                      method:(GRPCMethodName *)method
+              requestsWriter:(id<GRXWriter>)requestWriter {
+  if (!host || !method) {
+    [NSException raise:NSInvalidArgumentException format:@"Neither host nor method can be nil."];
+  }
+  // TODO(jcanizales): Throw if the requestWriter was already started.
+  if ((self = [super init])) {
+    static dispatch_once_t initialization;
+    dispatch_once(&initialization, ^{
+      grpc_init();
+    });
+
+    _completionQueue = [GRPCCompletionQueue completionQueue];
+
+    _channel = [GRPCChannel channelToHost:host];
+    _gRPCCall = grpc_channel_create_call_old(_channel.unmanagedChannel,
+                                             method.HTTP2Path.UTF8String,
+                                             host.UTF8String,
+                                             gpr_inf_future);
+
+    // Serial queue to invoke the non-reentrant methods of the grpc_call object.
+    _callQueue = dispatch_queue_create("org.grpc.call", NULL);
+
+    _requestWriter = requestWriter;
+  }
+  return self;
+}
+
+#pragma mark Finish
+
+- (void)finishWithError:(NSError *)errorOrNil {
+  _requestWriter.state = GRXWriterStateFinished;
+  _requestWriter = nil;
+  if (errorOrNil) {
+    [_responseWriteable cancelWithError:errorOrNil];
+  } else {
+    [_responseWriteable enqueueSuccessfulCompletion];
+  }
+}
+
+- (void)cancelCall {
+  // Can be called from any thread, any number of times.
+  AssertNoErrorInCall(grpc_call_cancel(_gRPCCall));
+}
+
+- (void)cancel {
+  [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+                                            code:GRPCErrorCodeCancelled
+                                        userInfo:nil]];
+  [self cancelCall];
+}
+
+- (void)dealloc {
+  grpc_call *gRPCCall = _gRPCCall;
+  dispatch_async(_callQueue, ^{
+    grpc_call_destroy(gRPCCall);
+  });
+}
+
+#pragma mark Read messages
+
+// Only called from the call queue.
+// The handler will be called from the network queue.
+- (void)startReadWithHandler:(GRPCEventHandler)handler {
+  AssertNoErrorInCall(grpc_call_start_read_old(_gRPCCall, (__bridge_retained void *)handler));
+}
+
+// Called initially from the network queue once response headers are received,
+// then "recursively" from the responseWriteable queue after each response from the
+// server has been written.
+// If the call is currently paused, this is a noop. Restarting the call will invoke this
+// method.
+// TODO(jcanizales): Rename to readResponseIfNotPaused.
+- (void)startNextRead {
+  if (self.state == GRXWriterStatePaused) {
+    return;
+  }
+  __weak GRPCCall *weakSelf = self;
+  __weak GRPCDelegateWrapper *weakWriteable = _responseWriteable;
+
+  dispatch_async(_callQueue, ^{
+    [weakSelf startReadWithHandler:^(grpc_event *event) {
+      if (!event->data.read) {
+        // No more responses from the server.
+        return;
+      }
+      NSData *data = [NSData grpc_dataWithByteBuffer:event->data.read];
+      if (!data) {
+        // The app doesn't have enough memory to hold the server response. We
+        // don't want to throw, because the app shouldn't crash for a behavior
+        // that's on the hands of any server to have. Instead we finish and ask
+        // the server to cancel.
+        //
+        // TODO(jcanizales): No canonical code is appropriate for this situation
+        // (because it's just a client problem). Use another domain and an
+        // appropriately-documented code.
+        [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+                                                      code:GRPCErrorCodeInternal
+                                                  userInfo:nil]];
+        [weakSelf cancelCall];
+        return;
+      }
+      [weakWriteable enqueueMessage:data completionHandler:^{
+        [weakSelf startNextRead];
+      }];
+    }];
+  });
+}
+
+#pragma mark Send headers
+
+- (void)addHeaderWithName:(NSString *)name binaryValue:(NSData *)value {
+  grpc_metadata metadata;
+  // Safe to discard const qualifiers; we're not going to modify the contents.
+  metadata.key = (char *)name.UTF8String;
+  metadata.value = (char *)value.bytes;
+  metadata.value_length = value.length;
+  grpc_call_add_metadata_old(_gRPCCall, &metadata, 0);
+}
+
+- (void)addHeaderWithName:(NSString *)name ASCIIValue:(NSString *)value {
+  grpc_metadata metadata;
+  // Safe to discard const qualifiers; we're not going to modify the contents.
+  metadata.key = (char *)name.UTF8String;
+  metadata.value = (char *)value.UTF8String;
+  // The trailing \0 isn't encoded in HTTP2.
+  metadata.value_length = value.length;
+  grpc_call_add_metadata_old(_gRPCCall, &metadata, 0);
+}
+
+// TODO(jcanizales): Rename to commitHeaders.
+- (void)sendHeaders:(NSDictionary *)metadata {
+  for (NSString *name in metadata) {
+    id value = metadata[name];
+    if ([value isKindOfClass:[NSData class]]) {
+      [self addHeaderWithName:name binaryValue:value];
+    } else if ([value isKindOfClass:[NSString class]]) {
+      [self addHeaderWithName:name ASCIIValue:value];
+    }
+  }
+}
+
+#pragma mark GRXWriteable implementation
+
+// Only called from the call queue. The error handler will be called from the
+// network queue if the write didn't succeed.
+- (void)writeMessage:(NSData *)message withErrorHandler:(void (^)())errorHandler {
+
+  __weak GRPCCall *weakSelf = self;
+  GRPCEventHandler resumingHandler = ^(grpc_event *event) {
+    if (event->data.write_accepted != GRPC_OP_OK) {
+      errorHandler();
+    }
+    // Resume the request writer (even in the case of error).
+    // TODO(jcanizales): No need to do it in the case of errors anymore?
+    GRPCCall *strongSelf = weakSelf;
+    if (strongSelf) {
+      strongSelf->_requestWriter.state = GRXWriterStateStarted;
+    }
+  };
+
+  grpc_byte_buffer *buffer = message.grpc_byteBuffer;
+  AssertNoErrorInCall(grpc_call_start_write_old(_gRPCCall,
+                                                buffer,
+                                                (__bridge_retained void *)resumingHandler,
+                                                0));
+  grpc_byte_buffer_destroy(buffer);
+}
+
+- (void)didReceiveValue:(id)value {
+  // TODO(jcanizales): Throw/assert if value isn't NSData.
+
+  // Pause the input and only resume it when the C layer notifies us that writes
+  // can proceed.
+  _requestWriter.state = GRXWriterStatePaused;
+
+  __weak GRPCCall *weakSelf = self;
+  dispatch_async(_callQueue, ^{
+    [weakSelf writeMessage:value withErrorHandler:^{
+      [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+                                                    code:GRPCErrorCodeInternal
+                                                userInfo:nil]];
+    }];
+  });
+}
+
+// Only called from the call queue. The error handler will be called from the
+// network queue if the requests stream couldn't be closed successfully.
+- (void)finishRequestWithErrorHandler:(void (^)())errorHandler {
+  GRPCEventHandler handler = ^(grpc_event *event) {
+    if (event->data.finish_accepted != GRPC_OP_OK) {
+      errorHandler();
+    }
+  };
+  AssertNoErrorInCall(grpc_call_writes_done_old(_gRPCCall, (__bridge_retained void *)handler));
+}
+
+- (void)didFinishWithError:(NSError *)errorOrNil {
+  if (errorOrNil) {
+    [self cancel];
+  } else {
+    __weak GRPCCall *weakSelf = self;
+    dispatch_async(_callQueue, ^{
+      [weakSelf finishRequestWithErrorHandler:^{
+        [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+                                                      code:GRPCErrorCodeInternal
+                                                  userInfo:nil]];
+      }];
+    });
+  }
+}
+
+#pragma mark Invoke
+
+// Both handlers will eventually be called, from the network queue. Writes can start immediately
+// after this.
+// The first one (metadataHandler), when the response headers are received.
+// The second one (completionHandler), whenever the RPC finishes for any reason.
+- (void)invokeCallWithMetadataHandler:(GRPCEventHandler)metadataHandler
+                    completionHandler:(GRPCEventHandler)completionHandler {
+  AssertNoErrorInCall(grpc_call_invoke_old(_gRPCCall,
+                                           _completionQueue.unmanagedQueue,
+                                           (__bridge_retained void *)metadataHandler,
+                                           (__bridge_retained void *)completionHandler,
+                                           0));
+}
+
+- (void)invokeCall {
+  __weak GRPCCall *weakSelf = self;
+  [self invokeCallWithMetadataHandler:^(grpc_event *event) {
+    // Response metadata received.
+    // TODO(jcanizales): Name the type of event->data.client_metadata_read
+    // in the C library so one can actually pass the object to a method.
+    grpc_metadata *entries = event->data.client_metadata_read.elements;
+    size_t count = event->data.client_metadata_read.count;
+    GRPCCall *strongSelf = weakSelf;
+    if (strongSelf) {
+      strongSelf.responseMetadata = [NSDictionary grpc_dictionaryFromMetadata:entries
+                                                                        count:count];
+      [strongSelf startNextRead];
+    }
+  } completionHandler:^(grpc_event *event) {
+    // TODO(jcanizales): Merge HTTP2 trailers into response metadata.
+    [weakSelf finishWithError:[NSError grpc_errorFromStatus:&event->data.finished]];
+  }];
+  // Now that the RPC has been initiated, request writes can start.
+  [_requestWriter startWithWriteable:self];
+}
+
+#pragma mark GRXWriter implementation
+
+- (void)startWithWriteable:(id<GRXWriteable>)writeable {
+  // The following produces a retain cycle self:_responseWriteable:self, which is only
+  // broken when didFinishWithError: is sent to the wrapped writeable.
+  // Care is taken not to retain self strongly in any of the blocks used in
+  // the implementation of GRPCCall, so that the life of the instance is
+  // determined by this retain cycle.
+  _responseWriteable = [[GRPCDelegateWrapper alloc] initWithWriteable:writeable writer:self];
+  [self sendHeaders:_requestMetadata];
+  [self invokeCall];
+}
+
+- (void)setState:(GRXWriterState)newState {
+  // Manual transitions are only allowed from the started or paused states.
+  if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) {
+    return;
+  }
+
+  switch (newState) {
+    case GRXWriterStateFinished:
+      _state = newState;
+      // Per GRXWriter's contract, setting the state to Finished manually
+      // means one doesn't wish the writeable to be messaged anymore.
+      [_responseWriteable cancelSilently];
+      _responseWriteable = nil;
+      return;
+    case GRXWriterStatePaused:
+      _state = newState;
+      return;
+    case GRXWriterStateStarted:
+      if (_state == GRXWriterStatePaused) {
+        _state = newState;
+        [self startNextRead];
+      }
+      return;
+    case GRXWriterStateNotStarted:
+      return;
+  }
+}
+@end
diff --git a/src/objective-c/GRPCClient/GRPCMethodName.h b/src/objective-c/GRPCClient/GRPCMethodName.h
new file mode 100644
index 0000000000000000000000000000000000000000..a62c4797885528f4366ad7850ea1ac5e4498980b
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCMethodName.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+// See the README file for an introduction to this library.
+
+// A fully-qualified gRPC method name. Full qualification is needed because a gRPC endpoint can
+// implement multiple interfaces.
+// TODO(jcanizales): Is this proto-specific, or actual part of gRPC? If the former, move one layer up.
+@interface GRPCMethodName : NSObject
+@property(nonatomic, readonly) NSString *package;
+@property(nonatomic, readonly) NSString *interface;
+@property(nonatomic, readonly) NSString *method;
+- (instancetype)initWithPackage:(NSString *)package
+                      interface:(NSString *)interface
+                         method:(NSString *)method;
+@end
diff --git a/src/objective-c/GRPCClient/GRPCMethodName.m b/src/objective-c/GRPCClient/GRPCMethodName.m
new file mode 100644
index 0000000000000000000000000000000000000000..fbaf24b9f08394ee05fff89bd7e47e9ba71967ef
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCMethodName.m
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCMethodName.h"
+
+@implementation GRPCMethodName
+- (instancetype)initWithPackage:(NSString *)package
+                      interface:(NSString *)interface
+                         method:(NSString *)method {
+  if ((self = [super init])) {
+    _package = [package copy];
+    _interface = [interface copy];
+    _method = [method copy];
+  }
+  return self;
+}
+@end
diff --git a/src/objective-c/GRPCClient/README.md b/src/objective-c/GRPCClient/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..9b87f0316cfff7cd3874c2e71a005524ebcae308
--- /dev/null
+++ b/src/objective-c/GRPCClient/README.md
@@ -0,0 +1,4 @@
+This is a generic gRPC client for Objective-C on iOS.
+
+If you're trying to get started with the library or with gRPC, you should first
+read GRPCCall.h.
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h
new file mode 100644
index 0000000000000000000000000000000000000000..7442f1fae44d041501b20ba3216b05157382b7db
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+struct grpc_channel;
+
+// Each separate instance of this class represents at least one TCP
+// connection to the provided host. To create a grpc_call, pass the
+// value of the unmanagedChannel property to grpc_channel_create_call.
+// Release this object when the call is finished.
+@interface GRPCChannel : NSObject
+@property(nonatomic, readonly) struct grpc_channel *unmanagedChannel;
+
+// Convenience constructor to allow for reuse of connections.
++ (instancetype)channelToHost:(NSString *)host;
+
+// Designated initializer
+- (instancetype)initWithHost:(NSString *)host;
+@end
diff --git a/src/cpp/server/server_rpc_handler.h b/src/objective-c/GRPCClient/private/GRPCChannel.m
similarity index 67%
rename from src/cpp/server/server_rpc_handler.h
rename to src/objective-c/GRPCClient/private/GRPCChannel.m
index a43e07dc5f9bfdbf1b93285703b34fc7b1fa26f2..3e6952cfa38a6dd96dd9a8bc3bcfe83ba1cfc986 100644
--- a/src/cpp/server/server_rpc_handler.h
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -31,36 +31,35 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_SERVER_SERVER_RPC_HANDLER_H__
-#define __GRPCPP_INTERNAL_SERVER_SERVER_RPC_HANDLER_H__
+#import "GRPCChannel.h"
 
-#include <memory>
+#import <grpc.h>
 
-#include <grpc++/completion_queue.h>
-#include <grpc++/status.h>
+@implementation GRPCChannel
 
-namespace grpc {
++ (instancetype)channelToHost:(NSString *)host {
+  // TODO(jcanizales): Reuse channels.
+  return [[self alloc] initWithHost:host];
+}
 
-class AsyncServerContext;
-class RpcServiceMethod;
+- (instancetype)init {
+  return [self initWithHost:nil];
+}
 
-class ServerRpcHandler {
- public:
-  // Takes ownership of async_server_context.
-  ServerRpcHandler(AsyncServerContext *async_server_context,
-                   RpcServiceMethod *method);
+// Designated initializer
+- (instancetype)initWithHost:(NSString *)host {
+  if (!host) {
+    [NSException raise:NSInvalidArgumentException format:@"Host can't be nil."];
+  }
+  if ((self = [super init])) {
+    _unmanagedChannel = grpc_channel_create(host.UTF8String, NULL);
+  }
+  return self;
+}
 
-  void StartRpc();
-
- private:
-  CompletionQueue::CompletionType WaitForNextEvent();
-  void FinishRpc(const Status &status);
-
-  std::unique_ptr<AsyncServerContext> async_server_context_;
-  RpcServiceMethod *method_;
-  CompletionQueue cq_;
-};
-
-}  // namespace grpc
-
-#endif  // __GRPCPP_INTERNAL_SERVER_SERVER_RPC_HANDLER_H__
+- (void)dealloc {
+  // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely,
+  // as in the past that made this call to crash.
+  grpc_channel_destroy(_unmanagedChannel);
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a8e397443e98c027ed782a3f99e3bce1764a798
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+struct grpc_completion_queue;
+struct grpc_event;
+
+typedef void(^GRPCEventHandler)(struct grpc_event *event);
+
+// This class lets one more easily use grpc_completion_queue. To use it, pass
+// the value of the unmanagedQueue property of an instance of this class to
+// grpc_call_start_invoke. Then for every grpc_call_* method that accepts a tag,
+// you can pass a block of type GRPCEventHandler (remembering to cast it using
+// __bridge_retained). The block is guaranteed to eventually be called, by a
+// concurrent queue, and then released. Each such block is passed a pointer to
+// the grpc_event that carried it (in event->tag).
+// Release the GRPCCompletionQueue object only after you are not going to pass
+// any more blocks to the grpc_call that's using it.
+@interface GRPCCompletionQueue : NSObject
+@property(nonatomic, readonly) struct grpc_completion_queue *unmanagedQueue;
+
++ (instancetype)completionQueue;
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
new file mode 100644
index 0000000000000000000000000000000000000000..c81e9a2a9881a4a4978198d3e57039c37ae613c3
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
@@ -0,0 +1,106 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCCompletionQueue.h"
+
+#import <grpc.h>
+
+@implementation GRPCCompletionQueue
+
++ (instancetype)completionQueue {
+  // TODO(jcanizales): Reuse completion queues to consume only one thread,
+  // instead of one per call.
+  return [[self alloc] init];
+}
+
+- (instancetype)init {
+  if ((self = [super init])) {
+    _unmanagedQueue = grpc_completion_queue_create();
+
+    // This is for the following block to capture the pointer by value (instead
+    // of retaining self and doing self->_unmanagedQueue). This is essential
+    // because the block doesn't end until after grpc_completion_queue_shutdown
+    // is called, and we only want that to happen after nobody's using the queue
+    // anymore (i.e. on self dealloc). So the block would never end if it
+    // retained self.
+    grpc_completion_queue *unmanagedQueue = _unmanagedQueue;
+
+    // Start a loop on a concurrent queue to read events from the completion
+    // queue and dispatch each.
+    static dispatch_once_t initialization;
+    static dispatch_queue_t gDefaultConcurrentQueue;
+    dispatch_once(&initialization, ^{
+      gDefaultConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    });
+    dispatch_async(gDefaultConcurrentQueue, ^{
+      while (YES) {
+        // The following call blocks until an event is available.
+        grpc_event *event = grpc_completion_queue_next(unmanagedQueue, gpr_inf_future);
+        switch (event->type) {
+          case GRPC_WRITE_ACCEPTED:
+          case GRPC_FINISH_ACCEPTED:
+          case GRPC_CLIENT_METADATA_READ:
+          case GRPC_READ:
+          case GRPC_FINISHED:
+            if (event->tag) {
+              GRPCEventHandler handler = (__bridge_transfer GRPCEventHandler) event->tag;
+              handler(event);
+            }
+            grpc_event_finish(event);
+            continue;
+          case GRPC_QUEUE_SHUTDOWN:
+            grpc_completion_queue_destroy(unmanagedQueue);
+            grpc_event_finish(event);
+            return;
+          case GRPC_SERVER_RPC_NEW:
+            NSAssert(NO, @"C gRPC library produced a server-only event.");
+            continue;
+        }
+        // This means the C gRPC library produced an event that wasn't known
+        // when this library was written. To preserve evolvability, ignore the
+        // unknown event on release builds.
+        NSAssert(NO, @"C gRPC library produced an unknown event.");
+      };
+    });
+  }
+  return self;
+}
+
+- (void)dealloc {
+  // This makes the completion queue produce a GRPC_QUEUE_SHUTDOWN event *after*
+  // all other pending events are flushed. What this means is all the blocks
+  // passed to the gRPC C library as void* are eventually called, even if some
+  // are called after self is dealloc'd.
+  grpc_completion_queue_shutdown(_unmanagedQueue);
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8a73b12df9bf395cb844f25aaa3579594f771a4
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.h
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+@protocol GRXWriteable;
+@protocol GRXWriter;
+
+// This is a thread-safe wrapper over a GRXWriteable instance. It lets one
+// enqueue calls to a GRXWriteable instance for the main thread, guaranteeing
+// that didFinishWithError: is the last message sent to it (no matter what
+// messages are sent to the wrapper, in what order, nor from which thread). It
+// also guarantees that, if cancelWithError: is called from the main thread
+// (e.g. by the app cancelling the writes), no further messages are sent to the
+// writeable except didFinishWithError:.
+//
+// TODO(jcanizales): Let the user specify another queue for the writeable
+// callbacks.
+// TODO(jcanizales): Rename to GRXWriteableWrapper and move to the Rx library.
+@interface GRPCDelegateWrapper : NSObject
+
+// The GRXWriteable passed is the wrapped writeable.
+// Both the GRXWriter instance and the GRXWriteable instance are retained until
+// didFinishWithError: is sent to the writeable, and released after that.
+// This is used to create a retain cycle that keeps both objects alive until the
+// writing is explicitly finished.
+- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable writer:(id<GRXWriter>)writer
+    NS_DESIGNATED_INITIALIZER;
+
+// Enqueues didReceiveValue: to be sent to the writeable in the main thread.
+// The passed handler is invoked from the main thread after didReceiveValue:
+// returns.
+- (void)enqueueMessage:(NSData *)message completionHandler:(void (^)())handler;
+
+// Enqueues didFinishWithError:nil to be sent to the writeable in the main
+// thread. After that message is sent to the writeable, all other methods of
+// this object are effectively noops.
+- (void)enqueueSuccessfulCompletion;
+
+// If the writeable has not yet received a didFinishWithError: message, this
+// will enqueue one to be sent to it in the main thread, and cancel all other
+// pending messages to the writeable enqueued by this object (both past and
+// future).
+// The error argument cannot be nil.
+- (void)cancelWithError:(NSError *)error;
+
+// Cancels all pending messages to the writeable enqueued by this object (both
+// past and future). Because the writeable won't receive didFinishWithError:,
+// this also releases the writeable and the writer.
+- (void)cancelSilently;
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m
new file mode 100644
index 0000000000000000000000000000000000000000..8c6225169a2e9198423c0bd973fae7ae8c487f1b
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCDelegateWrapper.m
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCDelegateWrapper.h"
+
+#import <RxLibrary/GRXWriteable.h>
+
+@interface GRPCDelegateWrapper ()
+// These are atomic so that cancellation can nillify them from any thread.
+@property(atomic, strong) id<GRXWriteable> writeable;
+@property(atomic, strong) id<GRXWriter> writer;
+@end
+
+@implementation GRPCDelegateWrapper {
+  dispatch_queue_t _writeableQueue;
+  // This ensures that didFinishWithError: is only sent once to the writeable.
+  dispatch_once_t _alreadyFinished;
+}
+
+- (instancetype)init {
+  return [self initWithWriteable:nil writer:nil];
+}
+
+// Designated initializer
+- (instancetype)initWithWriteable:(id<GRXWriteable>)writeable writer:(id<GRXWriter>)writer {
+  if (self = [super init]) {
+    _writeableQueue = dispatch_get_main_queue();
+    _writeable = writeable;
+    _writer = writer;
+  }
+  return self;
+}
+
+- (void)enqueueMessage:(NSData *)message completionHandler:(void (^)())handler {
+  dispatch_async(_writeableQueue, ^{
+    // We're racing a possible cancellation performed by another thread. To turn
+    // all already-enqueued messages into noops, cancellation nillifies the
+    // writeable property. If we get it before it's nil, we won
+    // the race.
+    id<GRXWriteable> writeable = self.writeable;
+    if (writeable) {
+      [writeable didReceiveValue:message];
+      handler();
+    }
+  });
+}
+
+- (void)enqueueSuccessfulCompletion {
+  dispatch_async(_writeableQueue, ^{
+    dispatch_once(&_alreadyFinished, ^{
+      // Cancellation is now impossible. None of the other three blocks can run
+      // concurrently with this one.
+      [self.writeable didFinishWithError:nil];
+      // Break the retain cycle with writer, and skip any possible message to the
+      // wrapped writeable enqueued after this one.
+      self.writeable = nil;
+      self.writer = nil;
+    });
+  });
+}
+
+- (void)cancelWithError:(NSError *)error {
+  NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion.");
+  dispatch_once(&_alreadyFinished, ^{
+    // Skip any of the still-enqueued messages to the wrapped writeable. We use
+    // the atomic setter to nillify writer and writeable because we might be
+    // running concurrently with the blocks in _writeableQueue, and assignment
+    // with ARC isn't atomic.
+    id<GRXWriteable> writeable = self.writeable;
+    self.writeable = nil;
+
+    dispatch_async(_writeableQueue, ^{
+      [writeable didFinishWithError:error];
+      // Break the retain cycle with writer.
+      self.writer = nil;
+    });
+  });
+}
+
+- (void)cancelSilently {
+  dispatch_once(&_alreadyFinished, ^{
+    // Skip any of the still-enqueued messages to the wrapped writeable. We use
+    // the atomic setter to nillify writer and writeable because we might be
+    // running concurrently with the blocks in _writeableQueue, and assignment
+    // with ARC isn't atomic.
+    self.writeable = nil;
+    self.writer = nil;
+  });
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCMethodName+HTTP2Encoding.h b/src/objective-c/GRPCClient/private/GRPCMethodName+HTTP2Encoding.h
new file mode 100644
index 0000000000000000000000000000000000000000..05e35bb1a399ed255fc778afcaa3414a111756a4
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCMethodName+HTTP2Encoding.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "GRPCMethodName.h"
+
+@interface GRPCMethodName (HTTP2Encoding)
+- (NSString *)HTTP2Path;
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCMethodName+HTTP2Encoding.m b/src/objective-c/GRPCClient/private/GRPCMethodName+HTTP2Encoding.m
new file mode 100644
index 0000000000000000000000000000000000000000..3fb9af25ec44598589ea624ebbb32e1b9a4f7daa
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCMethodName+HTTP2Encoding.m
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCMethodName+HTTP2Encoding.h"
+
+@implementation GRPCMethodName (HTTP2Encoding)
+- (NSString *)HTTP2Path {
+  if (self.package) {
+    return [NSString stringWithFormat:@"/%@.%@/%@", self.package, self.interface, self.method];
+  } else {
+    return [NSString stringWithFormat:@"/%@/%@", self.interface, self.method];
+  }
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/NSData+GRPC.h b/src/objective-c/GRPCClient/private/NSData+GRPC.h
new file mode 100644
index 0000000000000000000000000000000000000000..936c2a0e8ae265453a64f5f27ca0ecf68d6a8da4
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/NSData+GRPC.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+struct grpc_byte_buffer;
+
+@interface NSData (GRPC)
++ (instancetype)grpc_dataWithByteBuffer:(struct grpc_byte_buffer *)buffer;
+- (struct grpc_byte_buffer *)grpc_byteBuffer;
+@end
diff --git a/src/objective-c/GRPCClient/private/NSData+GRPC.m b/src/objective-c/GRPCClient/private/NSData+GRPC.m
new file mode 100644
index 0000000000000000000000000000000000000000..b5f952722cdaad66813bc8c63e529a8173ce2792
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/NSData+GRPC.m
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "NSData+GRPC.h"
+
+#include <byte_buffer.h>
+#include <string.h>
+
+// TODO(jcanizales): Move these two incantations to the C library.
+
+static void CopyByteBufferToCharArray(grpc_byte_buffer *buffer, char *array) {
+  size_t offset = 0;
+  grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer);
+  gpr_slice next;
+  while (grpc_byte_buffer_reader_next(reader, &next) != 0){
+    memcpy(array + offset, GPR_SLICE_START_PTR(next), (size_t) GPR_SLICE_LENGTH(next));
+    offset += GPR_SLICE_LENGTH(next);
+    gpr_slice_unref(next);
+  }
+  grpc_byte_buffer_reader_destroy(reader);
+}
+
+static grpc_byte_buffer *CopyCharArrayToNewByteBuffer(const char *array, size_t length) {
+  gpr_slice slice = gpr_slice_from_copied_buffer(array, length);
+  grpc_byte_buffer *buffer = grpc_byte_buffer_create(&slice, 1);
+  gpr_slice_unref(slice);
+  return buffer;
+}
+
+@implementation NSData (GRPC)
++ (instancetype)grpc_dataWithByteBuffer:(grpc_byte_buffer *)buffer {
+  NSUInteger length = grpc_byte_buffer_length(buffer);
+  char *array = malloc(length * sizeof(*array));
+  if (!array) {
+    // TODO(jcanizales): grpc_byte_buffer is reference-counted, so we can
+    // prevent this memory problem by implementing a subclass of NSData
+    // that wraps the grpc_byte_buffer. Then enumerateByteRangesUsingBlock:
+    // can be implemented using a grpc_byte_buffer_reader.
+    return nil;
+  }
+  CopyByteBufferToCharArray(buffer, array);
+  return [self dataWithBytesNoCopy:array length:length freeWhenDone:YES];
+}
+
+- (grpc_byte_buffer *)grpc_byteBuffer {
+  // Some implementations of NSData, as well as grpc_byte_buffer, support O(1)
+  // appending of byte arrays by not using internally a single contiguous memory
+  // block for representation.
+  // The following implementation is thus not optimal, sometimes requiring two
+  // copies (one by self.bytes and another by gpr_slice_from_copied_buffer).
+  // If it turns out to be an issue, we can use enumerateByteRangesUsingblock:
+  // to create an array of gpr_slice objects to pass to grpc_byte_buffer_create.
+  // That would make it do exactly one copy, always.
+  return CopyCharArrayToNewByteBuffer((const char *)self.bytes, (size_t)self.length);
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.h b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf0233fd460f4802b2af152d30074da839d45ea2
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+struct grpc_metadata;
+
+@interface NSDictionary (GRPC)
++ (instancetype)grpc_dictionaryFromMetadata:(struct grpc_metadata *)entries count:(size_t)count;
+@end
diff --git a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
new file mode 100644
index 0000000000000000000000000000000000000000..345ff3e1e6ddfdb7c3ca308d29d51227409694e2
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "NSDictionary+GRPC.h"
+
+#include <grpc.h>
+
+@implementation NSDictionary (GRPC)
++ (instancetype)grpc_dictionaryFromMetadata:(grpc_metadata *)entries count:(size_t)count {
+  NSMutableDictionary *metadata = [NSMutableDictionary dictionaryWithCapacity:count];
+  for (grpc_metadata *entry = entries; entry < entries + count; entry++) {
+    // TODO(jcanizales): Verify in a C library test that it's converting header names to lower case automatically.
+    NSString *name = [NSString stringWithUTF8String:entry->key];
+    if (!name) {
+      continue;
+    }
+    if (!metadata[name]) {
+      metadata[name] = [NSMutableArray array];
+    }
+    // TODO(jcanizales): Should we use a non-copy constructor?
+    [metadata[name] addObject:[NSData dataWithBytes:entry->value
+                                             length:entry->value_length]];
+  }
+  return metadata;
+}
+@end
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.h b/src/objective-c/GRPCClient/private/NSError+GRPC.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7439fa06735f64eab621946864a5b6b66d6a70e
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+// TODO(jcanizales): Make the domain string public.
+extern NSString *const kGRPCErrorDomain;
+
+// TODO(jcanizales): Make this public and document each code.
+typedef NS_ENUM(NSInteger, GRPCErrorCode) {
+  GRPCErrorCodeCancelled = 1,
+  GRPCErrorCodeUnknown = 2,
+  GRPCErrorCodeInvalidArgument = 3,
+  GRPCErrorCodeDeadlineExceeded = 4,
+  GRPCErrorCodeNotFound = 5,
+  GRPCErrorCodeAlreadyExists = 6,
+  GRPCErrorCodePermissionDenied = 7,
+  GRPCErrorCodeUnauthenticated = 16,
+  GRPCErrorCodeResourceExhausted = 8,
+  GRPCErrorCodeFailedPrecondition = 9,
+  GRPCErrorCodeAborted = 10,
+  GRPCErrorCodeOutOfRange = 11,
+  GRPCErrorCodeUnimplemented = 12,
+  GRPCErrorCodeInternal = 13,
+  GRPCErrorCodeUnavailable = 14,
+  GRPCErrorCodeDataLoss = 15
+};
+
+// TODO(jcanizales): This is conflating trailing metadata with Status details. Fix it once there's
+// a decision on how to codify Status.
+#include <grpc/status.h>
+struct grpc_metadata;
+struct grpc_status {
+    grpc_status_code status;
+    const char *details;
+    size_t metadata_count;
+    struct grpc_metadata *metadata_elements;
+};
+
+@interface NSError (GRPC)
+// Returns nil if the status is OK. Otherwise, a NSError whose code is one of
+// GRPCErrorCode and whose domain is kGRPCErrorDomain.
++ (instancetype)grpc_errorFromStatus:(struct grpc_status *)status;
+@end
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.m b/src/objective-c/GRPCClient/private/NSError+GRPC.m
new file mode 100644
index 0000000000000000000000000000000000000000..4fc1249efc282e71268b10f679705424acdeee81
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.m
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "NSError+GRPC.h"
+
+#include <grpc.h>
+
+NSString *const kGRPCErrorDomain = @"org.grpc";
+
+@implementation NSError (GRPC)
++ (instancetype)grpc_errorFromStatus:(struct grpc_status *)status {
+  if (status->status == GRPC_STATUS_OK) {
+    return nil;
+  }
+  NSString *message =
+      [NSString stringWithFormat:@"Code=%i Message='%s'", status->status, status->details];
+  return [NSError errorWithDomain:kGRPCErrorDomain
+                             code:status->status
+                         userInfo:@{NSLocalizedDescriptionKey: message}];
+}
+@end
diff --git a/src/objective-c/README.md b/src/objective-c/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..05e9f2b4dc91c7a07353b2c9858d0b1f2e3d5fd0
--- /dev/null
+++ b/src/objective-c/README.md
@@ -0,0 +1,3 @@
+gRPC implementation for Objective-C on iOS
+
+This is a work in progress.
diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.h b/src/objective-c/RxLibrary/GRXImmediateWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..74f4dc69f4bb4fc12dc4aa300ac06048b6ad1b84
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXImmediateWriter.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "GRXWriter.h"
+
+// Utility to construct GRXWriter instances from values that are immediately available when
+// required. The returned writers all support pausing and early termination.
+//
+// Unless the writeable callback pauses them or stops them early, these writers will do all their
+// interactions with the writeable before the start method returns.
+@interface GRXImmediateWriter : NSObject<GRXWriter>
+
+// Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to
+// its writeable. The NSEnumerator is released when it finishes.
++ (id<GRXWriter>)writerWithEnumerator:(NSEnumerator *)enumerator;
+
+// Returns a writer that pushes to its writeable the successive values returned by the passed
+// block. When the block first returns nil, it is released.
++ (id<GRXWriter>)writerWithValueSupplier:(id (^)())block;
+
+// Returns a writer that iterates over the values of the passed container and pushes them to
+// its writeable. The container is released when the iteration is over.
+//
+// Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to
+// call one method per element. Because GRXWriteable instances accept values one by one, that speed
+// gain doesn't happen here.
++ (id<GRXWriter>)writerWithContainer:(id<NSFastEnumeration>)container;
+
+// Returns a writer that sends the passed value to its writeable and then finishes (releasing the
+// value).
++ (id<GRXWriter>)writerWithValue:(id)value;
+
+// Returns a writer that, as part of its start method, sends the passed error to the writeable
+// (then releasing the error).
++ (id<GRXWriter>)writerWithError:(NSError *)error;
+
+// Returns a writer that, as part of its start method, finishes immediately without sending any
+// values to its writeable.
++ (id<GRXWriter>)emptyWriter;
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXImmediateWriter.m b/src/objective-c/RxLibrary/GRXImmediateWriter.m
new file mode 100644
index 0000000000000000000000000000000000000000..4417ae8f161e8c6abd0b9b006a5a0b7916b853db
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXImmediateWriter.m
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXImmediateWriter.h"
+
+#import "NSEnumerator+GRXUtil.h"
+
+@implementation GRXImmediateWriter {
+  NSEnumerator *_enumerator;
+  NSError *_errorOrNil;
+  id<GRXWriteable> _writeable;
+}
+
+@synthesize state = _state;
+
+- (instancetype) init {
+  return [self initWithEnumerator:nil error:nil]; // results in an empty writer.
+}
+
+// Designated initializer
+- (instancetype)initWithEnumerator:(NSEnumerator *)enumerator error:(NSError *)errorOrNil {
+  if (((self = [super init]))) {
+    _enumerator = enumerator;
+    _errorOrNil = errorOrNil;
+    _state = GRXWriterStateNotStarted;
+  }
+  return self;
+}
+
+#pragma mark Convenience constructors
+
++ (instancetype)writerWithEnumerator:(NSEnumerator *)enumerator error:(NSError *)errorOrNil {
+  return [[self alloc] initWithEnumerator:enumerator error:errorOrNil];
+}
+
++ (id<GRXWriter>)writerWithEnumerator:(NSEnumerator *)enumerator {
+  return [self writerWithEnumerator:enumerator error:nil];
+}
+
++ (id<GRXWriter>)writerWithValueSupplier:(id (^)())block {
+  return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithValueSupplier:block]];
+}
+
++ (id<GRXWriter>)writerWithContainer:(id<NSFastEnumeration>)container {
+  return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithContainer:container]];;
+}
+
++ (id<GRXWriter>)writerWithValue:(id)value {
+  if (value) {
+    return [self writerWithEnumerator:[NSEnumerator grx_enumeratorWithSingleValue:value]];
+  } else {
+    return [self emptyWriter];
+  }
+}
+
++ (id<GRXWriter>)writerWithError:(NSError *)error {
+  if (error) {
+    return [self writerWithEnumerator:nil error:error];
+  } else {
+    return [self emptyWriter];
+  }
+}
+
++ (id<GRXWriter>)emptyWriter {
+  static GRXImmediateWriter *emptyWriter;
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    emptyWriter = [self writerWithEnumerator:nil error:nil];
+  });
+  return emptyWriter;
+}
+
+#pragma mark Conformance with GRXWriter
+
+// Most of the complexity in this implementation is the result of supporting pause and resumption of
+// the GRXWriter. It's an important feature for instances of GRXWriter that are backed by a
+// container (which may be huge), or by a NSEnumerator (which may even be infinite).
+
+- (void)writeUntilPausedOrStopped {
+  id value;
+  while (value = [_enumerator nextObject]) {
+    [_writeable didReceiveValue:value];
+    // If the writeable has a reference to us, it might change our state to paused or finished.
+    if (_state == GRXWriterStatePaused || _state == GRXWriterStateFinished) {
+      return;
+    }
+  }
+  [self finishWithError:_errorOrNil];
+}
+
+- (void)startWithWriteable:(id<GRXWriteable>)writeable {
+  _state = GRXWriterStateStarted;
+  _writeable = writeable;
+  [self writeUntilPausedOrStopped];
+}
+
+- (void)finishWithError:(NSError *)errorOrNil {
+  _state = GRXWriterStateFinished;
+  _enumerator = nil;
+  _errorOrNil = nil;
+  id<GRXWriteable> writeable = _writeable;
+  _writeable = nil;
+  [writeable didFinishWithError:errorOrNil];
+}
+
+- (void)setState:(GRXWriterState)newState {
+  // Manual transitions are only allowed from the started or paused states.
+  if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) {
+    return;
+  }
+
+  switch (newState) {
+    case GRXWriterStateFinished:
+      _state = newState;
+      _enumerator = nil;
+      _errorOrNil = nil;
+      // Per GRXWriter's contract, setting the state to Finished manually
+      // means one doesn't wish the writeable to be messaged anymore.
+      _writeable = nil;
+      return;
+    case GRXWriterStatePaused:
+      _state = newState;
+      return;
+    case GRXWriterStateStarted:
+      if (_state == GRXWriterStatePaused) {
+        _state = newState;
+        [self writeUntilPausedOrStopped];
+      }
+      return;
+    case GRXWriterStateNotStarted:
+      return;
+  }
+}
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriteable.h b/src/objective-c/RxLibrary/GRXWriteable.h
new file mode 100644
index 0000000000000000000000000000000000000000..5aa00ba40ec1cf24937ce9aad85467099a118bea
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriteable.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+// A GRXWriteable is an object to which a sequence of values can be sent. The
+// sequence finishes with an optional error.
+@protocol GRXWriteable <NSObject>
+
+// Push the next value of the sequence to the receiving object.
+// TODO(jcanizales): Name it enumerator:(id<GRXEnumerator>) didProduceValue:(id)?
+- (void)didReceiveValue:(id)value;
+
+// Signal that the sequence is completed, or that an error ocurred. After this
+// message is sent to the instance, neither it nor didReceiveValue: may be
+// called again.
+// TODO(jcanizales): enumerator:(id<GRXEnumerator>) didFinishWithError:(NSError*)?
+- (void)didFinishWithError:(NSError *)errorOrNil;
+@end
+
+typedef void (^GRXValueHandler)(id value);
+typedef void (^GRXCompletionHandler)(NSError *errorOrNil);
+
+// Utility to create objects that conform to the GRXWriteable protocol, from
+// blocks that handle each of the two methods of the protocol.
+@interface GRXWriteable : NSObject<GRXWriteable>
+- (instancetype)initWithValueHandler:(GRXValueHandler)valueHandler
+                   completionHandler:(GRXCompletionHandler)completionHandler
+    NS_DESIGNATED_INITIALIZER;
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriteable.m b/src/objective-c/RxLibrary/GRXWriteable.m
new file mode 100644
index 0000000000000000000000000000000000000000..9567e42b747c7d512d081eb99ff51485152a80ce
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriteable.m
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXWriteable.h"
+
+@implementation GRXWriteable {
+  GRXValueHandler _valueHandler;
+  GRXCompletionHandler _completionHandler;
+}
+
+- (instancetype)init {
+  return [self initWithValueHandler:nil completionHandler:nil];
+}
+
+// Designated initializer
+- (instancetype)initWithValueHandler:(GRXValueHandler)valueHandler
+                   completionHandler:(GRXCompletionHandler)completionHandler {
+  if ((self = [super init])) {
+    _valueHandler = valueHandler;
+    _completionHandler = completionHandler;
+  }
+  return self;
+}
+
+- (void)didReceiveValue:(id)value {
+  if (_valueHandler) {
+    _valueHandler(value);
+  }
+}
+
+- (void)didFinishWithError:(NSError *)errorOrNil {
+  if (_completionHandler) {
+    _completionHandler(errorOrNil);
+  }
+}
+@end
diff --git a/src/cpp/server/async_server.cc b/src/objective-c/RxLibrary/GRXWriter+Immediate.h
similarity index 52%
rename from src/cpp/server/async_server.cc
rename to src/objective-c/RxLibrary/GRXWriter+Immediate.h
index 86faa07b31733e8a4e6c1ffed7f6ea6a7192eaa6..101df81e5e6a51bc165aba50be3169aedf7742b4 100644
--- a/src/cpp/server/async_server.cc
+++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.h
@@ -31,59 +31,36 @@
  *
  */
 
-#include <grpc++/async_server.h>
+#import "GRXWriter.h"
 
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-#include <grpc++/completion_queue.h>
+@interface GRXWriter (Immediate)
 
-namespace grpc {
+// Returns a writer that pulls values from the passed NSEnumerator instance and pushes them to
+// its writeable. The NSEnumerator is released when it finishes.
++ (instancetype)writerWithEnumerator:(NSEnumerator *)enumerator;
 
-AsyncServer::AsyncServer(CompletionQueue *cc)
-    : started_(false), shutdown_(false) {
-  server_ = grpc_server_create(cc->cq(), nullptr);
-}
+// Returns a writer that pushes to its writeable the successive values returned by the passed
+// block. When the block first returns nil, it is released.
++ (instancetype)writerWithValueSupplier:(id (^)())block;
 
-AsyncServer::~AsyncServer() {
-  std::unique_lock<std::mutex> lock(shutdown_mu_);
-  if (started_ && !shutdown_) {
-    lock.unlock();
-    Shutdown();
-  }
-  grpc_server_destroy(server_);
-}
+// Returns a writer that iterates over the values of the passed container and pushes them to
+// its writeable. The container is released when the iteration is over.
+//
+// Note that the usual speed gain of NSFastEnumeration over NSEnumerator results from not having to
+// call one method per element. Because GRXWriteable instances accept values one by one, that speed
+// gain doesn't happen here.
++ (instancetype)writerWithContainer:(id<NSFastEnumeration>)container;
 
-void AsyncServer::AddPort(const grpc::string &addr) {
-  GPR_ASSERT(!started_);
-  int success = grpc_server_add_http2_port(server_, addr.c_str());
-  GPR_ASSERT(success);
-}
+// Returns a writer that sends the passed value to its writeable and then finishes (releasing the
+// value).
++ (instancetype)writerWithValue:(id)value;
 
-void AsyncServer::Start() {
-  GPR_ASSERT(!started_);
-  started_ = true;
-  grpc_server_start(server_);
-}
+// Returns a writer that, as part of its start method, sends the passed error to the writeable
+// (then releasing the error).
++ (instancetype)writerWithError:(NSError *)error;
 
-void AsyncServer::RequestOneRpc() {
-  GPR_ASSERT(started_);
-  std::unique_lock<std::mutex> lock(shutdown_mu_);
-  if (shutdown_) {
-    return;
-  }
-  lock.unlock();
-  grpc_call_error err = grpc_server_request_call_old(server_, nullptr);
-  GPR_ASSERT(err == GRPC_CALL_OK);
-}
+// Returns a writer that, as part of its start method, finishes immediately without sending any
+// values to its writeable.
++ (instancetype)emptyWriter;
 
-void AsyncServer::Shutdown() {
-  std::unique_lock<std::mutex> lock(shutdown_mu_);
-  if (started_ && !shutdown_) {
-    shutdown_ = true;
-    lock.unlock();
-    // TODO(yangg) should we shutdown without start?
-    grpc_server_shutdown(server_);
-  }
-}
-
-}  // namespace grpc
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriter+Immediate.m b/src/objective-c/RxLibrary/GRXWriter+Immediate.m
new file mode 100644
index 0000000000000000000000000000000000000000..7dab5e2ba57ca92293cd887964dfdb45ab90f71a
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriter+Immediate.m
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXWriter+Immediate.h"
+
+#import "GRXImmediateWriter.h"
+
+@implementation GRXWriter (Immediate)
+
++ (instancetype)writerWithEnumerator:(NSEnumerator *)enumerator {
+  return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithEnumerator:enumerator]];
+}
+
++ (instancetype)writerWithValueSupplier:(id (^)())block {
+  return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithValueSupplier:block]];
+}
+
++ (instancetype)writerWithContainer:(id<NSFastEnumeration>)container {
+  return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithContainer:container]];
+}
+
++ (instancetype)writerWithValue:(id)value {
+  return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithValue:value]];
+}
+
++ (instancetype)writerWithError:(NSError *)error {
+  return [[self alloc] initWithWriter:[GRXImmediateWriter writerWithError:error]];
+}
+
++ (instancetype)emptyWriter {
+  return [[self alloc] initWithWriter:[GRXImmediateWriter emptyWriter]];
+}
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriter+Transformations.h b/src/objective-c/RxLibrary/GRXWriter+Transformations.h
new file mode 100644
index 0000000000000000000000000000000000000000..cfd644b52081e59dd4abb5774ea5ab6ae3e0e624
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriter+Transformations.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXWriter.h"
+
+@interface GRXWriter (Transformations)
+
+// Returns a writer that wraps the receiver, and has all the values the receiver would write
+// transformed by the provided mapping function.
+- (GRXWriter *)map:(id (^)(id value))map;
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriter+Transformations.m b/src/objective-c/RxLibrary/GRXWriter+Transformations.m
new file mode 100644
index 0000000000000000000000000000000000000000..67c54a7e80995b9d066e3412e6ae9808515b5f5b
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriter+Transformations.m
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXWriter+Transformations.h"
+
+#import "transformations/GRXMappingWriter.h"
+
+@implementation GRXWriter (Transformations)
+
+- (GRXWriter *)map:(id (^)(id))map {
+  if (!map) {
+    return self;
+  }
+  return [[GRXMappingWriter alloc] initWithWriter:self map:map];
+}
+
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..8bda52fcb98c270cb94aa911c1b88ec911b06148
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriter.h
@@ -0,0 +1,127 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "GRXWriteable.h"
+
+typedef NS_ENUM(NSInteger, GRXWriterState) {
+
+  // The writer has not yet been given a writeable to which it can push its
+  // values. To have an writer transition to the Started state, send it a
+  // startWithWriteable: message.
+  //
+  // An writer's state cannot be manually set to this value.
+  GRXWriterStateNotStarted,
+
+  // The writer might push values to the writeable at any moment.
+  GRXWriterStateStarted,
+
+  // The writer is temporarily paused, and won't send any more values to the
+  // writeable unless its state is set back to Started. The writer might still
+  // transition to the Finished state at any moment, and is allowed to send
+  // didFinishWithError: to its writeable.
+  //
+  // Not all implementations of writer have to support pausing, and thus
+  // trying to set an writer's state to this value might have no effect.
+  GRXWriterStatePaused,
+
+  // The writer has released its writeable and won't interact with it anymore.
+  //
+  // One seldomly wants to set an writer's state to this value, as its
+  // writeable isn't notified with a didFinishWithError: message. Instead, sending
+  // finishWithError: to the writer will make it notify the writeable and then
+  // transition to this state.
+  GRXWriterStateFinished
+};
+
+// An object that conforms to this protocol can produce, on demand, a sequence
+// of values. The sequence may be produced asynchronously, and it may consist of
+// any number of elements, including none or an infinite number.
+//
+// GRXWriter is the active dual of NSEnumerator. The difference between them
+// is thus whether the object plays an active or passive role during usage: A
+// user of NSEnumerator pulls values off it, and passes the values to a writeable.
+// A user of GRXWriter, though, just gives it a writeable, and the
+// GRXWriter instance pushes values to the writeable. This makes this protocol
+// suitable to represent a sequence of future values, as well as collections
+// with internal iteration.
+//
+// An instance of GRXWriter can start producing values after a writeable is
+// passed to it. It can also be commanded to finish the sequence immediately
+// (with an optional error). Finally, it can be asked to pause, but the
+// conforming instance is not required to oblige.
+//
+// Unless otherwise indicated by a conforming class, no messages should be sent
+// concurrently to a GRXWriter. I.e., conforming classes aren't required to
+// be thread-safe.
+@protocol GRXWriter <NSObject>
+
+// This property can be used to query the current state of the writer, which
+// determines how it might currently use its writeable. Some state transitions can
+// be triggered by setting this property to the corresponding value, and that's
+// useful for advanced use cases like pausing an writer. For more details,
+// see the documentation of the enum.
+@property(nonatomic) GRXWriterState state;
+
+// Start sending messages to the writeable. Messages may be sent before the method
+// returns, or they may be sent later in the future. See GRXWriteable.h for the
+// different messages a writeable can receive.
+//
+// If this writer draws its values from an external source (e.g. from the
+// filesystem or from a server), calling this method will commonly trigger side
+// effects (like network connections).
+//
+// This method might only be called on writers in the NotStarted state.
+- (void)startWithWriteable:(id<GRXWriteable>)writeable;
+
+// Send didFinishWithError:errorOrNil immediately to the writeable, and don't send
+// any more messages to it.
+//
+// This method might only be called on writers in the Started or Paused
+// state.
+//
+// TODO(jcanizales): Consider adding some guarantee about the immediacy of that
+// stopping. I know I've relied on it in part of the code that uses this, but
+// can't remember the details in the presence of concurrency.
+- (void)finishWithError:(NSError *)errorOrNil;
+@end
+
+// A "proxy" class that simply forwards values, completion, and errors from its
+// input writer to its writeable.
+// It is useful as a superclass for pipes that act as a transformation of their
+// input writer, and for classes that represent objects with input and
+// output sequences of values, like an RPC.
+@interface GRXWriter : NSObject<GRXWriter>
+- (instancetype)initWithWriter:(id<GRXWriter>)writer NS_DESIGNATED_INITIALIZER;
+@end
diff --git a/src/objective-c/RxLibrary/GRXWriter.m b/src/objective-c/RxLibrary/GRXWriter.m
new file mode 100644
index 0000000000000000000000000000000000000000..7d6c2acd369c2f339df671aad7118da400162ff6
--- /dev/null
+++ b/src/objective-c/RxLibrary/GRXWriter.m
@@ -0,0 +1,112 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXWriter.h"
+
+@interface GRXWriter () <GRXWriteable>
+@end
+
+@implementation GRXWriter {
+  id<GRXWriter> _writer;
+  id<GRXWriteable> _writeable;
+}
+
+- (instancetype)init {
+  return [self initWithWriter:nil];
+}
+
+// Designated initializer
+- (instancetype)initWithWriter:(id<GRXWriter>)writer {
+  if (!writer) {
+    [NSException raise:NSInvalidArgumentException format:@"writer can't be nil."];
+  }
+  if ((self = [super init])) {
+    _writer = writer;
+  }
+  return self;
+}
+
+// This is used to send a completion or an error to the writeable. It nillifies
+// our reference to it in order to guarantee no more messages are sent to it,
+// and to release it.
+- (void)finishOutputWithError:(NSError *)errorOrNil {
+  id<GRXWriteable> writeable = _writeable;
+  _writeable = nil;
+  [writeable didFinishWithError:errorOrNil];
+}
+
+// This is used to stop the input writer. It nillifies our reference to it
+// to release it.
+- (void)finishInput {
+  id<GRXWriter> writer = _writer;
+  _writer = nil;
+  writer.state = GRXWriterStateFinished;
+}
+
+#pragma mark GRXWriteable implementation
+
+- (void)didReceiveValue:(id)value {
+  [_writeable didReceiveValue:value];
+}
+
+- (void)didFinishWithError:(NSError *)errorOrNil {
+  _writer = nil;
+  [self finishOutputWithError:errorOrNil];
+}
+
+#pragma mark GRXWriter implementation
+
+- (GRXWriterState)state {
+  return _writer ? _writer.state : GRXWriterStateFinished;
+}
+
+- (void)setState:(GRXWriterState)state {
+  if (state == GRXWriterStateFinished) {
+    _writeable = nil;
+    [self finishInput];
+  } else {
+    _writer.state = state;
+  }
+}
+
+- (void)startWithWriteable:(id<GRXWriteable>)writeable {
+  _writeable = writeable;
+  [_writer startWithWriteable:self];
+}
+
+- (void)finishWithError:(NSError *)errorOrNil {
+  [self finishOutputWithError:errorOrNil];
+  [self finishInput];
+}
+
+@end
diff --git a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3f8bbe9c2e6bf5cb22fe45fbe095591a8262042
--- /dev/null
+++ b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface NSEnumerator (GRXUtil)
+
+// Returns a NSEnumerator instance that iterates through the elements of the passed container that
+// supports fast enumeration. Note that this negates the speed benefits of fast enumeration over
+// NSEnumerator. It's only intended for the rare cases when one needs the latter and only has the
+// former, e.g. for iteration that needs to be paused and resumed later.
++ (NSEnumerator *)grx_enumeratorWithContainer:(id<NSFastEnumeration>)container;
+
+// Returns a NSEnumerator instance that provides a single object before finishing. The value is then
+// released.
++ (NSEnumerator *)grx_enumeratorWithSingleValue:(id)value;
+
+// Returns a NSEnumerator instance that delegates the invocations of nextObject to the passed block.
+// When the block first returns nil, it is released.
++ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block;
+@end
diff --git a/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m
new file mode 100644
index 0000000000000000000000000000000000000000..807a1cd7009a7d44b4316c057c3ba9e63f27a285
--- /dev/null
+++ b/src/objective-c/RxLibrary/NSEnumerator+GRXUtil.m
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "NSEnumerator+GRXUtil.h"
+
+#import "private/GRXNSBlockEnumerator.h"
+#import "private/GRXNSFastEnumerator.h"
+#import "private/GRXNSScalarEnumerator.h"
+
+@implementation NSEnumerator (GRXUtil)
+
++ (NSEnumerator *)grx_enumeratorWithContainer:(id<NSFastEnumeration>)container {
+  // TODO(jcanizales): Consider checking if container responds to objectEnumerator and return that?
+  return [[GRXNSFastEnumerator alloc] initWithContainer:container];
+}
+
++ (NSEnumerator *)grx_enumeratorWithSingleValue:(id)value {
+  return [[GRXNSScalarEnumerator alloc] initWithValue:value];
+}
+
++ (NSEnumerator *)grx_enumeratorWithValueSupplier:(id (^)())block {
+  return [[GRXNSBlockEnumerator alloc] initWithValueSupplier:block];
+}
+@end
diff --git a/src/objective-c/RxLibrary/README.md b/src/objective-c/RxLibrary/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..88e90723b9bca89ca9716a7b349a0b440d87441b
--- /dev/null
+++ b/src/objective-c/RxLibrary/README.md
@@ -0,0 +1,8 @@
+This is a generic Reactive Extensions library for Objective-C, created to ease
+the implementation of the gRPC Objective-C runtime.
+
+It has no dependencies on gRPC nor other libraries, and should eventually be
+moved under its own GitHub project.
+
+If you're trying to get started on the library, you might want to first read
+GRXWriter.h and then GRXWriteable.h.
diff --git a/src/objective-c/RxLibrary/RxLibrary.podspec b/src/objective-c/RxLibrary/RxLibrary.podspec
new file mode 100644
index 0000000000000000000000000000000000000000..605aedaf108179a0007cc4eac8110e3be98b5609
--- /dev/null
+++ b/src/objective-c/RxLibrary/RxLibrary.podspec
@@ -0,0 +1,13 @@
+Pod::Spec.new do |s|
+  s.name         = 'RxLibrary'
+  s.version      = '0.0.1'
+  s.summary      = 'Reactive Extensions library for iOS'
+  s.author = {
+    'Jorge Canizales' => 'jcanizales@google.com'
+  }
+  s.source_files = '*.{h,m}', 'transformations/*.{h,m}', 'private/*.{h,m}'
+  s.private_header_files = 'private/*.h'
+  s.platform = :ios
+  s.ios.deployment_target = '6.0'
+  s.requires_arc = true
+end
diff --git a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..4253324e95cce75ab67c2ddd5b39755476d4b1b0
--- /dev/null
+++ b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+// Concrete subclass of NSEnumerator that delegates the invocations of nextObject to a block passed
+// on initialization.
+@interface GRXNSBlockEnumerator : NSEnumerator
+// The first time the passed block returns nil, the enumeration will end and the block will be
+// released.
+- (instancetype)initWithValueSupplier:(id (^)())block;
+@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m
new file mode 100644
index 0000000000000000000000000000000000000000..53b8bb863d619ae8abf64fecb2c62684736afcff
--- /dev/null
+++ b/src/objective-c/RxLibrary/private/GRXNSBlockEnumerator.m
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXNSBlockEnumerator.h"
+
+@implementation GRXNSBlockEnumerator {
+  id (^_block)();
+}
+
+- (instancetype)init {
+  return [self initWithValueSupplier:nil];
+}
+
+- (instancetype)initWithValueSupplier:(id (^)())block {
+  if ((self = [super init])) {
+    _block = block;
+  }
+  return self;
+}
+
+- (id)nextObject {
+  if (!_block) {
+    return nil;
+  }
+  id value = _block();
+  if (!value) {
+    _block = nil;
+  }
+  return value;
+}
+@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c28b158d73d946e55ad039d22af2cb066435ee0
--- /dev/null
+++ b/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+// This is a bridge to interact through NSEnumerator's interface with objects that only conform to
+// NSFastEnumeration. (There's nothing specifically fast about it - you certainly don't win any
+// speed by using this instead of a NSEnumerator provided by your container).
+@interface GRXNSFastEnumerator : NSEnumerator
+// After the iteration of the container (via the NSFastEnumeration protocol) is over, the container
+// is released. If the container is modified during enumeration, an exception is thrown.
+- (instancetype)initWithContainer:(id<NSFastEnumeration>)container;
+@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.m b/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.m
new file mode 100644
index 0000000000000000000000000000000000000000..2bbefacd69a716dad36deada3ff55096388d4809
--- /dev/null
+++ b/src/objective-c/RxLibrary/private/GRXNSFastEnumerator.m
@@ -0,0 +1,88 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXNSFastEnumerator.h"
+
+@implementation GRXNSFastEnumerator {
+  id<NSFastEnumeration> _container;
+  NSFastEnumerationState _state;
+  // Number of elements of the container currently in the _state.itemsPtr array.
+  NSUInteger _count;
+  // The index of the next object to return from the _state.itemsPtr array.
+  NSUInteger _index;
+  // A "buffer of one element," for the containers that enumerate their elements one by one. Those
+  // will set _state.itemsPtr to point to this.
+  // The NSFastEnumeration protocol requires it to be __unsafe_unretained, but that's alright
+  // because the only use we'd make of its value is to return it immediately as the result of
+  // nextObject.
+  __unsafe_unretained id _bufferValue;
+  // Neither NSEnumerator nor NSFastEnumeration instances are required to work correctly when the
+  // underlying container is mutated during iteration. The expectation is that an exception is
+  // thrown when that happens. So we check for mutations.
+  unsigned long _mutationFlag;
+  BOOL _mutationFlagIsSet;
+}
+
+- (instancetype)init {
+  return [self initWithContainer:nil];
+}
+
+// Designated initializer.
+- (instancetype)initWithContainer:(id<NSFastEnumeration>)container {
+  NSAssert(container, @"container can't be nil");
+  if ((self = [super init])) {
+    _container = container;
+  }
+  return self;
+}
+
+- (id)nextObject {
+  if (_index == _count) {
+    _index = 0;
+    _count = [_container countByEnumeratingWithState:&_state objects:&_bufferValue count:1];
+    if (_count == 0) {
+      // Enumeration is over.
+      _container = nil;
+      return nil;
+    }
+    if (_mutationFlagIsSet) {
+      NSAssert(_mutationFlag == *(_state.mutationsPtr),
+               @"container was mutated while being enumerated");
+    } else {
+      _mutationFlag = *(_state.mutationsPtr);
+      _mutationFlagIsSet = YES;
+    }
+  }
+  return _state.itemsPtr[_index++];
+}
+@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h b/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f4026e3a5f95376518e3643497224e6b3e1135a
--- /dev/null
+++ b/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+// Concrete subclass of NSEnumerator whose instances return a single object before finishing.
+@interface GRXNSScalarEnumerator : NSEnumerator
+// Param value: the single object this instance will produce. After the first invocation of
+// nextObject, the value is released.
+- (instancetype)initWithValue:(id)value;
+@end
diff --git a/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.m b/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.m
new file mode 100644
index 0000000000000000000000000000000000000000..18f6ddfc264fa11c0fc26c09de80d7fa39ec8171
--- /dev/null
+++ b/src/objective-c/RxLibrary/private/GRXNSScalarEnumerator.m
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXNSScalarEnumerator.h"
+
+@implementation GRXNSScalarEnumerator {
+  id _value;
+}
+
+- (instancetype)init {
+  return [self initWithValue:nil];
+}
+
+// Designated initializer.
+- (instancetype)initWithValue:(id)value {
+  if ((self = [super init])) {
+    _value = value;
+  }
+  return self;
+}
+
+- (id)nextObject {
+  id value = _value;
+  _value = nil;
+  return value;
+}
+@end
diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..72249b486bae5a840e8e312d7d73c77f51097d56
--- /dev/null
+++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRXWriter.h"
+
+// A "proxy" writer that transforms all the values of its input writer by using a mapping function.
+@interface GRXMappingWriter : GRXWriter
+- (instancetype)initWithWriter:(id<GRXWriter>)writer map:(id (^)(id value))map
+    NS_DESIGNATED_INITIALIZER;
+@end
diff --git a/src/cpp/server/server_context_impl.h b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
similarity index 70%
rename from src/cpp/server/server_context_impl.h
rename to src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
index c6016b763575027273a72a3f404a1aefb1ffaec2..8375aefdcd4b813991540374dec6dcc234dbd67b 100644
--- a/src/cpp/server/server_context_impl.h
+++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m
@@ -31,31 +31,33 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_SERVER_SERVER_CONTEXT_IMPL_H_
-#define __GRPCPP_INTERNAL_SERVER_SERVER_CONTEXT_IMPL_H_
+#import "GRXMappingWriter.h"
 
-#include <grpc++/server_context.h>
-
-#include <chrono>
+static id (^kIdentity)(id value) = ^id(id value) {
+  return value;
+};
 
-#include <grpc/support/time.h>
+@interface GRXWriter () <GRXWriteable>
+@end
 
-namespace grpc {
+@implementation GRXMappingWriter {
+  id (^_map)(id value);
+}
 
-class ServerContextImpl : public ServerContext {
- public:
-  explicit ServerContextImpl(std::chrono::system_clock::time_point deadline)
-      : absolute_deadline_(deadline) {}
-  ~ServerContextImpl() {}
+- (instancetype)initWithWriter:(id<GRXWriter>)writer {
+  return [self initWithWriter:writer map:nil];
+}
 
-  std::chrono::system_clock::time_point absolute_deadline() const {
-    return absolute_deadline_;
+// Designated initializer
+- (instancetype)initWithWriter:(id<GRXWriter>)writer map:(id (^)(id value))map {
+  if ((self = [super initWithWriter:writer])) {
+    _map = map ?: kIdentity;
   }
-
- private:
-  std::chrono::system_clock::time_point absolute_deadline_;
-};
-
-}  // namespace grpc
-
-#endif  // __GRPCPP_INTERNAL_SERVER_SERVER_CONTEXT_IMPL_H_
+  return self;
+}
+
+// Override
+- (void)didReceiveValue:(id)value {
+  [super didReceiveValue:_map(value)];
+}
+@end
diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile
new file mode 100644
index 0000000000000000000000000000000000000000..fa9898791021de0bc07858561736d1ffa040a924
--- /dev/null
+++ b/src/objective-c/examples/Sample/Podfile
@@ -0,0 +1,12 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+pod 'RxLibrary', :path => "../../RxLibrary"
+
+target 'Sample' do
+
+end
+
+target 'SampleTests' do
+
+end
diff --git a/src/objective-c/examples/Sample/Podfile.lock b/src/objective-c/examples/Sample/Podfile.lock
new file mode 100644
index 0000000000000000000000000000000000000000..fee4b43bec3cbd23e1f43e4b107ecf0d3f0657f0
--- /dev/null
+++ b/src/objective-c/examples/Sample/Podfile.lock
@@ -0,0 +1,14 @@
+PODS:
+  - RxLibrary (0.0.1)
+
+DEPENDENCIES:
+  - RxLibrary (from `../../RxLibrary`)
+
+EXTERNAL SOURCES:
+  RxLibrary:
+    :path: ../../RxLibrary
+
+SPEC CHECKSUMS:
+  RxLibrary: 70cfcf1573ec16a375b4fe61d976a3188aab9303
+
+COCOAPODS: 0.35.0
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXImmediateWriter.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXImmediateWriter.h
new file mode 120000
index 0000000000000000000000000000000000000000..915b0e4f90afa9092a847ceaa1f1868ca4614105
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXImmediateWriter.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/GRXImmediateWriter.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXMappingWriter.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXMappingWriter.h
new file mode 120000
index 0000000000000000000000000000000000000000..4d1073f4511d5dbdd962ad4bd3cb8970839f26e1
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXMappingWriter.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/transformations/GRXMappingWriter.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriteable.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriteable.h
new file mode 120000
index 0000000000000000000000000000000000000000..cb275199fce593118f4e1fcdcbde0d772b2d5a6c
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriteable.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/GRXWriteable.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter+Immediate.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter+Immediate.h
new file mode 120000
index 0000000000000000000000000000000000000000..fe5e740afbc8ac5796406e324181828a27e55426
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter+Immediate.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/GRXWriter+Immediate.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter+Transformations.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter+Transformations.h
new file mode 120000
index 0000000000000000000000000000000000000000..c57168c9efdb3ff26b343ea9275418ae9a87d00d
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter+Transformations.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/GRXWriter+Transformations.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter.h
new file mode 120000
index 0000000000000000000000000000000000000000..c4f657e5678b0ff7b73f8c176a56db623693b1c8
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/GRXWriter.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/GRXWriter.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/NSEnumerator+GRXUtil.h b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/NSEnumerator+GRXUtil.h
new file mode 120000
index 0000000000000000000000000000000000000000..97c6aaeeeccbca6fe69090113ed420b00e452e74
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Headers/Public/RxLibrary/NSEnumerator+GRXUtil.h
@@ -0,0 +1 @@
+../../../../../../RxLibrary/NSEnumerator+GRXUtil.h
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Local Podspecs/RxLibrary.podspec b/src/objective-c/examples/Sample/Pods/Local Podspecs/RxLibrary.podspec
new file mode 100644
index 0000000000000000000000000000000000000000..605aedaf108179a0007cc4eac8110e3be98b5609
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Local Podspecs/RxLibrary.podspec	
@@ -0,0 +1,13 @@
+Pod::Spec.new do |s|
+  s.name         = 'RxLibrary'
+  s.version      = '0.0.1'
+  s.summary      = 'Reactive Extensions library for iOS'
+  s.author = {
+    'Jorge Canizales' => 'jcanizales@google.com'
+  }
+  s.source_files = '*.{h,m}', 'transformations/*.{h,m}', 'private/*.{h,m}'
+  s.private_header_files = 'private/*.h'
+  s.platform = :ios
+  s.ios.deployment_target = '6.0'
+  s.requires_arc = true
+end
diff --git a/src/objective-c/examples/Sample/Pods/Manifest.lock b/src/objective-c/examples/Sample/Pods/Manifest.lock
new file mode 100644
index 0000000000000000000000000000000000000000..fee4b43bec3cbd23e1f43e4b107ecf0d3f0657f0
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Manifest.lock
@@ -0,0 +1,14 @@
+PODS:
+  - RxLibrary (0.0.1)
+
+DEPENDENCIES:
+  - RxLibrary (from `../../RxLibrary`)
+
+EXTERNAL SOURCES:
+  RxLibrary:
+    :path: ../../RxLibrary
+
+SPEC CHECKSUMS:
+  RxLibrary: 70cfcf1573ec16a375b4fe61d976a3188aab9303
+
+COCOAPODS: 0.35.0
diff --git a/src/objective-c/examples/Sample/Pods/Pods.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Pods/Pods.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000000000000000000000000000000000..68290dd5e8fc31be612638d07adf795f79962b94
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Pods.xcodeproj/project.pbxproj
@@ -0,0 +1,2888 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>archiveVersion</key>
+	<string>1</string>
+	<key>classes</key>
+	<dict/>
+	<key>objectVersion</key>
+	<string>46</string>
+	<key>objects</key>
+	<dict>
+		<key>00949E44051CD97851DEFF3B</key>
+		<dict>
+			<key>fileRef</key>
+			<string>9CFAC09E370EA1C96C8D2880</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>01F5B724A99ADB3547023C72</key>
+		<dict>
+			<key>fileRef</key>
+			<string>1868370C0050315A6B835D42</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>0239F1B46D24E21A8042F47F</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>8919AE774852DD128A7CB510</string>
+			<key>buildPhases</key>
+			<array>
+				<string>A71CC1B520D2DFF451839FE2</string>
+				<string>896F697BD1BEAF8A081337EB</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array>
+				<string>6EB14BC96525C955FBD5CC75</string>
+			</array>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Pods-Sample</string>
+			<key>productName</key>
+			<string>Pods-Sample</string>
+			<key>productReference</key>
+			<string>DF94410F5DC0A0AB69336DF4</string>
+			<key>productType</key>
+			<string>com.apple.product-type.library.static</string>
+		</dict>
+		<key>024F840533A6674922DB7899</key>
+		<dict>
+			<key>fileRef</key>
+			<string>46513F4AD14CBD2377C1E7A1</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>0260773D27B4AE159FB0B22D</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>GRXWriter+Immediate.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>026236C3432E9DBC10A40748</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>Pods-SampleTests-dummy.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>0385BCBCA0601E80FAD2A901</key>
+		<dict>
+			<key>fileRef</key>
+			<string>46513F4AD14CBD2377C1E7A1</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>0879DBE6FFA1852D106330B4</key>
+		<dict>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>CLANG_CXX_LANGUAGE_STANDARD</key>
+				<string>gnu++0x</string>
+				<key>CLANG_CXX_LIBRARY</key>
+				<string>libc++</string>
+				<key>CLANG_ENABLE_MODULES</key>
+				<string>YES</string>
+				<key>CLANG_ENABLE_OBJC_ARC</key>
+				<string>YES</string>
+				<key>CLANG_WARN_BOOL_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_CONSTANT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_DIRECT_OBJC_ISA_USAGE</key>
+				<string>YES</string>
+				<key>CLANG_WARN_EMPTY_BODY</key>
+				<string>YES</string>
+				<key>CLANG_WARN_ENUM_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_INT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_OBJC_ROOT_CLASS</key>
+				<string>YES</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>GCC_C_LANGUAGE_STANDARD</key>
+				<string>gnu99</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
+				<string>YES</string>
+				<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNDECLARED_SELECTOR</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNINITIALIZED_AUTOS</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNUSED_FUNCTION</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNUSED_VARIABLE</key>
+				<string>YES</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>ONLY_ACTIVE_ARCH</key>
+				<string>YES</string>
+				<key>STRIP_INSTALLED_PRODUCT</key>
+				<string>NO</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>092D0456252ED3F90F66084D</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>Pods-Sample-environment.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>0BC8818D3A097831FDE0750B</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BC50D76123DA4B85E6AD77B4</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>0C57EED724EBF58759F9F6DF</key>
+		<dict>
+			<key>fileRef</key>
+			<string>4BB75B0FC7359E8EA8672954</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>0D09CEB9308FA5BACEB5F84C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>30063D2979A72CA1050BD4A6</string>
+				<string>DB3528F609E6177E1C5A691C</string>
+				<string>026236C3432E9DBC10A40748</string>
+				<string>EF8B807C5A2059D6C709450D</string>
+				<string>8B503889F903CED9A12E5C87</string>
+				<string>591702CE7D8AF91674F1640F</string>
+				<string>DB677464758307786D68CCE9</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Pods-SampleTests</string>
+			<key>path</key>
+			<string>Target Support Files/Pods-SampleTests</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>0D53085043D992DC00E29F0A</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>GRXWriteable.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>0F20828B67FDCB990B1818E9</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>DB677464758307786D68CCE9</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_CFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_CPLUSPLUSFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>11072993378724E9AF9CAF85</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods-SampleTests-RxLibrary.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>1146D04C598DEBA045C96C2F</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>1F3162E71EE5AA2B65DEC06D</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>114F64D42E2AF2F3EBDE9BCB</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>1D31B6F63B148D2EA5637823</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>124B93EFC16A2026269840B2</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXTargetDependency</string>
+			<key>name</key>
+			<string>Pods-RxLibrary</string>
+			<key>target</key>
+			<string>6BFD156F312F6CAA1E5B00CA</string>
+			<key>targetProxy</key>
+			<string>DB007D27F74F8F72C72A1079</string>
+		</dict>
+		<key>14D92BB2ED12213381BD2EB9</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>C4342DDEEF3C3290956C21DF</string>
+			<key>buildPhases</key>
+			<array>
+				<string>432AE81157886BE484236751</string>
+				<string>87700F015FA41F53D88CA4BC</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array>
+				<string>F8B4778EF3030EEC2E9927CE</string>
+			</array>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Pods-SampleTests</string>
+			<key>productName</key>
+			<string>Pods-SampleTests</string>
+			<key>productReference</key>
+			<string>42A375125393D0613249D046</string>
+			<key>productType</key>
+			<string>com.apple.product-type.library.static</string>
+		</dict>
+		<key>15DC9A153BC412DB41B7F154</key>
+		<dict>
+			<key>fileRef</key>
+			<string>5AEFA85A5F1AD206D68B0576</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>15F64D3D7D10DB47599A72EB</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>name</key>
+			<string>GRXMappingWriter.m</string>
+			<key>path</key>
+			<string>transformations/GRXMappingWriter.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>16E6BBD46D9745611EF313FB</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BECFE3DCB323841851972996</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>17F4C2F25813E7A4588FF233</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>B153046F0CBA526564A9673C</string>
+				<string>B960FF1BE77D3F4459EEB1E0</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>1868370C0050315A6B835D42</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>name</key>
+			<string>GRXNSScalarEnumerator.h</string>
+			<key>path</key>
+			<string>private/GRXNSScalarEnumerator.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>19001096C873023095C4F032</key>
+		<dict>
+			<key>fileRef</key>
+			<string>EB29FAB1F81F0D17BDAD72D0</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>1B8264EEFEF4AD585182D256</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods-Sample.debug.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>1C8DFDF9C457D910DC1FD227</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>Pods-environment.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>1D31B6F63B148D2EA5637823</key>
+		<dict>
+			<key>fileRef</key>
+			<string>22DB20D833E7D26AEA6513D6</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>1E5420835E4862DBA55002A9</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BECFE3DCB323841851972996</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>1F3162E71EE5AA2B65DEC06D</key>
+		<dict>
+			<key>fileRef</key>
+			<string>56CE61A20C6F88CC0CE888C8</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>22531AF83592134D3879C3E1</key>
+		<dict>
+			<key>fileRef</key>
+			<string>15F64D3D7D10DB47599A72EB</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>22DB20D833E7D26AEA6513D6</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>Pods-dummy.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>245F9E9690E6E08D291FC94C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BC52B0661F25B25CE382296C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>266008D38F1E72755C711699</key>
+		<dict>
+			<key>fileRef</key>
+			<string>026236C3432E9DBC10A40748</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2663F4401A9075DAC0B24171</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>Pods-RxLibrary-dummy.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>26E6ACBF137DBC325B4E7DA7</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>B05A2B15C8A03AABA163D7D7</string>
+			<key>buildPhases</key>
+			<array>
+				<string>114F64D42E2AF2F3EBDE9BCB</string>
+				<string>DCAB71BD665AF17533987B69</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array>
+				<string>124B93EFC16A2026269840B2</string>
+			</array>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Pods</string>
+			<key>productName</key>
+			<string>Pods</string>
+			<key>productReference</key>
+			<string>5C30ABB95D604B483422D72A</string>
+			<key>productType</key>
+			<string>com.apple.product-type.library.static</string>
+		</dict>
+		<key>27E123435067CC11FE103999</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods-Sample.release.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>288A25371032891C824CF4AA</key>
+		<dict>
+			<key>fileRef</key>
+			<string>838341407CEBBFB19D25C45A</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>29B274FDF882AB8B39814FE6</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>687D79F4C2484F58E9796051</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREFIX_HEADER</key>
+				<string>Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-prefix.pch</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>2AADA4C52A284ED5D41C7CF5</key>
+		<dict>
+			<key>fileRef</key>
+			<string>0D53085043D992DC00E29F0A</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2B05A4C21D00E8CF0DE88447</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>name</key>
+			<string>Pods-SampleTests-RxLibrary-prefix.pch</string>
+			<key>path</key>
+			<string>../Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-prefix.pch</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>2B341576464148A01DCFB28B</key>
+		<dict>
+			<key>fileRef</key>
+			<string>3AD75C69A61408EF8BE0F247</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2B49DCA723ECBC0F2777B960</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BC52B0661F25B25CE382296C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2D6833D4D544AC13450405B1</key>
+		<dict>
+			<key>fileRef</key>
+			<string>2663F4401A9075DAC0B24171</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2D7732FBE1A5A7FC42D4DC4B</key>
+		<dict>
+			<key>fileRef</key>
+			<string>56CE61A20C6F88CC0CE888C8</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2DA405F6E578008991B3F9EA</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BECFE3DCB323841851972996</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2F91A2AD622F87D98C9B0E1E</key>
+		<dict>
+			<key>fileRef</key>
+			<string>0D53085043D992DC00E29F0A</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>2FE1D288B8389F925AA3CE0C</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods-RxLibrary-Private.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>30063D2979A72CA1050BD4A6</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text</string>
+			<key>path</key>
+			<string>Pods-SampleTests-acknowledgements.markdown</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>3133D1CCCF4F1FE3E893509C</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods-RxLibrary.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>352B4C7135E3BBBFEBAB7F55</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BA9F62DDE37FF0D601A4D5EA</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>355670384FC160AB6C32765E</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>56CE61A20C6F88CC0CE888C8</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>iOS</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>36C139FD3DEDB8CA2A1D3295</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text</string>
+			<key>path</key>
+			<string>Pods-acknowledgements.markdown</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>36FF37EAC7E918C4CD867776</key>
+		<dict>
+			<key>fileRef</key>
+			<string>EB29FAB1F81F0D17BDAD72D0</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>3749A34D3DFA6E2F3539E546</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>0879DBE6FFA1852D106330B4</string>
+				<string>6B88B9AB87714A903970EAED</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>3800855A656C8D0813062074</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>9508723D4C0D4321A5188108</string>
+			<key>buildPhases</key>
+			<array>
+				<string>F779618174957BE31FCCDE56</string>
+				<string>45FC41033EB61B16BC8151B9</string>
+				<string>8AB7020D9B71B1B4F34249BE</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Pods-SampleTests-RxLibrary</string>
+			<key>productName</key>
+			<string>Pods-SampleTests-RxLibrary</string>
+			<key>productReference</key>
+			<string>11072993378724E9AF9CAF85</string>
+			<key>productType</key>
+			<string>com.apple.product-type.library.static</string>
+		</dict>
+		<key>397A12919FB4BDD608FE207C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>B4FB10339A6A2E1AAF255802</string>
+				<string>5840BDD08ED67C12ADB1DF08</string>
+				<string>817F8B2E38A51910E8F8EC7D</string>
+				<string>8B05D39455D5B23720961FA4</string>
+				<string>F2BB78774BCEFD5DDDF38239</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>3A4DE73D0D0274E782C1A564</key>
+		<dict>
+			<key>fileRef</key>
+			<string>56CE61A20C6F88CC0CE888C8</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>3AD75C69A61408EF8BE0F247</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>GRXWriteable.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>3C3F1A188E25219C230FFD4F</key>
+		<dict>
+			<key>fileRef</key>
+			<string>9DADE0CF857B717294F7F74F</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>404D4F98249F3383235463A4</key>
+		<dict>
+			<key>fileRef</key>
+			<string>56CE61A20C6F88CC0CE888C8</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>407E794549893DD91A2ED84E</key>
+		<dict>
+			<key>fileRef</key>
+			<string>DB0257E62EC33F3F316EF017</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>42A375125393D0613249D046</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods-SampleTests.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>42B461F095E85911637DFD60</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>name</key>
+			<string>Pods-SampleTests-RxLibrary-dummy.m</string>
+			<key>path</key>
+			<string>../Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-dummy.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>432AE81157886BE484236751</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>266008D38F1E72755C711699</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>43CC797FB2A733DF5B7A9F05</key>
+		<dict>
+			<key>fileRef</key>
+			<string>15F64D3D7D10DB47599A72EB</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>458FF1EEF4EB9646C699F3DD</key>
+		<dict>
+			<key>fileRef</key>
+			<string>57AC9BF19B9635D7476CA5FA</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>45A1913C8F48686C1FC82520</key>
+		<dict>
+			<key>fileRef</key>
+			<string>9DADE0CF857B717294F7F74F</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>45FC41033EB61B16BC8151B9</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>2D7732FBE1A5A7FC42D4DC4B</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>46513F4AD14CBD2377C1E7A1</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>name</key>
+			<string>GRXNSFastEnumerator.h</string>
+			<key>path</key>
+			<string>private/GRXNSFastEnumerator.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>46A8EFCC59CF17E048EC34ED</key>
+		<dict>
+			<key>fileRef</key>
+			<string>5AEFA85A5F1AD206D68B0576</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>46FAFA88CA3E774263422EB9</key>
+		<dict>
+			<key>fileRef</key>
+			<string>3AD75C69A61408EF8BE0F247</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>4946B2D315E9BF5CBACD7D52</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.plist.xml</string>
+			<key>path</key>
+			<string>Pods-acknowledgements.plist</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>4954E8CE730737CD2991E502</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>BECFE3DCB323841851972996</string>
+				<string>BC52B0661F25B25CE382296C</string>
+				<string>9CFAC09E370EA1C96C8D2880</string>
+				<string>15F64D3D7D10DB47599A72EB</string>
+				<string>5AEFA85A5F1AD206D68B0576</string>
+				<string>4BB75B0FC7359E8EA8672954</string>
+				<string>46513F4AD14CBD2377C1E7A1</string>
+				<string>636AC1003F2C71FFD74542CD</string>
+				<string>1868370C0050315A6B835D42</string>
+				<string>57AC9BF19B9635D7476CA5FA</string>
+				<string>0D53085043D992DC00E29F0A</string>
+				<string>3AD75C69A61408EF8BE0F247</string>
+				<string>DB0257E62EC33F3F316EF017</string>
+				<string>BDA58E5E1AE450540A2B0227</string>
+				<string>0260773D27B4AE159FB0B22D</string>
+				<string>EB29FAB1F81F0D17BDAD72D0</string>
+				<string>838341407CEBBFB19D25C45A</string>
+				<string>F763F3DF1B47888E75D0ED9C</string>
+				<string>9DADE0CF857B717294F7F74F</string>
+				<string>BA9F62DDE37FF0D601A4D5EA</string>
+				<string>D49849E96C0C5FFB93C810CD</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>RxLibrary</string>
+			<key>path</key>
+			<string>../../../RxLibrary</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>4972C151CE9A8A15BC1AE2C8</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>name</key>
+			<string>Pods-Sample-RxLibrary-prefix.pch</string>
+			<key>path</key>
+			<string>../Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-prefix.pch</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>4BB47C74830C63C90981278E</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>245F9E9690E6E08D291FC94C</string>
+				<string>A96854FB48432263FE68C313</string>
+				<string>AA52EF1CD8A3683472BD86FE</string>
+				<string>BB88043BB37FC0261BA90A30</string>
+				<string>54A02FC8DA14CEC49EA8C8D5</string>
+				<string>B7902691B66134F3764663D9</string>
+				<string>19001096C873023095C4F032</string>
+				<string>E86A17CE1D79ECDCEBF91109</string>
+				<string>8BB6B6B3653FC309CB8EB3A0</string>
+				<string>7BBF3F432525D33FCB074BD5</string>
+				<string>2D6833D4D544AC13450405B1</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>4BB75B0FC7359E8EA8672954</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>name</key>
+			<string>GRXNSBlockEnumerator.m</string>
+			<key>path</key>
+			<string>private/GRXNSBlockEnumerator.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>50FF607D5DA961C6BEF4ABAC</key>
+		<dict>
+			<key>fileRef</key>
+			<string>838341407CEBBFB19D25C45A</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>5280A583CA6C6C66698AE67C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>DB0257E62EC33F3F316EF017</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>54A02FC8DA14CEC49EA8C8D5</key>
+		<dict>
+			<key>fileRef</key>
+			<string>57AC9BF19B9635D7476CA5FA</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>56CE61A20C6F88CC0CE888C8</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>wrapper.framework</string>
+			<key>name</key>
+			<string>Foundation.framework</string>
+			<key>path</key>
+			<string>Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework</string>
+			<key>sourceTree</key>
+			<string>DEVELOPER_DIR</string>
+		</dict>
+		<key>57AC9BF19B9635D7476CA5FA</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>name</key>
+			<string>GRXNSScalarEnumerator.m</string>
+			<key>path</key>
+			<string>private/GRXNSScalarEnumerator.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>5840BDD08ED67C12ADB1DF08</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>4954E8CE730737CD2991E502</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Development Pods</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>591702CE7D8AF91674F1640F</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods-SampleTests.debug.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>594F98D43B96AB5C11E61C10</key>
+		<dict>
+			<key>fileRef</key>
+			<string>F763F3DF1B47888E75D0ED9C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>5AEFA85A5F1AD206D68B0576</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>name</key>
+			<string>GRXNSBlockEnumerator.h</string>
+			<key>path</key>
+			<string>private/GRXNSBlockEnumerator.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>5B8A3BFE016346EF080D52C6</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>3A4DE73D0D0274E782C1A564</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>5C30ABB95D604B483422D72A</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>5DE93D7B39D2D1AD7336C4AC</key>
+		<dict>
+			<key>fileRef</key>
+			<string>838341407CEBBFB19D25C45A</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>621587D6C7759FBE7096D185</key>
+		<dict>
+			<key>fileRef</key>
+			<string>46513F4AD14CBD2377C1E7A1</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>636AC1003F2C71FFD74542CD</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>name</key>
+			<string>GRXNSFastEnumerator.m</string>
+			<key>path</key>
+			<string>private/GRXNSFastEnumerator.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>687D79F4C2484F58E9796051</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>name</key>
+			<string>Pods-SampleTests-RxLibrary-Private.xcconfig</string>
+			<key>path</key>
+			<string>../Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-Private.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>69E8FF71552D08D72B9068F1</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>36C139FD3DEDB8CA2A1D3295</string>
+				<string>4946B2D315E9BF5CBACD7D52</string>
+				<string>22DB20D833E7D26AEA6513D6</string>
+				<string>1C8DFDF9C457D910DC1FD227</string>
+				<string>E14CB6F332A9E58BB5F76C07</string>
+				<string>6AC13D00A5A61BDA0DE5FAAF</string>
+				<string>A577CB571492B4F951064FCF</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Pods</string>
+			<key>path</key>
+			<string>Target Support Files/Pods</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6AC13D00A5A61BDA0DE5FAAF</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods.debug.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6B5B56ED61BE76782DF02817</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>687D79F4C2484F58E9796051</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREFIX_HEADER</key>
+				<string>Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-prefix.pch</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_CFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_CPLUSPLUSFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>6B88B9AB87714A903970EAED</key>
+		<dict>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>CLANG_CXX_LANGUAGE_STANDARD</key>
+				<string>gnu++0x</string>
+				<key>CLANG_CXX_LIBRARY</key>
+				<string>libc++</string>
+				<key>CLANG_ENABLE_MODULES</key>
+				<string>YES</string>
+				<key>CLANG_ENABLE_OBJC_ARC</key>
+				<string>YES</string>
+				<key>CLANG_WARN_BOOL_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_CONSTANT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_DIRECT_OBJC_ISA_USAGE</key>
+				<string>YES</string>
+				<key>CLANG_WARN_EMPTY_BODY</key>
+				<string>YES</string>
+				<key>CLANG_WARN_ENUM_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_INT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_OBJC_ROOT_CLASS</key>
+				<string>YES</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>ENABLE_NS_ASSERTIONS</key>
+				<string>NO</string>
+				<key>GCC_C_LANGUAGE_STANDARD</key>
+				<string>gnu99</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>RELEASE=1</string>
+				</array>
+				<key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
+				<string>YES</string>
+				<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNDECLARED_SELECTOR</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNINITIALIZED_AUTOS</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNUSED_FUNCTION</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNUSED_VARIABLE</key>
+				<string>YES</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>STRIP_INSTALLED_PRODUCT</key>
+				<string>NO</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>6BFD156F312F6CAA1E5B00CA</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>962FF5FAC21292530C615D05</string>
+			<key>buildPhases</key>
+			<array>
+				<string>4BB47C74830C63C90981278E</string>
+				<string>5B8A3BFE016346EF080D52C6</string>
+				<string>A4C1C82F355864E7D3E200DD</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Pods-RxLibrary</string>
+			<key>productName</key>
+			<string>Pods-RxLibrary</string>
+			<key>productReference</key>
+			<string>A579EC5BE7E68C55CA5FECDE</string>
+			<key>productType</key>
+			<string>com.apple.product-type.library.static</string>
+		</dict>
+		<key>6D1D41BAE4E325572FAC7B17</key>
+		<dict>
+			<key>fileRef</key>
+			<string>9DADE0CF857B717294F7F74F</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6E00FD6D197F0D1332D11199</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>1B8264EEFEF4AD585182D256</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>6E0669CB3E76E19FC854BA74</key>
+		<dict>
+			<key>fileRef</key>
+			<string>4BB75B0FC7359E8EA8672954</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6EB14BC96525C955FBD5CC75</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXTargetDependency</string>
+			<key>name</key>
+			<string>Pods-Sample-RxLibrary</string>
+			<key>target</key>
+			<string>F6C59E5B4CFE053E9F98000E</string>
+			<key>targetProxy</key>
+			<string>A0215878A7EC41E833B5F1D2</string>
+		</dict>
+		<key>74F28D2155D125C3068F96BE</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>6AC13D00A5A61BDA0DE5FAAF</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>7A8627E1649F66DEE014EB46</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>D53A8F2B11E6C2C187AFFF1D</string>
+				<string>B50ECED4CEC7554ED6077619</string>
+				<string>BC50D76123DA4B85E6AD77B4</string>
+				<string>092D0456252ED3F90F66084D</string>
+				<string>AA99564782B655791B053E58</string>
+				<string>1B8264EEFEF4AD585182D256</string>
+				<string>27E123435067CC11FE103999</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Pods-Sample</string>
+			<key>path</key>
+			<string>Target Support Files/Pods-Sample</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>7AC4B3F3D7BB132642153A38</key>
+		<dict>
+			<key>fileRef</key>
+			<string>0260773D27B4AE159FB0B22D</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>7BBF3F432525D33FCB074BD5</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BA9F62DDE37FF0D601A4D5EA</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>7DA2A517A18D85B390FB122A</key>
+		<dict>
+			<key>containerPortal</key>
+			<string>FBF79DDF04ADEAED54BA2286</string>
+			<key>isa</key>
+			<string>PBXContainerItemProxy</string>
+			<key>proxyType</key>
+			<string>1</string>
+			<key>remoteGlobalIDString</key>
+			<string>3800855A656C8D0813062074</string>
+			<key>remoteInfo</key>
+			<string>Pods-SampleTests-RxLibrary</string>
+		</dict>
+		<key>7E9B63EFA2466C4456A0695A</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>2FE1D288B8389F925AA3CE0C</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREFIX_HEADER</key>
+				<string>Target Support Files/Pods-RxLibrary/Pods-RxLibrary-prefix.pch</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_CFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_CPLUSPLUSFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>7FACBF2C8AF0403DD1C11015</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>name</key>
+			<string>Pods-Sample-RxLibrary-Private.xcconfig</string>
+			<key>path</key>
+			<string>../Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-Private.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>801BBA7A538CFAE6746966A7</key>
+		<dict>
+			<key>fileRef</key>
+			<string>42B461F095E85911637DFD60</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>817F8B2E38A51910E8F8EC7D</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>355670384FC160AB6C32765E</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Frameworks</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>838341407CEBBFB19D25C45A</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>GRXWriter+Transformations.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>85D5565EC08D14A6A60F1DDA</key>
+		<dict>
+			<key>fileRef</key>
+			<string>56CE61A20C6F88CC0CE888C8</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>86586E0B51D3DC6A97D0A7F3</key>
+		<dict>
+			<key>fileRef</key>
+			<string>56CE61A20C6F88CC0CE888C8</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>86D03B997B81819E2F39E48B</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BC52B0661F25B25CE382296C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>87700F015FA41F53D88CA4BC</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>404D4F98249F3383235463A4</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>8915073BE8158EF53FE11B95</key>
+		<dict>
+			<key>fileRef</key>
+			<string>EB29FAB1F81F0D17BDAD72D0</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>8919AE774852DD128A7CB510</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>6E00FD6D197F0D1332D11199</string>
+				<string>B602CFEF970BEA98E40A056C</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>896F697BD1BEAF8A081337EB</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>86586E0B51D3DC6A97D0A7F3</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>8A7375A2F98889F35C15E2D7</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>name</key>
+			<string>Pods-SampleTests-RxLibrary.xcconfig</string>
+			<key>path</key>
+			<string>../Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>8AB7020D9B71B1B4F34249BE</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>1E5420835E4862DBA55002A9</string>
+				<string>00949E44051CD97851DEFF3B</string>
+				<string>15DC9A153BC412DB41B7F154</string>
+				<string>0385BCBCA0601E80FAD2A901</string>
+				<string>01F5B724A99ADB3547023C72</string>
+				<string>F2C6AACFE46FFA8DC383DE43</string>
+				<string>7AC4B3F3D7BB132642153A38</string>
+				<string>5DE93D7B39D2D1AD7336C4AC</string>
+				<string>407E794549893DD91A2ED84E</string>
+				<string>3C3F1A188E25219C230FFD4F</string>
+			</array>
+			<key>isa</key>
+			<string>PBXHeadersBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>8B05D39455D5B23720961FA4</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>5C30ABB95D604B483422D72A</string>
+				<string>A579EC5BE7E68C55CA5FECDE</string>
+				<string>DF94410F5DC0A0AB69336DF4</string>
+				<string>EF2EE4BC906FF9909348DAB5</string>
+				<string>42A375125393D0613249D046</string>
+				<string>11072993378724E9AF9CAF85</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Products</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>8B503889F903CED9A12E5C87</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.script.sh</string>
+			<key>path</key>
+			<string>Pods-SampleTests-resources.sh</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>8BB6B6B3653FC309CB8EB3A0</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BDA58E5E1AE450540A2B0227</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>8CD061F02F905957F4C1D188</key>
+		<dict>
+			<key>fileRef</key>
+			<string>636AC1003F2C71FFD74542CD</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>911BEE248BE640294A081862</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>Pods-RxLibrary-prefix.pch</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>9508723D4C0D4321A5188108</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>29B274FDF882AB8B39814FE6</string>
+				<string>6B5B56ED61BE76782DF02817</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>962FF5FAC21292530C615D05</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>A150782D73BBE95DE629B03C</string>
+				<string>7E9B63EFA2466C4456A0695A</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>9BD773E928AD698D23B20123</key>
+		<dict>
+			<key>fileRef</key>
+			<string>1868370C0050315A6B835D42</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>9CCBE9A628C305B3B089B8DD</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BA9F62DDE37FF0D601A4D5EA</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>9CFAC09E370EA1C96C8D2880</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>name</key>
+			<string>GRXMappingWriter.h</string>
+			<key>path</key>
+			<string>transformations/GRXMappingWriter.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>9DADE0CF857B717294F7F74F</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>NSEnumerator+GRXUtil.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>9E8DC61269B141639DA7F859</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>16E6BBD46D9745611EF313FB</string>
+				<string>CC0A03D531EF0FF199671820</string>
+				<string>C382F416EFA39BE2CF216044</string>
+				<string>621587D6C7759FBE7096D185</string>
+				<string>C0AC333A6FE8F07600C96890</string>
+				<string>2F91A2AD622F87D98C9B0E1E</string>
+				<string>FDC6B84EAC9989F0827EA4F3</string>
+				<string>50FF607D5DA961C6BEF4ABAC</string>
+				<string>5280A583CA6C6C66698AE67C</string>
+				<string>6D1D41BAE4E325572FAC7B17</string>
+			</array>
+			<key>isa</key>
+			<string>PBXHeadersBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>A00077019C113466960E9DAF</key>
+		<dict>
+			<key>fileRef</key>
+			<string>9CFAC09E370EA1C96C8D2880</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>A0215878A7EC41E833B5F1D2</key>
+		<dict>
+			<key>containerPortal</key>
+			<string>FBF79DDF04ADEAED54BA2286</string>
+			<key>isa</key>
+			<string>PBXContainerItemProxy</string>
+			<key>proxyType</key>
+			<string>1</string>
+			<key>remoteGlobalIDString</key>
+			<string>F6C59E5B4CFE053E9F98000E</string>
+			<key>remoteInfo</key>
+			<string>Pods-Sample-RxLibrary</string>
+		</dict>
+		<key>A150782D73BBE95DE629B03C</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>2FE1D288B8389F925AA3CE0C</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREFIX_HEADER</key>
+				<string>Target Support Files/Pods-RxLibrary/Pods-RxLibrary-prefix.pch</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>A4C1C82F355864E7D3E200DD</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>2DA405F6E578008991B3F9EA</string>
+				<string>A00077019C113466960E9DAF</string>
+				<string>46A8EFCC59CF17E048EC34ED</string>
+				<string>024F840533A6674922DB7899</string>
+				<string>9BD773E928AD698D23B20123</string>
+				<string>2AADA4C52A284ED5D41C7CF5</string>
+				<string>CC358E38AE146C095C401760</string>
+				<string>288A25371032891C824CF4AA</string>
+				<string>FDC939796E70DC7D141E29FC</string>
+				<string>45A1913C8F48686C1FC82520</string>
+			</array>
+			<key>isa</key>
+			<string>PBXHeadersBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>A577CB571492B4F951064FCF</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods.release.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>A579EC5BE7E68C55CA5FECDE</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods-RxLibrary.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>A71CC1B520D2DFF451839FE2</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>0BC8818D3A097831FDE0750B</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>A8AFEFDF4700447BBCDF9E10</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>591702CE7D8AF91674F1640F</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>A96854FB48432263FE68C313</key>
+		<dict>
+			<key>fileRef</key>
+			<string>15F64D3D7D10DB47599A72EB</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>AA52EF1CD8A3683472BD86FE</key>
+		<dict>
+			<key>fileRef</key>
+			<string>4BB75B0FC7359E8EA8672954</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>AA99564782B655791B053E58</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.script.sh</string>
+			<key>path</key>
+			<string>Pods-Sample-resources.sh</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>AF9F0D991C2913F55496D06E</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>A577CB571492B4F951064FCF</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_CFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_CPLUSPLUSFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>B034EE43C1EF96D1CBD1328A</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>name</key>
+			<string>Pods-Sample-RxLibrary.xcconfig</string>
+			<key>path</key>
+			<string>../Pods-Sample-RxLibrary/Pods-Sample-RxLibrary.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>B05A2B15C8A03AABA163D7D7</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>74F28D2155D125C3068F96BE</string>
+				<string>AF9F0D991C2913F55496D06E</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>B153046F0CBA526564A9673C</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>7FACBF2C8AF0403DD1C11015</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREFIX_HEADER</key>
+				<string>Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-prefix.pch</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>B4FB10339A6A2E1AAF255802</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text</string>
+			<key>name</key>
+			<string>Podfile</string>
+			<key>path</key>
+			<string>../Podfile</string>
+			<key>sourceTree</key>
+			<string>SOURCE_ROOT</string>
+			<key>xcLanguageSpecificationIdentifier</key>
+			<string>xcode.lang.ruby</string>
+		</dict>
+		<key>B50ECED4CEC7554ED6077619</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.plist.xml</string>
+			<key>path</key>
+			<string>Pods-Sample-acknowledgements.plist</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>B602CFEF970BEA98E40A056C</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>27E123435067CC11FE103999</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_CFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_CPLUSPLUSFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>B78477CA74AEFC96C25B49B4</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BDA58E5E1AE450540A2B0227</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>B7902691B66134F3764663D9</key>
+		<dict>
+			<key>fileRef</key>
+			<string>3AD75C69A61408EF8BE0F247</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>B90592E4E39AFD1E769F9A95</key>
+		<dict>
+			<key>fileRef</key>
+			<string>F763F3DF1B47888E75D0ED9C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>B960FF1BE77D3F4459EEB1E0</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>7FACBF2C8AF0403DD1C11015</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>DSTROOT</key>
+				<string>/tmp/xcodeproj.dst</string>
+				<key>GCC_PRECOMPILE_PREFIX_HEADER</key>
+				<string>YES</string>
+				<key>GCC_PREFIX_HEADER</key>
+				<string>Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-prefix.pch</string>
+				<key>INSTALL_PATH</key>
+				<string>$(BUILT_PRODUCTS_DIR)</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.0</string>
+				<key>OTHER_CFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_CPLUSPLUSFLAGS</key>
+				<array>
+					<string>-DNS_BLOCK_ASSERTIONS=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>OTHER_LDFLAGS</key>
+				<string></string>
+				<key>OTHER_LIBTOOLFLAGS</key>
+				<string></string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>PUBLIC_HEADERS_FOLDER_PATH</key>
+				<string>$(TARGET_NAME)</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>SKIP_INSTALL</key>
+				<string>YES</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>BA9F62DDE37FF0D601A4D5EA</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>NSEnumerator+GRXUtil.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>BB88043BB37FC0261BA90A30</key>
+		<dict>
+			<key>fileRef</key>
+			<string>636AC1003F2C71FFD74542CD</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>BC50D76123DA4B85E6AD77B4</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>Pods-Sample-dummy.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>BC52B0661F25B25CE382296C</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>GRXImmediateWriter.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>BDA58E5E1AE450540A2B0227</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>GRXWriter.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>BECFE3DCB323841851972996</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>GRXImmediateWriter.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>BFE770FF3C0847AB995A82CA</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>86D03B997B81819E2F39E48B</string>
+				<string>43CC797FB2A733DF5B7A9F05</string>
+				<string>6E0669CB3E76E19FC854BA74</string>
+				<string>CBA4FEEF7E642535FB39D878</string>
+				<string>FC1BEDED07CA4D91AFEB56BD</string>
+				<string>46FAFA88CA3E774263422EB9</string>
+				<string>8915073BE8158EF53FE11B95</string>
+				<string>B90592E4E39AFD1E769F9A95</string>
+				<string>F6383D21195A5BEFC51F6618</string>
+				<string>352B4C7135E3BBBFEBAB7F55</string>
+				<string>E8F0B998CE49FF732F312133</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>C0AC333A6FE8F07600C96890</key>
+		<dict>
+			<key>fileRef</key>
+			<string>1868370C0050315A6B835D42</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>C382F416EFA39BE2CF216044</key>
+		<dict>
+			<key>fileRef</key>
+			<string>5AEFA85A5F1AD206D68B0576</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>C4342DDEEF3C3290956C21DF</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>A8AFEFDF4700447BBCDF9E10</string>
+				<string>0F20828B67FDCB990B1818E9</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>CBA4FEEF7E642535FB39D878</key>
+		<dict>
+			<key>fileRef</key>
+			<string>636AC1003F2C71FFD74542CD</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>CC0A03D531EF0FF199671820</key>
+		<dict>
+			<key>fileRef</key>
+			<string>9CFAC09E370EA1C96C8D2880</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>CC358E38AE146C095C401760</key>
+		<dict>
+			<key>fileRef</key>
+			<string>0260773D27B4AE159FB0B22D</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>D49849E96C0C5FFB93C810CD</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>3133D1CCCF4F1FE3E893509C</string>
+				<string>2FE1D288B8389F925AA3CE0C</string>
+				<string>2663F4401A9075DAC0B24171</string>
+				<string>911BEE248BE640294A081862</string>
+				<string>B034EE43C1EF96D1CBD1328A</string>
+				<string>7FACBF2C8AF0403DD1C11015</string>
+				<string>E232BDE68610C0AC98C0D29F</string>
+				<string>4972C151CE9A8A15BC1AE2C8</string>
+				<string>8A7375A2F98889F35C15E2D7</string>
+				<string>687D79F4C2484F58E9796051</string>
+				<string>42B461F095E85911637DFD60</string>
+				<string>2B05A4C21D00E8CF0DE88447</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Support Files</string>
+			<key>path</key>
+			<string>../examples/Sample/Pods/Target Support Files/Pods-RxLibrary</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>D53A8F2B11E6C2C187AFFF1D</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text</string>
+			<key>path</key>
+			<string>Pods-Sample-acknowledgements.markdown</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>DB007D27F74F8F72C72A1079</key>
+		<dict>
+			<key>containerPortal</key>
+			<string>FBF79DDF04ADEAED54BA2286</string>
+			<key>isa</key>
+			<string>PBXContainerItemProxy</string>
+			<key>proxyType</key>
+			<string>1</string>
+			<key>remoteGlobalIDString</key>
+			<string>6BFD156F312F6CAA1E5B00CA</string>
+			<key>remoteInfo</key>
+			<string>Pods-RxLibrary</string>
+		</dict>
+		<key>DB0257E62EC33F3F316EF017</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>GRXWriter.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>DB3528F609E6177E1C5A691C</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.plist.xml</string>
+			<key>path</key>
+			<string>Pods-SampleTests-acknowledgements.plist</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>DB677464758307786D68CCE9</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>path</key>
+			<string>Pods-SampleTests.release.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>DCAB71BD665AF17533987B69</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>85D5565EC08D14A6A60F1DDA</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>DF94410F5DC0A0AB69336DF4</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods-Sample.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>E14CB6F332A9E58BB5F76C07</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.script.sh</string>
+			<key>path</key>
+			<string>Pods-resources.sh</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>E232BDE68610C0AC98C0D29F</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>name</key>
+			<string>Pods-Sample-RxLibrary-dummy.m</string>
+			<key>path</key>
+			<string>../Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-dummy.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>E86A17CE1D79ECDCEBF91109</key>
+		<dict>
+			<key>fileRef</key>
+			<string>F763F3DF1B47888E75D0ED9C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>E8F0B998CE49FF732F312133</key>
+		<dict>
+			<key>fileRef</key>
+			<string>E232BDE68610C0AC98C0D29F</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>EB29FAB1F81F0D17BDAD72D0</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>GRXWriter+Immediate.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>EF2EE4BC906FF9909348DAB5</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods-Sample-RxLibrary.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>EF8B807C5A2059D6C709450D</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>Pods-SampleTests-environment.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>F2BB78774BCEFD5DDDF38239</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>69E8FF71552D08D72B9068F1</string>
+				<string>7A8627E1649F66DEE014EB46</string>
+				<string>0D09CEB9308FA5BACEB5F84C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Targets Support Files</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>F2C6AACFE46FFA8DC383DE43</key>
+		<dict>
+			<key>fileRef</key>
+			<string>0D53085043D992DC00E29F0A</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>F6383D21195A5BEFC51F6618</key>
+		<dict>
+			<key>fileRef</key>
+			<string>BDA58E5E1AE450540A2B0227</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>F6C59E5B4CFE053E9F98000E</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>17F4C2F25813E7A4588FF233</string>
+			<key>buildPhases</key>
+			<array>
+				<string>BFE770FF3C0847AB995A82CA</string>
+				<string>1146D04C598DEBA045C96C2F</string>
+				<string>9E8DC61269B141639DA7F859</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Pods-Sample-RxLibrary</string>
+			<key>productName</key>
+			<string>Pods-Sample-RxLibrary</string>
+			<key>productReference</key>
+			<string>EF2EE4BC906FF9909348DAB5</string>
+			<key>productType</key>
+			<string>com.apple.product-type.library.static</string>
+		</dict>
+		<key>F763F3DF1B47888E75D0ED9C</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>GRXWriter+Transformations.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>F779618174957BE31FCCDE56</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>2B49DCA723ECBC0F2777B960</string>
+				<string>22531AF83592134D3879C3E1</string>
+				<string>0C57EED724EBF58759F9F6DF</string>
+				<string>8CD061F02F905957F4C1D188</string>
+				<string>458FF1EEF4EB9646C699F3DD</string>
+				<string>2B341576464148A01DCFB28B</string>
+				<string>36FF37EAC7E918C4CD867776</string>
+				<string>594F98D43B96AB5C11E61C10</string>
+				<string>B78477CA74AEFC96C25B49B4</string>
+				<string>9CCBE9A628C305B3B089B8DD</string>
+				<string>801BBA7A538CFAE6746966A7</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>F8B4778EF3030EEC2E9927CE</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXTargetDependency</string>
+			<key>name</key>
+			<string>Pods-SampleTests-RxLibrary</string>
+			<key>target</key>
+			<string>3800855A656C8D0813062074</string>
+			<key>targetProxy</key>
+			<string>7DA2A517A18D85B390FB122A</string>
+		</dict>
+		<key>FBF79DDF04ADEAED54BA2286</key>
+		<dict>
+			<key>attributes</key>
+			<dict>
+				<key>LastUpgradeCheck</key>
+				<string>0510</string>
+			</dict>
+			<key>buildConfigurationList</key>
+			<string>3749A34D3DFA6E2F3539E546</string>
+			<key>compatibilityVersion</key>
+			<string>Xcode 3.2</string>
+			<key>developmentRegion</key>
+			<string>English</string>
+			<key>hasScannedForEncodings</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXProject</string>
+			<key>knownRegions</key>
+			<array>
+				<string>en</string>
+			</array>
+			<key>mainGroup</key>
+			<string>397A12919FB4BDD608FE207C</string>
+			<key>productRefGroup</key>
+			<string>8B05D39455D5B23720961FA4</string>
+			<key>projectDirPath</key>
+			<string></string>
+			<key>projectReferences</key>
+			<array/>
+			<key>projectRoot</key>
+			<string></string>
+			<key>targets</key>
+			<array>
+				<string>26E6ACBF137DBC325B4E7DA7</string>
+				<string>6BFD156F312F6CAA1E5B00CA</string>
+				<string>0239F1B46D24E21A8042F47F</string>
+				<string>F6C59E5B4CFE053E9F98000E</string>
+				<string>14D92BB2ED12213381BD2EB9</string>
+				<string>3800855A656C8D0813062074</string>
+			</array>
+		</dict>
+		<key>FC1BEDED07CA4D91AFEB56BD</key>
+		<dict>
+			<key>fileRef</key>
+			<string>57AC9BF19B9635D7476CA5FA</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>FDC6B84EAC9989F0827EA4F3</key>
+		<dict>
+			<key>fileRef</key>
+			<string>0260773D27B4AE159FB0B22D</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>FDC939796E70DC7D141E29FC</key>
+		<dict>
+			<key>fileRef</key>
+			<string>DB0257E62EC33F3F316EF017</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+	</dict>
+	<key>rootObject</key>
+	<string>FBF79DDF04ADEAED54BA2286</string>
+</dict>
+</plist>
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-Private.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-Private.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..5c1a7097bed70be3db68efd76c2f503ac5079658
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-Private.xcconfig	
@@ -0,0 +1,5 @@
+#include "Pods-RxLibrary.xcconfig"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/RxLibrary" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC
+PODS_ROOT = ${SRCROOT}
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-dummy.m b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-dummy.m
new file mode 100644
index 0000000000000000000000000000000000000000..79e146025702ff6abc0d808caef6dc46132c9b01
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-dummy.m	
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_RxLibrary : NSObject
+@end
+@implementation PodsDummy_Pods_RxLibrary
+@end
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-prefix.pch b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-prefix.pch
new file mode 100644
index 0000000000000000000000000000000000000000..95cf11d9fb04da88b7d82d6e26fb881b62c28b75
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary-prefix.pch	
@@ -0,0 +1,5 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#endif
+
+#import "Pods-environment.h"
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-RxLibrary/Pods-RxLibrary.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-Private.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-Private.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..2cc81f729dc4953b4ae67038df7cb116410619dd
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-Private.xcconfig	
@@ -0,0 +1,5 @@
+#include "Pods-Sample-RxLibrary.xcconfig"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/RxLibrary" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC
+PODS_ROOT = ${SRCROOT}
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-dummy.m b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-dummy.m
new file mode 100644
index 0000000000000000000000000000000000000000..c81b57bbe880861dcb7c02f8afb90824b6a6655e
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-dummy.m	
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_Sample_RxLibrary : NSObject
+@end
+@implementation PodsDummy_Pods_Sample_RxLibrary
+@end
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-prefix.pch b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-prefix.pch
new file mode 100644
index 0000000000000000000000000000000000000000..0e807f67a35ac9dccfea77be0cd6a5bf175e7be3
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary-prefix.pch	
@@ -0,0 +1,5 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#endif
+
+#import "Pods-Sample-environment.h"
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample-RxLibrary/Pods-Sample-RxLibrary.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-acknowledgements.markdown b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-acknowledgements.markdown
new file mode 100644
index 0000000000000000000000000000000000000000..255149a828678c05336d615fa0b513b0dbf20816
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-acknowledgements.markdown	
@@ -0,0 +1,3 @@
+# Acknowledgements
+This application makes use of the following third party libraries:
+Generated by CocoaPods - http://cocoapods.org
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-acknowledgements.plist b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-acknowledgements.plist
new file mode 100644
index 0000000000000000000000000000000000000000..e4edebe92da6bc5bb3d514a675d78f68a45ccad4
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-acknowledgements.plist	
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreferenceSpecifiers</key>
+	<array>
+		<dict>
+			<key>FooterText</key>
+			<string>This application makes use of the following third party libraries:</string>
+			<key>Title</key>
+			<string>Acknowledgements</string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+		<dict>
+			<key>FooterText</key>
+			<string>Generated by CocoaPods - http://cocoapods.org</string>
+			<key>Title</key>
+			<string></string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+	</array>
+	<key>StringsTable</key>
+	<string>Acknowledgements</string>
+	<key>Title</key>
+	<string>Acknowledgements</string>
+</dict>
+</plist>
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-dummy.m b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-dummy.m
new file mode 100644
index 0000000000000000000000000000000000000000..b5ca68a1c55e4edfe41b0612050207f807a7d55a
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-dummy.m	
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_Sample : NSObject
+@end
+@implementation PodsDummy_Pods_Sample
+@end
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-environment.h b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-environment.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4fd16b369bbc3b0b1242cedea20fc676550971e
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-environment.h	
@@ -0,0 +1,14 @@
+
+// To check if a library is compiled with CocoaPods you
+// can use the `COCOAPODS` macro definition which is
+// defined in the xcconfigs so it is available in
+// headers also when they are imported in the client
+// project.
+
+
+// RxLibrary
+#define COCOAPODS_POD_AVAILABLE_RxLibrary
+#define COCOAPODS_VERSION_MAJOR_RxLibrary 0
+#define COCOAPODS_VERSION_MINOR_RxLibrary 0
+#define COCOAPODS_VERSION_PATCH_RxLibrary 1
+
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-resources.sh b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-resources.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e149064a090682c96ecd6833aa61db7e87a2eab5
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample-resources.sh	
@@ -0,0 +1,74 @@
+#!/bin/sh
+set -e
+
+mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+
+RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
+> "$RESOURCES_TO_COPY"
+
+install_resource()
+{
+  case $1 in
+    *.storyboard)
+      echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
+      ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
+      ;;
+    *.xib)
+        echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
+      ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
+      ;;
+    *.framework)
+      echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      ;;
+    *.xcdatamodel)
+      echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
+      xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
+      ;;
+    *.xcdatamodeld)
+      echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
+      xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
+      ;;
+    *.xcmappingmodel)
+      echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\""
+      xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
+      ;;
+    *.xcassets)
+      ;;
+    /*)
+      echo "$1"
+      echo "$1" >> "$RESOURCES_TO_COPY"
+      ;;
+    *)
+      echo "${PODS_ROOT}/$1"
+      echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
+      ;;
+  esac
+}
+
+rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+if [[ "${ACTION}" == "install" ]]; then
+  rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+fi
+rm -f "$RESOURCES_TO_COPY"
+
+if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ]
+then
+  case "${TARGETED_DEVICE_FAMILY}" in
+    1,2)
+      TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
+      ;;
+    1)
+      TARGET_DEVICE_ARGS="--target-device iphone"
+      ;;
+    2)
+      TARGET_DEVICE_ARGS="--target-device ipad"
+      ;;
+    *)
+      TARGET_DEVICE_ARGS="--target-device mac"
+      ;;
+  esac
+  find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+fi
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..776727154c16c18e418891e04460318aad6f30e5
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig	
@@ -0,0 +1,6 @@
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC -l"Pods-Sample-RxLibrary"
+OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
+PODS_ROOT = ${SRCROOT}/Pods
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..776727154c16c18e418891e04460318aad6f30e5
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig	
@@ -0,0 +1,6 @@
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC -l"Pods-Sample-RxLibrary"
+OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
+PODS_ROOT = ${SRCROOT}/Pods
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-Private.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-Private.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..a3cd79243452f38e766239b04fb312230a53e383
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-Private.xcconfig	
@@ -0,0 +1,5 @@
+#include "Pods-SampleTests-RxLibrary.xcconfig"
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/RxLibrary" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC
+PODS_ROOT = ${SRCROOT}
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-dummy.m b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-dummy.m
new file mode 100644
index 0000000000000000000000000000000000000000..d57aef11d68120ea48848750027d4aa02d77b457
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-dummy.m	
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_SampleTests_RxLibrary : NSObject
+@end
+@implementation PodsDummy_Pods_SampleTests_RxLibrary
+@end
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-prefix.pch b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-prefix.pch
new file mode 100644
index 0000000000000000000000000000000000000000..abd56515872177cd1fbfd31cb70501fb4e7e2563
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary-prefix.pch	
@@ -0,0 +1,5 @@
+#ifdef __OBJC__
+#import <UIKit/UIKit.h>
+#endif
+
+#import "Pods-SampleTests-environment.h"
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests-RxLibrary/Pods-SampleTests-RxLibrary.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-acknowledgements.markdown b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-acknowledgements.markdown
new file mode 100644
index 0000000000000000000000000000000000000000..255149a828678c05336d615fa0b513b0dbf20816
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-acknowledgements.markdown	
@@ -0,0 +1,3 @@
+# Acknowledgements
+This application makes use of the following third party libraries:
+Generated by CocoaPods - http://cocoapods.org
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-acknowledgements.plist b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-acknowledgements.plist
new file mode 100644
index 0000000000000000000000000000000000000000..e4edebe92da6bc5bb3d514a675d78f68a45ccad4
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-acknowledgements.plist	
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreferenceSpecifiers</key>
+	<array>
+		<dict>
+			<key>FooterText</key>
+			<string>This application makes use of the following third party libraries:</string>
+			<key>Title</key>
+			<string>Acknowledgements</string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+		<dict>
+			<key>FooterText</key>
+			<string>Generated by CocoaPods - http://cocoapods.org</string>
+			<key>Title</key>
+			<string></string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+	</array>
+	<key>StringsTable</key>
+	<string>Acknowledgements</string>
+	<key>Title</key>
+	<string>Acknowledgements</string>
+</dict>
+</plist>
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-dummy.m b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-dummy.m
new file mode 100644
index 0000000000000000000000000000000000000000..01b4ad73ba6c3cc05360ed830dbe9e33b0a5b177
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-dummy.m	
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods_SampleTests : NSObject
+@end
+@implementation PodsDummy_Pods_SampleTests
+@end
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-environment.h b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-environment.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4fd16b369bbc3b0b1242cedea20fc676550971e
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-environment.h	
@@ -0,0 +1,14 @@
+
+// To check if a library is compiled with CocoaPods you
+// can use the `COCOAPODS` macro definition which is
+// defined in the xcconfigs so it is available in
+// headers also when they are imported in the client
+// project.
+
+
+// RxLibrary
+#define COCOAPODS_POD_AVAILABLE_RxLibrary
+#define COCOAPODS_VERSION_MAJOR_RxLibrary 0
+#define COCOAPODS_VERSION_MINOR_RxLibrary 0
+#define COCOAPODS_VERSION_PATCH_RxLibrary 1
+
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-resources.sh b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-resources.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e149064a090682c96ecd6833aa61db7e87a2eab5
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests-resources.sh	
@@ -0,0 +1,74 @@
+#!/bin/sh
+set -e
+
+mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+
+RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
+> "$RESOURCES_TO_COPY"
+
+install_resource()
+{
+  case $1 in
+    *.storyboard)
+      echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
+      ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
+      ;;
+    *.xib)
+        echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
+      ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
+      ;;
+    *.framework)
+      echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      ;;
+    *.xcdatamodel)
+      echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
+      xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
+      ;;
+    *.xcdatamodeld)
+      echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
+      xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
+      ;;
+    *.xcmappingmodel)
+      echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\""
+      xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
+      ;;
+    *.xcassets)
+      ;;
+    /*)
+      echo "$1"
+      echo "$1" >> "$RESOURCES_TO_COPY"
+      ;;
+    *)
+      echo "${PODS_ROOT}/$1"
+      echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
+      ;;
+  esac
+}
+
+rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+if [[ "${ACTION}" == "install" ]]; then
+  rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+fi
+rm -f "$RESOURCES_TO_COPY"
+
+if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ]
+then
+  case "${TARGETED_DEVICE_FAMILY}" in
+    1,2)
+      TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
+      ;;
+    1)
+      TARGET_DEVICE_ARGS="--target-device iphone"
+      ;;
+    2)
+      TARGET_DEVICE_ARGS="--target-device ipad"
+      ;;
+    *)
+      TARGET_DEVICE_ARGS="--target-device mac"
+      ;;
+  esac
+  find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+fi
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests.debug.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests.debug.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..92a3b7d2bd5c576daedb9a81221282766b524238
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests.debug.xcconfig	
@@ -0,0 +1,6 @@
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC -l"Pods-SampleTests-RxLibrary"
+OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
+PODS_ROOT = ${SRCROOT}/Pods
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests.release.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests.release.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..92a3b7d2bd5c576daedb9a81221282766b524238
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods-SampleTests/Pods-SampleTests.release.xcconfig	
@@ -0,0 +1,6 @@
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC -l"Pods-SampleTests-RxLibrary"
+OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
+PODS_ROOT = ${SRCROOT}/Pods
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown
new file mode 100644
index 0000000000000000000000000000000000000000..255149a828678c05336d615fa0b513b0dbf20816
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown	
@@ -0,0 +1,3 @@
+# Acknowledgements
+This application makes use of the following third party libraries:
+Generated by CocoaPods - http://cocoapods.org
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-acknowledgements.plist b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-acknowledgements.plist
new file mode 100644
index 0000000000000000000000000000000000000000..e4edebe92da6bc5bb3d514a675d78f68a45ccad4
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-acknowledgements.plist	
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PreferenceSpecifiers</key>
+	<array>
+		<dict>
+			<key>FooterText</key>
+			<string>This application makes use of the following third party libraries:</string>
+			<key>Title</key>
+			<string>Acknowledgements</string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+		<dict>
+			<key>FooterText</key>
+			<string>Generated by CocoaPods - http://cocoapods.org</string>
+			<key>Title</key>
+			<string></string>
+			<key>Type</key>
+			<string>PSGroupSpecifier</string>
+		</dict>
+	</array>
+	<key>StringsTable</key>
+	<string>Acknowledgements</string>
+	<key>Title</key>
+	<string>Acknowledgements</string>
+</dict>
+</plist>
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-dummy.m b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-dummy.m
new file mode 100644
index 0000000000000000000000000000000000000000..ade64bd1a9b4e9fc118a37c545ef232fecffa983
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-dummy.m	
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+@interface PodsDummy_Pods : NSObject
+@end
+@implementation PodsDummy_Pods
+@end
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-environment.h b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-environment.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4fd16b369bbc3b0b1242cedea20fc676550971e
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-environment.h	
@@ -0,0 +1,14 @@
+
+// To check if a library is compiled with CocoaPods you
+// can use the `COCOAPODS` macro definition which is
+// defined in the xcconfigs so it is available in
+// headers also when they are imported in the client
+// project.
+
+
+// RxLibrary
+#define COCOAPODS_POD_AVAILABLE_RxLibrary
+#define COCOAPODS_VERSION_MAJOR_RxLibrary 0
+#define COCOAPODS_VERSION_MINOR_RxLibrary 0
+#define COCOAPODS_VERSION_PATCH_RxLibrary 1
+
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-resources.sh b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-resources.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e149064a090682c96ecd6833aa61db7e87a2eab5
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods-resources.sh	
@@ -0,0 +1,74 @@
+#!/bin/sh
+set -e
+
+mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+
+RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
+> "$RESOURCES_TO_COPY"
+
+install_resource()
+{
+  case $1 in
+    *.storyboard)
+      echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
+      ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
+      ;;
+    *.xib)
+        echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
+      ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
+      ;;
+    *.framework)
+      echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
+      ;;
+    *.xcdatamodel)
+      echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
+      xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
+      ;;
+    *.xcdatamodeld)
+      echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
+      xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
+      ;;
+    *.xcmappingmodel)
+      echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\""
+      xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
+      ;;
+    *.xcassets)
+      ;;
+    /*)
+      echo "$1"
+      echo "$1" >> "$RESOURCES_TO_COPY"
+      ;;
+    *)
+      echo "${PODS_ROOT}/$1"
+      echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
+      ;;
+  esac
+}
+
+rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+if [[ "${ACTION}" == "install" ]]; then
+  rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+fi
+rm -f "$RESOURCES_TO_COPY"
+
+if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ]
+then
+  case "${TARGETED_DEVICE_FAMILY}" in
+    1,2)
+      TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
+      ;;
+    1)
+      TARGET_DEVICE_ARGS="--target-device iphone"
+      ;;
+    2)
+      TARGET_DEVICE_ARGS="--target-device ipad"
+      ;;
+    *)
+      TARGET_DEVICE_ARGS="--target-device mac"
+      ;;
+  esac
+  find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
+fi
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods.debug.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods.debug.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..3c7fe4aa0074815fba3e495100de1e39f17df6f6
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods.debug.xcconfig	
@@ -0,0 +1,6 @@
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC -l"Pods-RxLibrary"
+OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
+PODS_ROOT = ${SRCROOT}/Pods
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods.release.xcconfig b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods.release.xcconfig
new file mode 100644
index 0000000000000000000000000000000000000000..3c7fe4aa0074815fba3e495100de1e39f17df6f6
--- /dev/null
+++ b/src/objective-c/examples/Sample/Pods/Target Support Files/Pods/Pods.release.xcconfig	
@@ -0,0 +1,6 @@
+GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
+HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/RxLibrary"
+OTHER_LDFLAGS = -ObjC -l"Pods-RxLibrary"
+OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
+PODS_ROOT = ${SRCROOT}/Pods
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/README.md b/src/objective-c/examples/Sample/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..45ba544a34a1b8d256222c359e83fd9c0b680c37
--- /dev/null
+++ b/src/objective-c/examples/Sample/README.md
@@ -0,0 +1,2 @@
+When contributing changes to this sample, use Cocoapods to manage the workspace
+file and everything under the Pods directory.
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000000000000000000000000000000000..142e60e2b25e318311f0ab8de2ed198ed45bb71d
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
@@ -0,0 +1,955 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>archiveVersion</key>
+	<string>1</string>
+	<key>classes</key>
+	<dict/>
+	<key>objectVersion</key>
+	<string>46</string>
+	<key>objects</key>
+	<dict>
+		<key>04554623324BE4A838846086</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array/>
+			<key>inputPaths</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXShellScriptBuildPhase</string>
+			<key>name</key>
+			<string>Copy Pods Resources</string>
+			<key>outputPaths</key>
+			<array/>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+			<key>shellPath</key>
+			<string>/bin/sh</string>
+			<key>shellScript</key>
+			<string>"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh"
+</string>
+			<key>showEnvVarsInLog</key>
+			<string>0</string>
+		</dict>
+		<key>2DC7B7C4C0410F43B9621631</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>archive.ar</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>libPods.a</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>41F7486D8F66994B0BFB84AF</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array/>
+			<key>inputPaths</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXShellScriptBuildPhase</string>
+			<key>name</key>
+			<string>Check Pods Manifest.lock</string>
+			<key>outputPaths</key>
+			<array/>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+			<key>shellPath</key>
+			<string>/bin/sh</string>
+			<key>shellScript</key>
+			<string>diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" &gt; /dev/null
+if [[ $? != 0 ]] ; then
+    cat &lt;&lt; EOM
+error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
+EOM
+    exit 1
+fi
+</string>
+			<key>showEnvVarsInLog</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2611A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A26C1A9322E20015FC5C</string>
+				<string>6369A2861A9322E20015FC5C</string>
+				<string>6369A26B1A9322E20015FC5C</string>
+				<string>AB3331C9AE6488E61B2B094E</string>
+				<string>C4C2C5219053E079C9EFB930</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2621A9322E20015FC5C</key>
+		<dict>
+			<key>attributes</key>
+			<dict>
+				<key>LastUpgradeCheck</key>
+				<string>0610</string>
+				<key>ORGANIZATIONNAME</key>
+				<string>gRPC</string>
+				<key>TargetAttributes</key>
+				<dict>
+					<key>6369A2691A9322E20015FC5C</key>
+					<dict>
+						<key>CreatedOnToolsVersion</key>
+						<string>6.1.1</string>
+					</dict>
+					<key>6369A2821A9322E20015FC5C</key>
+					<dict>
+						<key>CreatedOnToolsVersion</key>
+						<string>6.1.1</string>
+						<key>TestTargetID</key>
+						<string>6369A2691A9322E20015FC5C</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>buildConfigurationList</key>
+			<string>6369A2651A9322E20015FC5C</string>
+			<key>compatibilityVersion</key>
+			<string>Xcode 3.2</string>
+			<key>developmentRegion</key>
+			<string>English</string>
+			<key>hasScannedForEncodings</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXProject</string>
+			<key>knownRegions</key>
+			<array>
+				<string>en</string>
+				<string>Base</string>
+			</array>
+			<key>mainGroup</key>
+			<string>6369A2611A9322E20015FC5C</string>
+			<key>productRefGroup</key>
+			<string>6369A26B1A9322E20015FC5C</string>
+			<key>projectDirPath</key>
+			<string></string>
+			<key>projectReferences</key>
+			<array/>
+			<key>projectRoot</key>
+			<string></string>
+			<key>targets</key>
+			<array>
+				<string>6369A2691A9322E20015FC5C</string>
+				<string>6369A2821A9322E20015FC5C</string>
+			</array>
+		</dict>
+		<key>6369A2651A9322E20015FC5C</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>6369A28B1A9322E20015FC5C</string>
+				<string>6369A28C1A9322E20015FC5C</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>defaultConfigurationName</key>
+			<string>Release</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>6369A2661A9322E20015FC5C</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>6369A2761A9322E20015FC5C</string>
+				<string>6369A2731A9322E20015FC5C</string>
+				<string>6369A2701A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2671A9322E20015FC5C</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>FC81FE63CA655031F3524EC0</string>
+			</array>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2681A9322E20015FC5C</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>6369A2791A9322E20015FC5C</string>
+				<string>6369A27E1A9322E20015FC5C</string>
+				<string>6369A27B1A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXResourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2691A9322E20015FC5C</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>6369A28D1A9322E20015FC5C</string>
+			<key>buildPhases</key>
+			<array>
+				<string>41F7486D8F66994B0BFB84AF</string>
+				<string>6369A2661A9322E20015FC5C</string>
+				<string>6369A2671A9322E20015FC5C</string>
+				<string>6369A2681A9322E20015FC5C</string>
+				<string>04554623324BE4A838846086</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>Sample</string>
+			<key>productName</key>
+			<string>Sample</string>
+			<key>productReference</key>
+			<string>6369A26A1A9322E20015FC5C</string>
+			<key>productType</key>
+			<string>com.apple.product-type.application</string>
+		</dict>
+		<key>6369A26A1A9322E20015FC5C</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>wrapper.application</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>Sample.app</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>6369A26B1A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A26A1A9322E20015FC5C</string>
+				<string>6369A2831A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Products</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A26C1A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A2711A9322E20015FC5C</string>
+				<string>6369A2721A9322E20015FC5C</string>
+				<string>6369A2741A9322E20015FC5C</string>
+				<string>6369A2751A9322E20015FC5C</string>
+				<string>6369A2771A9322E20015FC5C</string>
+				<string>6369A27A1A9322E20015FC5C</string>
+				<string>6369A27C1A9322E20015FC5C</string>
+				<string>6369A26D1A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>path</key>
+			<string>Sample</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A26D1A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A26E1A9322E20015FC5C</string>
+				<string>6369A26F1A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Supporting Files</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A26E1A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.plist.xml</string>
+			<key>path</key>
+			<string>Info.plist</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A26F1A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>main.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2701A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A26F1A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A2711A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>AppDelegate.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2721A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>AppDelegate.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2731A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A2721A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A2741A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.h</string>
+			<key>path</key>
+			<string>ViewController.h</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2751A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>ViewController.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2761A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A2751A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A2771A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A2781A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXVariantGroup</string>
+			<key>name</key>
+			<string>Main.storyboard</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2781A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>file.storyboard</string>
+			<key>name</key>
+			<string>Base</string>
+			<key>path</key>
+			<string>Base.lproj/Main.storyboard</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2791A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A2771A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A27A1A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>folder.assetcatalog</string>
+			<key>path</key>
+			<string>Images.xcassets</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A27B1A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A27A1A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A27C1A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A27D1A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXVariantGroup</string>
+			<key>name</key>
+			<string>LaunchScreen.xib</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A27D1A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>file.xib</string>
+			<key>name</key>
+			<string>Base</string>
+			<key>path</key>
+			<string>Base.lproj/LaunchScreen.xib</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A27E1A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A27C1A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A27F1A9322E20015FC5C</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array>
+				<string>6369A28A1A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXSourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2801A9322E20015FC5C</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXFrameworksBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2811A9322E20015FC5C</key>
+		<dict>
+			<key>buildActionMask</key>
+			<string>2147483647</string>
+			<key>files</key>
+			<array/>
+			<key>isa</key>
+			<string>PBXResourcesBuildPhase</string>
+			<key>runOnlyForDeploymentPostprocessing</key>
+			<string>0</string>
+		</dict>
+		<key>6369A2821A9322E20015FC5C</key>
+		<dict>
+			<key>buildConfigurationList</key>
+			<string>6369A2901A9322E20015FC5C</string>
+			<key>buildPhases</key>
+			<array>
+				<string>6369A27F1A9322E20015FC5C</string>
+				<string>6369A2801A9322E20015FC5C</string>
+				<string>6369A2811A9322E20015FC5C</string>
+			</array>
+			<key>buildRules</key>
+			<array/>
+			<key>dependencies</key>
+			<array>
+				<string>6369A2851A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXNativeTarget</string>
+			<key>name</key>
+			<string>SampleTests</string>
+			<key>productName</key>
+			<string>SampleTests</string>
+			<key>productReference</key>
+			<string>6369A2831A9322E20015FC5C</string>
+			<key>productType</key>
+			<string>com.apple.product-type.bundle.unit-test</string>
+		</dict>
+		<key>6369A2831A9322E20015FC5C</key>
+		<dict>
+			<key>explicitFileType</key>
+			<string>wrapper.cfbundle</string>
+			<key>includeInIndex</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>path</key>
+			<string>SampleTests.xctest</string>
+			<key>sourceTree</key>
+			<string>BUILT_PRODUCTS_DIR</string>
+		</dict>
+		<key>6369A2841A9322E20015FC5C</key>
+		<dict>
+			<key>containerPortal</key>
+			<string>6369A2621A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXContainerItemProxy</string>
+			<key>proxyType</key>
+			<string>1</string>
+			<key>remoteGlobalIDString</key>
+			<string>6369A2691A9322E20015FC5C</string>
+			<key>remoteInfo</key>
+			<string>Sample</string>
+		</dict>
+		<key>6369A2851A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXTargetDependency</string>
+			<key>target</key>
+			<string>6369A2691A9322E20015FC5C</string>
+			<key>targetProxy</key>
+			<string>6369A2841A9322E20015FC5C</string>
+		</dict>
+		<key>6369A2861A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A2891A9322E20015FC5C</string>
+				<string>6369A2871A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>path</key>
+			<string>SampleTests</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2871A9322E20015FC5C</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>6369A2881A9322E20015FC5C</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Supporting Files</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2881A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.plist.xml</string>
+			<key>path</key>
+			<string>Info.plist</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A2891A9322E20015FC5C</key>
+		<dict>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>sourcecode.c.objc</string>
+			<key>path</key>
+			<string>SampleTests.m</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>6369A28A1A9322E20015FC5C</key>
+		<dict>
+			<key>fileRef</key>
+			<string>6369A2891A9322E20015FC5C</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+		<key>6369A28B1A9322E20015FC5C</key>
+		<dict>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>CLANG_CXX_LANGUAGE_STANDARD</key>
+				<string>gnu++0x</string>
+				<key>CLANG_CXX_LIBRARY</key>
+				<string>libc++</string>
+				<key>CLANG_ENABLE_MODULES</key>
+				<string>YES</string>
+				<key>CLANG_ENABLE_OBJC_ARC</key>
+				<string>YES</string>
+				<key>CLANG_WARN_BOOL_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_CONSTANT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_DIRECT_OBJC_ISA_USAGE</key>
+				<string>YES_ERROR</string>
+				<key>CLANG_WARN_EMPTY_BODY</key>
+				<string>YES</string>
+				<key>CLANG_WARN_ENUM_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_INT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_OBJC_ROOT_CLASS</key>
+				<string>YES_ERROR</string>
+				<key>CLANG_WARN_UNREACHABLE_CODE</key>
+				<string>YES</string>
+				<key>CLANG_WARN__DUPLICATE_METHOD_MATCH</key>
+				<string>YES</string>
+				<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
+				<string>iPhone Developer</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>NO</string>
+				<key>ENABLE_STRICT_OBJC_MSGSEND</key>
+				<string>YES</string>
+				<key>GCC_C_LANGUAGE_STANDARD</key>
+				<string>gnu99</string>
+				<key>GCC_DYNAMIC_NO_PIC</key>
+				<string>NO</string>
+				<key>GCC_OPTIMIZATION_LEVEL</key>
+				<string>0</string>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
+				<string>NO</string>
+				<key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
+				<string>YES</string>
+				<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
+				<string>YES_ERROR</string>
+				<key>GCC_WARN_UNDECLARED_SELECTOR</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNINITIALIZED_AUTOS</key>
+				<string>YES_AGGRESSIVE</string>
+				<key>GCC_WARN_UNUSED_FUNCTION</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNUSED_VARIABLE</key>
+				<string>YES</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.1</string>
+				<key>MTL_ENABLE_DEBUG_INFO</key>
+				<string>YES</string>
+				<key>ONLY_ACTIVE_ARCH</key>
+				<string>YES</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>TARGETED_DEVICE_FAMILY</key>
+				<string>1,2</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>6369A28C1A9322E20015FC5C</key>
+		<dict>
+			<key>buildSettings</key>
+			<dict>
+				<key>ALWAYS_SEARCH_USER_PATHS</key>
+				<string>NO</string>
+				<key>CLANG_CXX_LANGUAGE_STANDARD</key>
+				<string>gnu++0x</string>
+				<key>CLANG_CXX_LIBRARY</key>
+				<string>libc++</string>
+				<key>CLANG_ENABLE_MODULES</key>
+				<string>YES</string>
+				<key>CLANG_ENABLE_OBJC_ARC</key>
+				<string>YES</string>
+				<key>CLANG_WARN_BOOL_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_CONSTANT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_DIRECT_OBJC_ISA_USAGE</key>
+				<string>YES_ERROR</string>
+				<key>CLANG_WARN_EMPTY_BODY</key>
+				<string>YES</string>
+				<key>CLANG_WARN_ENUM_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_INT_CONVERSION</key>
+				<string>YES</string>
+				<key>CLANG_WARN_OBJC_ROOT_CLASS</key>
+				<string>YES_ERROR</string>
+				<key>CLANG_WARN_UNREACHABLE_CODE</key>
+				<string>YES</string>
+				<key>CLANG_WARN__DUPLICATE_METHOD_MATCH</key>
+				<string>YES</string>
+				<key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
+				<string>iPhone Developer</string>
+				<key>COPY_PHASE_STRIP</key>
+				<string>YES</string>
+				<key>ENABLE_NS_ASSERTIONS</key>
+				<string>NO</string>
+				<key>ENABLE_STRICT_OBJC_MSGSEND</key>
+				<string>YES</string>
+				<key>GCC_C_LANGUAGE_STANDARD</key>
+				<string>gnu99</string>
+				<key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
+				<string>YES</string>
+				<key>GCC_WARN_ABOUT_RETURN_TYPE</key>
+				<string>YES_ERROR</string>
+				<key>GCC_WARN_UNDECLARED_SELECTOR</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNINITIALIZED_AUTOS</key>
+				<string>YES_AGGRESSIVE</string>
+				<key>GCC_WARN_UNUSED_FUNCTION</key>
+				<string>YES</string>
+				<key>GCC_WARN_UNUSED_VARIABLE</key>
+				<string>YES</string>
+				<key>IPHONEOS_DEPLOYMENT_TARGET</key>
+				<string>8.1</string>
+				<key>MTL_ENABLE_DEBUG_INFO</key>
+				<string>NO</string>
+				<key>SDKROOT</key>
+				<string>iphoneos</string>
+				<key>TARGETED_DEVICE_FAMILY</key>
+				<string>1,2</string>
+				<key>VALIDATE_PRODUCT</key>
+				<string>YES</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>6369A28D1A9322E20015FC5C</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>6369A28E1A9322E20015FC5C</string>
+				<string>6369A28F1A9322E20015FC5C</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>6369A28E1A9322E20015FC5C</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>AC29DD6FCDF962F519FEBB0D</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ASSETCATALOG_COMPILER_APPICON_NAME</key>
+				<string>AppIcon</string>
+				<key>INFOPLIST_FILE</key>
+				<string>Sample/Info.plist</string>
+				<key>LD_RUNPATH_SEARCH_PATHS</key>
+				<string>$(inherited) @executable_path/Frameworks</string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>6369A28F1A9322E20015FC5C</key>
+		<dict>
+			<key>baseConfigurationReference</key>
+			<string>C68330F8D451CC6ACEABA09F</string>
+			<key>buildSettings</key>
+			<dict>
+				<key>ASSETCATALOG_COMPILER_APPICON_NAME</key>
+				<string>AppIcon</string>
+				<key>INFOPLIST_FILE</key>
+				<string>Sample/Info.plist</string>
+				<key>LD_RUNPATH_SEARCH_PATHS</key>
+				<string>$(inherited) @executable_path/Frameworks</string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>6369A2901A9322E20015FC5C</key>
+		<dict>
+			<key>buildConfigurations</key>
+			<array>
+				<string>6369A2911A9322E20015FC5C</string>
+				<string>6369A2921A9322E20015FC5C</string>
+			</array>
+			<key>defaultConfigurationIsVisible</key>
+			<string>0</string>
+			<key>isa</key>
+			<string>XCConfigurationList</string>
+		</dict>
+		<key>6369A2911A9322E20015FC5C</key>
+		<dict>
+			<key>buildSettings</key>
+			<dict>
+				<key>BUNDLE_LOADER</key>
+				<string>$(TEST_HOST)</string>
+				<key>FRAMEWORK_SEARCH_PATHS</key>
+				<array>
+					<string>$(SDKROOT)/Developer/Library/Frameworks</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>GCC_PREPROCESSOR_DEFINITIONS</key>
+				<array>
+					<string>DEBUG=1</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>INFOPLIST_FILE</key>
+				<string>SampleTests/Info.plist</string>
+				<key>LD_RUNPATH_SEARCH_PATHS</key>
+				<string>$(inherited) @executable_path/Frameworks @loader_path/Frameworks</string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>TEST_HOST</key>
+				<string>$(BUILT_PRODUCTS_DIR)/Sample.app/Sample</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Debug</string>
+		</dict>
+		<key>6369A2921A9322E20015FC5C</key>
+		<dict>
+			<key>buildSettings</key>
+			<dict>
+				<key>BUNDLE_LOADER</key>
+				<string>$(TEST_HOST)</string>
+				<key>FRAMEWORK_SEARCH_PATHS</key>
+				<array>
+					<string>$(SDKROOT)/Developer/Library/Frameworks</string>
+					<string>$(inherited)</string>
+				</array>
+				<key>INFOPLIST_FILE</key>
+				<string>SampleTests/Info.plist</string>
+				<key>LD_RUNPATH_SEARCH_PATHS</key>
+				<string>$(inherited) @executable_path/Frameworks @loader_path/Frameworks</string>
+				<key>PRODUCT_NAME</key>
+				<string>$(TARGET_NAME)</string>
+				<key>TEST_HOST</key>
+				<string>$(BUILT_PRODUCTS_DIR)/Sample.app/Sample</string>
+			</dict>
+			<key>isa</key>
+			<string>XCBuildConfiguration</string>
+			<key>name</key>
+			<string>Release</string>
+		</dict>
+		<key>AB3331C9AE6488E61B2B094E</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>AC29DD6FCDF962F519FEBB0D</string>
+				<string>C68330F8D451CC6ACEABA09F</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Pods</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>AC29DD6FCDF962F519FEBB0D</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>name</key>
+			<string>Pods.debug.xcconfig</string>
+			<key>path</key>
+			<string>Pods/Target Support Files/Pods/Pods.debug.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>C4C2C5219053E079C9EFB930</key>
+		<dict>
+			<key>children</key>
+			<array>
+				<string>2DC7B7C4C0410F43B9621631</string>
+			</array>
+			<key>isa</key>
+			<string>PBXGroup</string>
+			<key>name</key>
+			<string>Frameworks</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>C68330F8D451CC6ACEABA09F</key>
+		<dict>
+			<key>includeInIndex</key>
+			<string>1</string>
+			<key>isa</key>
+			<string>PBXFileReference</string>
+			<key>lastKnownFileType</key>
+			<string>text.xcconfig</string>
+			<key>name</key>
+			<string>Pods.release.xcconfig</string>
+			<key>path</key>
+			<string>Pods/Target Support Files/Pods/Pods.release.xcconfig</string>
+			<key>sourceTree</key>
+			<string>&lt;group&gt;</string>
+		</dict>
+		<key>FC81FE63CA655031F3524EC0</key>
+		<dict>
+			<key>fileRef</key>
+			<string>2DC7B7C4C0410F43B9621631</string>
+			<key>isa</key>
+			<string>PBXBuildFile</string>
+		</dict>
+	</dict>
+	<key>rootObject</key>
+	<string>6369A2621A9322E20015FC5C</string>
+</dict>
+</plist>
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/src/objective-c/examples/Sample/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000000000000000000000000000000000..a80c038249587c0ccbc024376cd198dd085201ab
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:Sample.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/src/objective-c/examples/Sample/Sample.xcworkspace/contents.xcworkspacedata b/src/objective-c/examples/Sample/Sample.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000000000000000000000000000000000..7b5a2f3050a527698c6cd9cfc08a96b4ef83556d
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:Sample.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.h b/src/objective-c/examples/Sample/Sample/AppDelegate.h
new file mode 100644
index 0000000000000000000000000000000000000000..867e62842aecaf7cb061f3f363c3947b31b513c7
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.m b/src/objective-c/examples/Sample/Sample/AppDelegate.m
new file mode 100644
index 0000000000000000000000000000000000000000..66fceffd85cb40e55921fd0c5c2bca058ddcb7d7
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.m
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+  // Override point for customization after application launch.
+  return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+  // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+  // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+  // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+  // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+  // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+  // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+  // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/src/objective-c/examples/Sample/Sample/Base.lproj/LaunchScreen.xib b/src/objective-c/examples/Sample/Sample/Base.lproj/LaunchScreen.xib
new file mode 100644
index 0000000000000000000000000000000000000000..c51a8e199eb454ca06bcd9fb6d6b2d60e1d55f49
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/Base.lproj/LaunchScreen.xib
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2015 gRPC. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
+                    <rect key="frame" x="20" y="439" width="441" height="21"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sample" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
+                    <rect key="frame" x="20" y="140" width="441" height="43"/>
+                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+            <constraints>
+                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
+                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
+                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
+                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
+                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
+                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
+            </constraints>
+            <nil key="simulatedStatusBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="548" y="455"/>
+        </view>
+    </objects>
+</document>
diff --git a/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard b/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard
new file mode 100644
index 0000000000000000000000000000000000000000..f56d2f3bb56e8474d49393008be744986bd41c3c
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>
diff --git a/src/objective-c/examples/Sample/Sample/Images.xcassets/AppIcon.appiconset/Contents.json b/src/objective-c/examples/Sample/Sample/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000000000000000000000000000000000..36d2c80d8893178d7e1f2964085b273959bfdc28
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/src/objective-c/examples/Sample/Sample/Info.plist b/src/objective-c/examples/Sample/Sample/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..ffdc8b30122ff1eb90e0944e79feaaf9aefbf7f8
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/Info.plist
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.grpc.$(PRODUCT_NAME:rfc1034identifier)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIMainStoryboardFile</key>
+	<string>Main</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>
diff --git a/src/cpp/server/server_context_impl.cc b/src/objective-c/examples/Sample/Sample/ViewController.h
similarity index 92%
rename from src/cpp/server/server_context_impl.cc
rename to src/objective-c/examples/Sample/Sample/ViewController.h
index 467cc80e055ebc3f2de158794e774f6e5c1cb56c..38cd7f92b660a1ca327a66138f6c1d50e69dba69 100644
--- a/src/cpp/server/server_context_impl.cc
+++ b/src/objective-c/examples/Sample/Sample/ViewController.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,10 @@
  *
  */
 
-#include "src/cpp/server/server_context_impl.h"
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+
+
+@end
 
-namespace grpc {}  // namespace grpc
diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m
new file mode 100644
index 0000000000000000000000000000000000000000..70b5d45811051fdf1c89141debbc8f6e0b2b1392
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/ViewController.m
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "ViewController.h"
+
+@interface ViewController ()
+
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  // Do any additional setup after loading the view, typically from a nib.
+}
+
+- (void)didReceiveMemoryWarning {
+  [super didReceiveMemoryWarning];
+  // Dispose of any resources that can be recreated.
+}
+
+@end
diff --git a/src/objective-c/examples/Sample/Sample/main.m b/src/objective-c/examples/Sample/Sample/main.m
new file mode 100644
index 0000000000000000000000000000000000000000..81e9d44e542b264d8a6a48d78e3c2555b893eac3
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample/main.m
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+  @autoreleasepool {
+      return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+  }
+}
diff --git a/src/objective-c/examples/Sample/SampleTests/Info.plist b/src/objective-c/examples/Sample/SampleTests/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..f547b0b70726345b5530f7396813317802f44487
--- /dev/null
+++ b/src/objective-c/examples/Sample/SampleTests/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.grpc.$(PRODUCT_NAME:rfc1034identifier)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>
diff --git a/src/objective-c/examples/Sample/SampleTests/SampleTests.m b/src/objective-c/examples/Sample/SampleTests/SampleTests.m
new file mode 100644
index 0000000000000000000000000000000000000000..9a1d4b14d43b274c9a43a51906836459fdc7b6a7
--- /dev/null
+++ b/src/objective-c/examples/Sample/SampleTests/SampleTests.m
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+
+@interface SampleTests : XCTestCase
+
+@end
+
+@implementation SampleTests
+
+- (void)setUp {
+    [super setUp];
+    // Put setup code here. This method is called before the invocation of each test method in the class.
+}
+
+- (void)tearDown {
+    // Put teardown code here. This method is called after the invocation of each test method in the class.
+    [super tearDown];
+}
+
+- (void)testExample {
+    // This is an example of a functional test case.
+    XCTAssert(YES, @"Pass");
+}
+
+- (void)testPerformanceExample {
+    // This is an example of a performance test case.
+    [self measureBlock:^{
+        // Put the code you want to measure the time of here.
+    }];
+}
+
+@end
diff --git a/src/php/README.md b/src/php/README.md
index 620c68fd7b5feb7b0f4d5545f48d62117e082edc..40c79e0dd4003115c71234df4ea885c46df0ee71 100755
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -1,4 +1,12 @@
-# PHP wrapper for the GRPC interfaces.
+
+#Overview
+
+This directory contains source code for PHP implementation of gRPC layered on shared C library.
+
+#Status
+
+Pre-Alpha : This gRPC PHP implementation is work-in-progress and is not expected to work yet.
+
 
 ## LAYOUT
 
diff --git a/src/php/bin/interop_client.sh b/src/php/bin/interop_client.sh
index 2e2b12fd44402630287f60bb8857b76858a2a3f0..2c61ea8aa0980b9ac6e206524f32d8775b5c51b3 100755
--- a/src/php/bin/interop_client.sh
+++ b/src/php/bin/interop_client.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/php/bin/run_gen_code_test.sh b/src/php/bin/run_gen_code_test.sh
index f035a9ba7f0684eca0ab50fe3df1a744f394b29c..3f176fb5e4aad2d81195a07f680bf55d1e4a5d73 100755
--- a/src/php/bin/run_gen_code_test.sh
+++ b/src/php/bin/run_gen_code_test.sh
@@ -1,5 +1,5 @@
 # Runs the generated code test against the ruby server
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh
index b9946834e93b0413f38568b628504e7f3c3232a8..c3358ed899f8e4aee3cfb7d7a57d73d8267e3dd2 100755
--- a/src/php/bin/run_tests.sh
+++ b/src/php/bin/run_tests.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/php/tests/generated_code/math.php b/src/php/tests/generated_code/math.php
index d50f94e11c76166cd3d94e3ec39bbe9f648c9c54..e97a5cf97ebc48779b0abdbf9fa6d0da23153474 100755
--- a/src/php/tests/generated_code/math.php
+++ b/src/php/tests/generated_code/math.php
@@ -9,10 +9,10 @@ namespace math {
 
     /**  @var int */
     public $dividend = null;
-    
+
     /**  @var int */
     public $divisor = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -52,7 +52,7 @@ namespace math {
     public function hasDividend(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <dividend> value
      *
@@ -61,7 +61,7 @@ namespace math {
     public function clearDividend(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <dividend> value
      *
@@ -70,7 +70,7 @@ namespace math {
     public function getDividend(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <dividend> value
      *
@@ -80,7 +80,7 @@ namespace math {
     public function setDividend( $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <divisor> has a value
      *
@@ -89,7 +89,7 @@ namespace math {
     public function hasDivisor(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <divisor> value
      *
@@ -98,7 +98,7 @@ namespace math {
     public function clearDivisor(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <divisor> value
      *
@@ -107,7 +107,7 @@ namespace math {
     public function getDivisor(){
       return $this->_get(2);
     }
-    
+
     /**
      * Set <divisor> value
      *
@@ -126,10 +126,10 @@ namespace math {
 
     /**  @var int */
     public $quotient = null;
-    
+
     /**  @var int */
     public $remainder = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -169,7 +169,7 @@ namespace math {
     public function hasQuotient(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <quotient> value
      *
@@ -178,7 +178,7 @@ namespace math {
     public function clearQuotient(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <quotient> value
      *
@@ -187,7 +187,7 @@ namespace math {
     public function getQuotient(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <quotient> value
      *
@@ -197,7 +197,7 @@ namespace math {
     public function setQuotient( $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <remainder> has a value
      *
@@ -206,7 +206,7 @@ namespace math {
     public function hasRemainder(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <remainder> value
      *
@@ -215,7 +215,7 @@ namespace math {
     public function clearRemainder(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <remainder> value
      *
@@ -224,7 +224,7 @@ namespace math {
     public function getRemainder(){
       return $this->_get(2);
     }
-    
+
     /**
      * Set <remainder> value
      *
@@ -243,7 +243,7 @@ namespace math {
 
     /**  @var int */
     public $limit = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -275,7 +275,7 @@ namespace math {
     public function hasLimit(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <limit> value
      *
@@ -284,7 +284,7 @@ namespace math {
     public function clearLimit(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <limit> value
      *
@@ -293,7 +293,7 @@ namespace math {
     public function getLimit(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <limit> value
      *
@@ -312,7 +312,7 @@ namespace math {
 
     /**  @var int */
     public $num = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -344,7 +344,7 @@ namespace math {
     public function hasNum(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <num> value
      *
@@ -353,7 +353,7 @@ namespace math {
     public function clearNum(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <num> value
      *
@@ -362,7 +362,7 @@ namespace math {
     public function getNum(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <num> value
      *
@@ -381,7 +381,7 @@ namespace math {
 
     /**  @var int */
     public $count = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -413,7 +413,7 @@ namespace math {
     public function hasCount(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <count> value
      *
@@ -422,7 +422,7 @@ namespace math {
     public function clearCount(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <count> value
      *
@@ -431,7 +431,7 @@ namespace math {
     public function getCount(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <count> value
      *
diff --git a/src/php/tests/interop/messages.php b/src/php/tests/interop/messages.php
index 129c96fa136792ce7ea232553d27f0cad0ae0035..a626a17ab37779992748597cc752c9a549bd20c3 100755
--- a/src/php/tests/interop/messages.php
+++ b/src/php/tests/interop/messages.php
@@ -17,10 +17,10 @@ namespace grpc\testing {
 
     /**  @var int - \grpc\testing\PayloadType */
     public $type = null;
-    
+
     /**  @var string */
     public $body = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -61,7 +61,7 @@ namespace grpc\testing {
     public function hasType(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <type> value
      *
@@ -70,7 +70,7 @@ namespace grpc\testing {
     public function clearType(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <type> value
      *
@@ -79,7 +79,7 @@ namespace grpc\testing {
     public function getType(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <type> value
      *
@@ -89,7 +89,7 @@ namespace grpc\testing {
     public function setType( $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <body> has a value
      *
@@ -98,7 +98,7 @@ namespace grpc\testing {
     public function hasBody(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <body> value
      *
@@ -107,7 +107,7 @@ namespace grpc\testing {
     public function clearBody(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <body> value
      *
@@ -116,7 +116,7 @@ namespace grpc\testing {
     public function getBody(){
       return $this->_get(2);
     }
-    
+
     /**
      * Set <body> value
      *
@@ -135,19 +135,19 @@ namespace grpc\testing {
 
     /**  @var int - \grpc\testing\PayloadType */
     public $response_type = null;
-    
+
     /**  @var int */
     public $response_size = null;
-    
+
     /**  @var \grpc\testing\Payload */
     public $payload = null;
-    
+
     /**  @var boolean */
     public $fill_username = null;
-    
+
     /**  @var boolean */
     public $fill_oauth_scope = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -213,7 +213,7 @@ namespace grpc\testing {
     public function hasResponseType(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <response_type> value
      *
@@ -222,7 +222,7 @@ namespace grpc\testing {
     public function clearResponseType(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <response_type> value
      *
@@ -231,7 +231,7 @@ namespace grpc\testing {
     public function getResponseType(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <response_type> value
      *
@@ -241,7 +241,7 @@ namespace grpc\testing {
     public function setResponseType( $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <response_size> has a value
      *
@@ -250,7 +250,7 @@ namespace grpc\testing {
     public function hasResponseSize(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <response_size> value
      *
@@ -259,7 +259,7 @@ namespace grpc\testing {
     public function clearResponseSize(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <response_size> value
      *
@@ -268,7 +268,7 @@ namespace grpc\testing {
     public function getResponseSize(){
       return $this->_get(2);
     }
-    
+
     /**
      * Set <response_size> value
      *
@@ -278,7 +278,7 @@ namespace grpc\testing {
     public function setResponseSize( $value){
       return $this->_set(2, $value);
     }
-    
+
     /**
      * Check if <payload> has a value
      *
@@ -287,7 +287,7 @@ namespace grpc\testing {
     public function hasPayload(){
       return $this->_has(3);
     }
-    
+
     /**
      * Clear <payload> value
      *
@@ -296,7 +296,7 @@ namespace grpc\testing {
     public function clearPayload(){
       return $this->_clear(3);
     }
-    
+
     /**
      * Get <payload> value
      *
@@ -305,7 +305,7 @@ namespace grpc\testing {
     public function getPayload(){
       return $this->_get(3);
     }
-    
+
     /**
      * Set <payload> value
      *
@@ -315,7 +315,7 @@ namespace grpc\testing {
     public function setPayload(\grpc\testing\Payload $value){
       return $this->_set(3, $value);
     }
-    
+
     /**
      * Check if <fill_username> has a value
      *
@@ -324,7 +324,7 @@ namespace grpc\testing {
     public function hasFillUsername(){
       return $this->_has(4);
     }
-    
+
     /**
      * Clear <fill_username> value
      *
@@ -333,7 +333,7 @@ namespace grpc\testing {
     public function clearFillUsername(){
       return $this->_clear(4);
     }
-    
+
     /**
      * Get <fill_username> value
      *
@@ -342,7 +342,7 @@ namespace grpc\testing {
     public function getFillUsername(){
       return $this->_get(4);
     }
-    
+
     /**
      * Set <fill_username> value
      *
@@ -352,7 +352,7 @@ namespace grpc\testing {
     public function setFillUsername( $value){
       return $this->_set(4, $value);
     }
-    
+
     /**
      * Check if <fill_oauth_scope> has a value
      *
@@ -361,7 +361,7 @@ namespace grpc\testing {
     public function hasFillOauthScope(){
       return $this->_has(5);
     }
-    
+
     /**
      * Clear <fill_oauth_scope> value
      *
@@ -370,7 +370,7 @@ namespace grpc\testing {
     public function clearFillOauthScope(){
       return $this->_clear(5);
     }
-    
+
     /**
      * Get <fill_oauth_scope> value
      *
@@ -379,7 +379,7 @@ namespace grpc\testing {
     public function getFillOauthScope(){
       return $this->_get(5);
     }
-    
+
     /**
      * Set <fill_oauth_scope> value
      *
@@ -398,13 +398,13 @@ namespace grpc\testing {
 
     /**  @var \grpc\testing\Payload */
     public $payload = null;
-    
+
     /**  @var string */
     public $username = null;
-    
+
     /**  @var string */
     public $oauth_scope = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -453,7 +453,7 @@ namespace grpc\testing {
     public function hasPayload(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <payload> value
      *
@@ -462,7 +462,7 @@ namespace grpc\testing {
     public function clearPayload(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <payload> value
      *
@@ -471,7 +471,7 @@ namespace grpc\testing {
     public function getPayload(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <payload> value
      *
@@ -481,7 +481,7 @@ namespace grpc\testing {
     public function setPayload(\grpc\testing\Payload $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <username> has a value
      *
@@ -490,7 +490,7 @@ namespace grpc\testing {
     public function hasUsername(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <username> value
      *
@@ -499,7 +499,7 @@ namespace grpc\testing {
     public function clearUsername(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <username> value
      *
@@ -508,7 +508,7 @@ namespace grpc\testing {
     public function getUsername(){
       return $this->_get(2);
     }
-    
+
     /**
      * Set <username> value
      *
@@ -518,7 +518,7 @@ namespace grpc\testing {
     public function setUsername( $value){
       return $this->_set(2, $value);
     }
-    
+
     /**
      * Check if <oauth_scope> has a value
      *
@@ -527,7 +527,7 @@ namespace grpc\testing {
     public function hasOauthScope(){
       return $this->_has(3);
     }
-    
+
     /**
      * Clear <oauth_scope> value
      *
@@ -536,7 +536,7 @@ namespace grpc\testing {
     public function clearOauthScope(){
       return $this->_clear(3);
     }
-    
+
     /**
      * Get <oauth_scope> value
      *
@@ -545,7 +545,7 @@ namespace grpc\testing {
     public function getOauthScope(){
       return $this->_get(3);
     }
-    
+
     /**
      * Set <oauth_scope> value
      *
@@ -564,7 +564,7 @@ namespace grpc\testing {
 
     /**  @var \grpc\testing\Payload */
     public $payload = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -597,7 +597,7 @@ namespace grpc\testing {
     public function hasPayload(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <payload> value
      *
@@ -606,7 +606,7 @@ namespace grpc\testing {
     public function clearPayload(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <payload> value
      *
@@ -615,7 +615,7 @@ namespace grpc\testing {
     public function getPayload(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <payload> value
      *
@@ -634,7 +634,7 @@ namespace grpc\testing {
 
     /**  @var int */
     public $aggregated_payload_size = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -666,7 +666,7 @@ namespace grpc\testing {
     public function hasAggregatedPayloadSize(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <aggregated_payload_size> value
      *
@@ -675,7 +675,7 @@ namespace grpc\testing {
     public function clearAggregatedPayloadSize(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <aggregated_payload_size> value
      *
@@ -684,7 +684,7 @@ namespace grpc\testing {
     public function getAggregatedPayloadSize(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <aggregated_payload_size> value
      *
@@ -703,10 +703,10 @@ namespace grpc\testing {
 
     /**  @var int */
     public $size = null;
-    
+
     /**  @var int */
     public $interval_us = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -746,7 +746,7 @@ namespace grpc\testing {
     public function hasSize(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <size> value
      *
@@ -755,7 +755,7 @@ namespace grpc\testing {
     public function clearSize(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <size> value
      *
@@ -764,7 +764,7 @@ namespace grpc\testing {
     public function getSize(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <size> value
      *
@@ -774,7 +774,7 @@ namespace grpc\testing {
     public function setSize( $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <interval_us> has a value
      *
@@ -783,7 +783,7 @@ namespace grpc\testing {
     public function hasIntervalUs(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <interval_us> value
      *
@@ -792,7 +792,7 @@ namespace grpc\testing {
     public function clearIntervalUs(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <interval_us> value
      *
@@ -801,7 +801,7 @@ namespace grpc\testing {
     public function getIntervalUs(){
       return $this->_get(2);
     }
-    
+
     /**
      * Set <interval_us> value
      *
@@ -820,13 +820,13 @@ namespace grpc\testing {
 
     /**  @var int - \grpc\testing\PayloadType */
     public $response_type = null;
-    
+
     /**  @var \grpc\testing\ResponseParameters[]  */
     public $response_parameters = array();
-    
+
     /**  @var \grpc\testing\Payload */
     public $payload = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -877,7 +877,7 @@ namespace grpc\testing {
     public function hasResponseType(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <response_type> value
      *
@@ -886,7 +886,7 @@ namespace grpc\testing {
     public function clearResponseType(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <response_type> value
      *
@@ -895,7 +895,7 @@ namespace grpc\testing {
     public function getResponseType(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <response_type> value
      *
@@ -905,7 +905,7 @@ namespace grpc\testing {
     public function setResponseType( $value){
       return $this->_set(1, $value);
     }
-    
+
     /**
      * Check if <response_parameters> has a value
      *
@@ -914,7 +914,7 @@ namespace grpc\testing {
     public function hasResponseParameters(){
       return $this->_has(2);
     }
-    
+
     /**
      * Clear <response_parameters> value
      *
@@ -923,7 +923,7 @@ namespace grpc\testing {
     public function clearResponseParameters(){
       return $this->_clear(2);
     }
-    
+
     /**
      * Get <response_parameters> value
      *
@@ -933,7 +933,7 @@ namespace grpc\testing {
     public function getResponseParameters($idx = NULL){
       return $this->_get(2, $idx);
     }
-    
+
     /**
      * Set <response_parameters> value
      *
@@ -943,7 +943,7 @@ namespace grpc\testing {
     public function setResponseParameters(\grpc\testing\ResponseParameters $value, $idx = NULL){
       return $this->_set(2, $value, $idx);
     }
-    
+
     /**
      * Get all elements of <response_parameters>
      *
@@ -952,7 +952,7 @@ namespace grpc\testing {
     public function getResponseParametersList(){
      return $this->_get(2);
     }
-    
+
     /**
      * Add a new element to <response_parameters>
      *
@@ -962,7 +962,7 @@ namespace grpc\testing {
     public function addResponseParameters(\grpc\testing\ResponseParameters $value){
      return $this->_add(2, $value);
     }
-    
+
     /**
      * Check if <payload> has a value
      *
@@ -971,7 +971,7 @@ namespace grpc\testing {
     public function hasPayload(){
       return $this->_has(3);
     }
-    
+
     /**
      * Clear <payload> value
      *
@@ -980,7 +980,7 @@ namespace grpc\testing {
     public function clearPayload(){
       return $this->_clear(3);
     }
-    
+
     /**
      * Get <payload> value
      *
@@ -989,7 +989,7 @@ namespace grpc\testing {
     public function getPayload(){
       return $this->_get(3);
     }
-    
+
     /**
      * Set <payload> value
      *
@@ -1008,7 +1008,7 @@ namespace grpc\testing {
 
     /**  @var \grpc\testing\Payload */
     public $payload = null;
-    
+
 
     /** @var \Closure[] */
     protected static $__extensions = array();
@@ -1041,7 +1041,7 @@ namespace grpc\testing {
     public function hasPayload(){
       return $this->_has(1);
     }
-    
+
     /**
      * Clear <payload> value
      *
@@ -1050,7 +1050,7 @@ namespace grpc\testing {
     public function clearPayload(){
       return $this->_clear(1);
     }
-    
+
     /**
      * Get <payload> value
      *
@@ -1059,7 +1059,7 @@ namespace grpc\testing {
     public function getPayload(){
       return $this->_get(1);
     }
-    
+
     /**
      * Set <payload> value
      *
diff --git a/src/python/README.md b/src/python/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..be2f2bedf9cae7e4599d1559e926042026c512b2
--- /dev/null
+++ b/src/python/README.md
@@ -0,0 +1,34 @@
+GRPC Python
+=========
+
+The Python facility of GRPC.
+
+
+Prerequisites
+-----------------------
+
+Python 2.7, virtualenv, pip, libprotobuf-dev, and libprotoc-dev.
+
+
+Building from source
+----------------------
+
+- Build the GRPC core
+E.g, from the root of the grpc [git repo](https://github.com/google/grpc)
+```
+$ make shared_c static_c
+```
+
+- Use build_python.sh to build the Python code and install it into a virtual environment
+```
+$ tools/run_tests/build_python.sh
+```
+
+
+Testing
+-----------------------
+
+- Use run_python.sh to run GRPC as it was installed into the virtual environment
+```
+$ tools/run_tests/run_python.sh
+```
diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py
index 854dbec8cc396ef15e514295db5dd12b7ceebbd0..26c1869f93e675d29150236216f2b620c4963d20 100644
--- a/src/python/interop/interop/methods.py
+++ b/src/python/interop/interop/methods.py
@@ -37,9 +37,11 @@ from interop import messages_pb2
 def _empty_call(request):
   return empty_pb2.Empty()
 
-EMPTY_CALL = utilities.unary_unary_rpc_method(
-    _empty_call, empty_pb2.Empty.SerializeToString, empty_pb2.Empty.FromString,
+_CLIENT_EMPTY_CALL = utilities.unary_unary_client_rpc_method(
     empty_pb2.Empty.SerializeToString, empty_pb2.Empty.FromString)
+_SERVER_EMPTY_CALL = utilities.unary_unary_server_rpc_method(
+    _empty_call, empty_pb2.Empty.FromString,
+    empty_pb2.Empty.SerializeToString)
 
 
 def _unary_call(request):
@@ -48,11 +50,12 @@ def _unary_call(request):
           type=messages_pb2.COMPRESSABLE,
           body=b'\x00' * request.response_size))
 
-UNARY_CALL = utilities.unary_unary_rpc_method(
-    _unary_call, messages_pb2.SimpleRequest.SerializeToString,
-    messages_pb2.SimpleRequest.FromString,
-    messages_pb2.SimpleResponse.SerializeToString,
+_CLIENT_UNARY_CALL = utilities.unary_unary_client_rpc_method(
+    messages_pb2.SimpleRequest.SerializeToString,
     messages_pb2.SimpleResponse.FromString)
+_SERVER_UNARY_CALL = utilities.unary_unary_server_rpc_method(
+    _unary_call, messages_pb2.SimpleRequest.FromString,
+    messages_pb2.SimpleResponse.SerializeToString)
 
 
 def _streaming_output_call(request):
@@ -62,12 +65,13 @@ def _streaming_output_call(request):
             type=request.response_type,
             body=b'\x00' * response_parameters.size))
 
-STREAMING_OUTPUT_CALL = utilities.unary_stream_rpc_method(
-    _streaming_output_call,
+_CLIENT_STREAMING_OUTPUT_CALL = utilities.unary_stream_client_rpc_method(
     messages_pb2.StreamingOutputCallRequest.SerializeToString,
-    messages_pb2.StreamingOutputCallRequest.FromString,
-    messages_pb2.StreamingOutputCallResponse.SerializeToString,
     messages_pb2.StreamingOutputCallResponse.FromString)
+_SERVER_STREAMING_OUTPUT_CALL = utilities.unary_stream_server_rpc_method(
+    _streaming_output_call,
+    messages_pb2.StreamingOutputCallRequest.FromString,
+    messages_pb2.StreamingOutputCallResponse.SerializeToString)
 
 
 def _streaming_input_call(request_iterator):
@@ -78,12 +82,13 @@ def _streaming_input_call(request_iterator):
   return messages_pb2.StreamingInputCallResponse(
       aggregated_payload_size=aggregate_size)
 
-STREAMING_INPUT_CALL = utilities.stream_unary_rpc_method(
-    _streaming_input_call,
+_CLIENT_STREAMING_INPUT_CALL = utilities.stream_unary_client_rpc_method(
     messages_pb2.StreamingInputCallRequest.SerializeToString,
-    messages_pb2.StreamingInputCallRequest.FromString,
-    messages_pb2.StreamingInputCallResponse.SerializeToString,
     messages_pb2.StreamingInputCallResponse.FromString)
+_SERVER_STREAMING_INPUT_CALL = utilities.stream_unary_server_rpc_method(
+    _streaming_input_call,
+    messages_pb2.StreamingInputCallRequest.FromString,
+    messages_pb2.StreamingInputCallResponse.SerializeToString)
 
 
 def _full_duplex_call(request_iterator):
@@ -93,17 +98,47 @@ def _full_duplex_call(request_iterator):
             type=request.payload.type,
             body=b'\x00' * request.response_parameters[0].size))
 
-FULL_DUPLEX_CALL = utilities.stream_stream_rpc_method(
-    _full_duplex_call,
+_CLIENT_FULL_DUPLEX_CALL = utilities.stream_stream_client_rpc_method(
     messages_pb2.StreamingOutputCallRequest.SerializeToString,
-    messages_pb2.StreamingOutputCallRequest.FromString,
-    messages_pb2.StreamingOutputCallResponse.SerializeToString,
     messages_pb2.StreamingOutputCallResponse.FromString)
+_SERVER_FULL_DUPLEX_CALL = utilities.stream_stream_server_rpc_method(
+    _full_duplex_call,
+    messages_pb2.StreamingOutputCallRequest.FromString,
+    messages_pb2.StreamingOutputCallResponse.SerializeToString)
 
 # NOTE(nathaniel): Apparently this is the same as the full-duplex call?
-HALF_DUPLEX_CALL = utilities.stream_stream_rpc_method(
-    _full_duplex_call,
+_CLIENT_HALF_DUPLEX_CALL = utilities.stream_stream_client_rpc_method(
     messages_pb2.StreamingOutputCallRequest.SerializeToString,
-    messages_pb2.StreamingOutputCallRequest.FromString,
-    messages_pb2.StreamingOutputCallResponse.SerializeToString,
     messages_pb2.StreamingOutputCallResponse.FromString)
+_SERVER_HALF_DUPLEX_CALL = utilities.stream_stream_server_rpc_method(
+    _full_duplex_call,
+    messages_pb2.StreamingOutputCallRequest.FromString,
+    messages_pb2.StreamingOutputCallResponse.SerializeToString)
+
+
+_SERVICE_NAME = '/grpc.testing.TestService'
+
+EMPTY_CALL_METHOD_NAME = _SERVICE_NAME + '/EmptyCall'
+UNARY_CALL_METHOD_NAME = _SERVICE_NAME + '/UnaryCall'
+STREAMING_OUTPUT_CALL_METHOD_NAME = _SERVICE_NAME + '/StreamingOutputCall'
+STREAMING_INPUT_CALL_METHOD_NAME = _SERVICE_NAME + '/StreamingInputCall'
+FULL_DUPLEX_CALL_METHOD_NAME = _SERVICE_NAME + '/FullDuplexCall'
+HALF_DUPLEX_CALL_METHOD_NAME = _SERVICE_NAME + '/HalfDuplexCall'
+
+CLIENT_METHODS = {
+    EMPTY_CALL_METHOD_NAME: _CLIENT_EMPTY_CALL,
+    UNARY_CALL_METHOD_NAME: _CLIENT_UNARY_CALL,
+    STREAMING_OUTPUT_CALL_METHOD_NAME: _CLIENT_STREAMING_OUTPUT_CALL,
+    STREAMING_INPUT_CALL_METHOD_NAME: _CLIENT_STREAMING_INPUT_CALL,
+    FULL_DUPLEX_CALL_METHOD_NAME: _CLIENT_FULL_DUPLEX_CALL,
+    HALF_DUPLEX_CALL_METHOD_NAME: _CLIENT_HALF_DUPLEX_CALL,
+}
+
+SERVER_METHODS = {
+    EMPTY_CALL_METHOD_NAME: _SERVER_EMPTY_CALL,
+    UNARY_CALL_METHOD_NAME: _SERVER_UNARY_CALL,
+    STREAMING_OUTPUT_CALL_METHOD_NAME: _SERVER_STREAMING_OUTPUT_CALL,
+    STREAMING_INPUT_CALL_METHOD_NAME: _SERVER_STREAMING_INPUT_CALL,
+    FULL_DUPLEX_CALL_METHOD_NAME: _SERVER_FULL_DUPLEX_CALL,
+    HALF_DUPLEX_CALL_METHOD_NAME: _SERVER_HALF_DUPLEX_CALL,
+}
diff --git a/src/python/interop/interop/server.py b/src/python/interop/interop/server.py
index 0035e062a4eee242662459dd5e0452692d0045e6..785d482fe59bfc91f8b10b97d407b0a9ab2e514d 100644
--- a/src/python/interop/interop/server.py
+++ b/src/python/interop/interop/server.py
@@ -43,19 +43,6 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
 _PRIVATE_KEY_RESOURCE_PATH = 'credentials/server1.key'
 _CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem'
 
-_METHODS = {
-    '/grpc.testing.TestService/EmptyCall': methods.EMPTY_CALL,
-    '/grpc.testing.TestService/UnaryCall': methods.UNARY_CALL,
-    '/grpc.testing.TestService/StreamingOutputCall':
-        methods.STREAMING_OUTPUT_CALL,
-    '/grpc.testing.TestService/StreamingInputCall':
-        methods.STREAMING_INPUT_CALL,
-    '/grpc.testing.TestService/FullDuplexCall':
-        methods.FULL_DUPLEX_CALL,
-    '/grpc.testing.TestService/HalfDuplexCall':
-        methods.HALF_DUPLEX_CALL,
-}
-
 
 def serve():
   parser = argparse.ArgumentParser()
@@ -72,10 +59,10 @@ def serve():
     certificate_chain = pkg_resources.resource_string(
         __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH)
     server = implementations.secure_server(
-        _METHODS, args.port, private_key, certificate_chain)
+        methods.SERVER_METHODS, args.port, private_key, certificate_chain)
   else:
     server = implementations.insecure_server(
-        _METHODS, args.port)
+        methods.SERVER_METHODS, args.port)
 
   server.start()
   logging.info('Server serving.')
diff --git a/src/python/src/grpc/_adapter/_c.c b/src/python/src/grpc/_adapter/_c.c
index 13eb93fe5ab17dafd7a45f100d677f6fd2a8e83e..55b9d0512c99fec3f673d9cdc6d7003876cf0a4c 100644
--- a/src/python/src/grpc/_adapter/_c.c
+++ b/src/python/src/grpc/_adapter/_c.c
@@ -40,19 +40,20 @@
 #include "grpc/_adapter/_server.h"
 #include "grpc/_adapter/_server_credentials.h"
 
-static PyObject *init(PyObject *self, PyObject *args) {
+static PyObject *init(PyObject *self) {
   grpc_init();
   Py_RETURN_NONE;
 }
 
-static PyObject *shutdown(PyObject *self, PyObject *args) {
+static PyObject *shutdown(PyObject *self) {
   grpc_shutdown();
   Py_RETURN_NONE;
 }
 
 static PyMethodDef _c_methods[] = {
-    {"init", init, METH_VARARGS, "Initialize the module's static state."},
-    {"shut_down", shutdown, METH_VARARGS,
+    {"init", (PyCFunction)init, METH_NOARGS,
+     "Initialize the module's static state."},
+    {"shut_down", (PyCFunction)shutdown, METH_NOARGS,
      "Shut down the module's static state."},
     {NULL},
 };
diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c
index a2cc590d28be3a088b8bf37d339ce19fb08cc816..325d3d5bbd6c12630437d9a6920e26f6d84da765 100644
--- a/src/python/src/grpc/_adapter/_call.c
+++ b/src/python/src/grpc/_adapter/_call.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,10 +46,11 @@ static int pygrpc_call_init(Call *self, PyObject *args, PyObject *kwds) {
   const char *method;
   const char *host;
   const double deadline;
+  static char *kwlist[] = {"channel", "method", "host", "deadline", NULL};
 
-  if (!PyArg_ParseTuple(args, "O!ssd", &pygrpc_ChannelType, &channel, &method,
-                        &host, &deadline)) {
-    self->c_call = NULL;
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!ssd:Call", kwlist,
+                                   &pygrpc_ChannelType, &channel, &method,
+                                   &host, &deadline)) {
     return -1;
   }
 
@@ -77,7 +78,7 @@ static const PyObject *pygrpc_call_invoke(Call *self, PyObject *args) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "O!OO", &pygrpc_CompletionQueueType,
+  if (!(PyArg_ParseTuple(args, "O!OO:invoke", &pygrpc_CompletionQueueType,
                          &completion_queue, &metadata_tag, &finish_tag))) {
     return NULL;
   }
@@ -103,7 +104,7 @@ static const PyObject *pygrpc_call_write(Call *self, PyObject *args) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "s#O", &bytes, &length, &tag))) {
+  if (!(PyArg_ParseTuple(args, "s#O:write", &bytes, &length, &tag))) {
     return NULL;
   }
 
@@ -123,15 +124,10 @@ static const PyObject *pygrpc_call_write(Call *self, PyObject *args) {
   return result;
 }
 
-static const PyObject *pygrpc_call_complete(Call *self, PyObject *args) {
-  const PyObject *tag;
+static const PyObject *pygrpc_call_complete(Call *self, PyObject *tag) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "O", &tag))) {
-    return NULL;
-  }
-
   call_error = grpc_call_writes_done_old(self->c_call, (void *)tag);
 
   result = pygrpc_translate_call_error(call_error);
@@ -147,7 +143,7 @@ static const PyObject *pygrpc_call_accept(Call *self, PyObject *args) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "O!O", &pygrpc_CompletionQueueType,
+  if (!(PyArg_ParseTuple(args, "O!O:accept", &pygrpc_CompletionQueueType,
                          &completion_queue, &tag))) {
     return NULL;
   }
@@ -164,21 +160,16 @@ static const PyObject *pygrpc_call_accept(Call *self, PyObject *args) {
   return result;
 }
 
-static const PyObject *pygrpc_call_premetadata(Call *self, PyObject *args) {
+static const PyObject *pygrpc_call_premetadata(Call *self) {
   /* TODO(b/18702680): Actually support metadata. */
   return pygrpc_translate_call_error(
       grpc_call_server_end_initial_metadata_old(self->c_call, 0));
 }
 
-static const PyObject *pygrpc_call_read(Call *self, PyObject *args) {
-  const PyObject *tag;
+static const PyObject *pygrpc_call_read(Call *self, PyObject *tag) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "O", &tag))) {
-    return NULL;
-  }
-
   call_error = grpc_call_start_read_old(self->c_call, (void *)tag);
 
   result = pygrpc_translate_call_error(call_error);
@@ -198,16 +189,30 @@ static const PyObject *pygrpc_call_status(Call *self, PyObject *args) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "OO", &status, &tag))) {
+  if (!(PyArg_ParseTuple(args, "OO:status", &status, &tag))) {
     return NULL;
   }
 
   code = PyObject_GetAttrString(status, "code");
+  if (code == NULL) {
+    return NULL;
+  }
   details = PyObject_GetAttrString(status, "details");
+  if (details == NULL) {
+    Py_DECREF(code);
+    return NULL;
+  }
   c_code = PyInt_AsLong(code);
-  c_message = PyBytes_AsString(details);
   Py_DECREF(code);
+  if (c_code == -1 && PyErr_Occurred()) {
+    Py_DECREF(details);
+    return NULL;
+  }
+  c_message = PyBytes_AsString(details);
   Py_DECREF(details);
+  if (c_message == NULL) {
+    return NULL;
+  }
 
   call_error = grpc_call_start_write_status_old(self->c_call, c_code, c_message,
                                                 (void *)tag);
@@ -228,12 +233,12 @@ static PyMethodDef methods[] = {
      "Invoke this call."},
     {"write", (PyCFunction)pygrpc_call_write, METH_VARARGS,
      "Write bytes to this call."},
-    {"complete", (PyCFunction)pygrpc_call_complete, METH_VARARGS,
+    {"complete", (PyCFunction)pygrpc_call_complete, METH_O,
      "Complete writes to this call."},
     {"accept", (PyCFunction)pygrpc_call_accept, METH_VARARGS, "Accept an RPC."},
     {"premetadata", (PyCFunction)pygrpc_call_premetadata, METH_VARARGS,
      "Indicate the end of leading metadata in the response."},
-    {"read", (PyCFunction)pygrpc_call_read, METH_VARARGS,
+    {"read", (PyCFunction)pygrpc_call_read, METH_O,
      "Read bytes from this call."},
     {"status", (PyCFunction)pygrpc_call_status, METH_VARARGS,
      "Report this call's status."},
@@ -242,7 +247,7 @@ static PyMethodDef methods[] = {
     {NULL}};
 
 PyTypeObject pygrpc_CallType = {
-    PyObject_HEAD_INIT(NULL)0,       /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_grpc.Call",                    /*tp_name*/
     sizeof(Call),                    /*tp_basicsize*/
     0,                               /*tp_itemsize*/
@@ -278,16 +283,16 @@ PyTypeObject pygrpc_CallType = {
     0,                               /* tp_descr_set */
     0,                               /* tp_dictoffset */
     (initproc)pygrpc_call_init,      /* tp_init */
+    0,                               /* tp_alloc */
+    PyType_GenericNew,               /* tp_new */
 };
 
 int pygrpc_add_call(PyObject *module) {
-  pygrpc_CallType.tp_new = PyType_GenericNew;
   if (PyType_Ready(&pygrpc_CallType) < 0) {
-    PyErr_SetString(PyExc_RuntimeError, "Error defining pygrpc_CallType!");
     return -1;
   }
   if (PyModule_AddObject(module, "Call", (PyObject *)&pygrpc_CallType) == -1) {
-    PyErr_SetString(PyExc_ImportError, "Couldn't add Call type to module!");
+    return -1;
   }
   return 0;
 }
diff --git a/src/python/src/grpc/_adapter/_channel.c b/src/python/src/grpc/_adapter/_channel.c
index 6962722ed253602a95a30e23d96bb148cd04137f..3ba943e4b2d0f1f34ab4e6d7351f4d22fd75c5c5 100644
--- a/src/python/src/grpc/_adapter/_channel.c
+++ b/src/python/src/grpc/_adapter/_channel.c
@@ -38,9 +38,10 @@
 
 static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) {
   const char *hostport;
+  static char *kwlist[] = {"hostport", NULL};
 
-  if (!(PyArg_ParseTuple(args, "s", &hostport))) {
-    self->c_channel = NULL;
+  if (!(PyArg_ParseTupleAndKeywords(args, kwds, "s:Channel", kwlist,
+                                    &hostport))) {
     return -1;
   }
 
@@ -56,7 +57,7 @@ static void pygrpc_channel_dealloc(Channel *self) {
 }
 
 PyTypeObject pygrpc_ChannelType = {
-    PyObject_HEAD_INIT(NULL)0,          /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_grpc.Channel",                    /*tp_name*/
     sizeof(Channel),                    /*tp_basicsize*/
     0,                                  /*tp_itemsize*/
@@ -92,17 +93,16 @@ PyTypeObject pygrpc_ChannelType = {
     0,                                  /* tp_descr_set */
     0,                                  /* tp_dictoffset */
     (initproc)pygrpc_channel_init,      /* tp_init */
+    0,                                  /* tp_alloc */
+    PyType_GenericNew,                  /* tp_new */
 };
 
 int pygrpc_add_channel(PyObject *module) {
-  pygrpc_ChannelType.tp_new = PyType_GenericNew;
   if (PyType_Ready(&pygrpc_ChannelType) < 0) {
-    PyErr_SetString(PyExc_RuntimeError, "Error defining pygrpc_ChannelType!");
     return -1;
   }
   if (PyModule_AddObject(module, "Channel", (PyObject *)&pygrpc_ChannelType) ==
       -1) {
-    PyErr_SetString(PyExc_ImportError, "Couldn't add Channel type to module!");
     return -1;
   }
   return 0;
diff --git a/src/python/src/grpc/_adapter/_completion_queue.c b/src/python/src/grpc/_adapter/_completion_queue.c
index 1d593d0d1401448640240fd979888ff317eae4a6..b56ca1926e5b6602b6a01192119f41815aaa8a24 100644
--- a/src/python/src/grpc/_adapter/_completion_queue.c
+++ b/src/python/src/grpc/_adapter/_completion_queue.c
@@ -70,7 +70,7 @@ static PyObject *metadata_event_kind;
 static PyObject *finish_event_kind;
 
 static PyObject *pygrpc_as_py_time(gpr_timespec *timespec) {
-  return Py_BuildValue("f",
+  return PyFloat_FromDouble(
                        timespec->tv_sec + ((double)timespec->tv_nsec) / 1.0E9);
 }
 
@@ -116,67 +116,82 @@ static PyObject *pygrpc_status_code(grpc_status_code c_status_code) {
 }
 
 static PyObject *pygrpc_stop_event_args(grpc_event *c_event) {
-  return Py_BuildValue("(OOOOOOO)", stop_event_kind, Py_None, Py_None, Py_None,
-                       Py_None, Py_None, Py_None);
+  return PyTuple_Pack(7, stop_event_kind, Py_None, Py_None, Py_None,
+                      Py_None, Py_None, Py_None);
 }
 
 static PyObject *pygrpc_write_event_args(grpc_event *c_event) {
   PyObject *write_accepted =
       c_event->data.write_accepted == GRPC_OP_OK ? Py_True : Py_False;
-  return Py_BuildValue("(OOOOOOO)", write_event_kind, (PyObject *)c_event->tag,
-                       write_accepted, Py_None, Py_None, Py_None, Py_None);
+  return PyTuple_Pack(7, write_event_kind, (PyObject *)c_event->tag,
+                      write_accepted, Py_None, Py_None, Py_None, Py_None);
 }
 
 static PyObject *pygrpc_complete_event_args(grpc_event *c_event) {
   PyObject *complete_accepted =
       c_event->data.finish_accepted == GRPC_OP_OK ? Py_True : Py_False;
-  return Py_BuildValue("(OOOOOOO)", complete_event_kind,
-                       (PyObject *)c_event->tag, Py_None, complete_accepted,
-                       Py_None, Py_None, Py_None);
+  return PyTuple_Pack(7, complete_event_kind, (PyObject *)c_event->tag,
+                      Py_None, complete_accepted, Py_None, Py_None, Py_None);
 }
 
 static PyObject *pygrpc_service_event_args(grpc_event *c_event) {
   if (c_event->data.server_rpc_new.method == NULL) {
-    return Py_BuildValue("(OOOOOOO)", service_event_kind, c_event->tag,
-                         Py_None, Py_None, Py_None, Py_None, Py_None);
+    return PyTuple_Pack(7, service_event_kind, c_event->tag,
+                        Py_None, Py_None, Py_None, Py_None, Py_None);
   } else {
-    PyObject *method = PyBytes_FromString(c_event->data.server_rpc_new.method);
-    PyObject *host = PyBytes_FromString(c_event->data.server_rpc_new.host);
-    PyObject *service_deadline =
+    PyObject *method = NULL;
+    PyObject *host = NULL;
+    PyObject *service_deadline = NULL;
+    Call *call = NULL;
+    PyObject *service_acceptance = NULL;
+    PyObject *event_args = NULL;
+
+    method = PyBytes_FromString(c_event->data.server_rpc_new.method);
+    if (method == NULL) {
+      goto error;
+    }
+    host = PyBytes_FromString(c_event->data.server_rpc_new.host);
+    if (host == NULL) {
+      goto error;
+    }
+    service_deadline =
         pygrpc_as_py_time(&c_event->data.server_rpc_new.deadline);
-
-    Call *call;
-    PyObject *service_acceptance_args;
-    PyObject *service_acceptance;
-    PyObject *event_args;
+    if (service_deadline == NULL) {
+      goto error;
+    }
 
     call = PyObject_New(Call, &pygrpc_CallType);
+    if (call == NULL) {
+      goto error;
+    }
     call->c_call = c_event->call;
 
-    service_acceptance_args =
-        Py_BuildValue("(OOOO)", call, method, host, service_deadline);
-    Py_DECREF(call);
-    Py_DECREF(method);
-    Py_DECREF(host);
-    Py_DECREF(service_deadline);
-
     service_acceptance =
-        PyObject_CallObject(service_acceptance_class, service_acceptance_args);
-    Py_DECREF(service_acceptance_args);
+        PyObject_CallFunctionObjArgs(service_acceptance_class, call, method,
+                                     host, service_deadline, NULL);
+    if (service_acceptance == NULL) {
+      goto error;
+    }
+
+    event_args = PyTuple_Pack(7, service_event_kind,
+                              (PyObject *)c_event->tag, Py_None, Py_None,
+                              service_acceptance, Py_None, Py_None);
 
-    event_args = Py_BuildValue("(OOOOOOO)", service_event_kind,
-                               (PyObject *)c_event->tag, Py_None, Py_None,
-                               service_acceptance, Py_None, Py_None);
     Py_DECREF(service_acceptance);
+error:
+    Py_XDECREF(call);
+    Py_XDECREF(method);
+    Py_XDECREF(host);
+    Py_XDECREF(service_deadline);
+
     return event_args;
   }
 }
 
 static PyObject *pygrpc_read_event_args(grpc_event *c_event) {
   if (c_event->data.read == NULL) {
-    return Py_BuildValue("(OOOOOOO)", read_event_kind,
-                         (PyObject *)c_event->tag, Py_None, Py_None, Py_None,
-                         Py_None, Py_None);
+    return PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag,
+                        Py_None, Py_None, Py_None, Py_None, Py_None);
   } else {
     size_t length;
     size_t offset;
@@ -198,9 +213,11 @@ static PyObject *pygrpc_read_event_args(grpc_event *c_event) {
     grpc_byte_buffer_reader_destroy(reader);
     bytes = PyBytes_FromStringAndSize(c_bytes, length);
     gpr_free(c_bytes);
-    event_args =
-        Py_BuildValue("(OOOOOOO)", read_event_kind, (PyObject *)c_event->tag,
-                      Py_None, Py_None, Py_None, bytes, Py_None);
+    if (bytes == NULL) {
+      return NULL;
+    }
+    event_args = PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag,
+                              Py_None, Py_None, Py_None, bytes, Py_None);
     Py_DECREF(bytes);
     return event_args;
   }
@@ -208,15 +225,13 @@ static PyObject *pygrpc_read_event_args(grpc_event *c_event) {
 
 static PyObject *pygrpc_metadata_event_args(grpc_event *c_event) {
   /* TODO(nathaniel): Actual transmission of metadata. */
-  return Py_BuildValue("(OOOOOOO)", metadata_event_kind,
-                       (PyObject *)c_event->tag, Py_None, Py_None, Py_None,
-                       Py_None, Py_None);
+  return PyTuple_Pack(7, metadata_event_kind, (PyObject *)c_event->tag,
+                      Py_None, Py_None, Py_None, Py_None, Py_None);
 }
 
 static PyObject *pygrpc_finished_event_args(grpc_event *c_event) {
   PyObject *code;
   PyObject *details;
-  PyObject *status_args;
   PyObject *status;
   PyObject *event_args;
 
@@ -230,19 +245,26 @@ static PyObject *pygrpc_finished_event_args(grpc_event *c_event) {
   } else {
     details = PyBytes_FromString(c_event->data.finished.details);
   }
-  status_args = Py_BuildValue("(OO)", code, details);
+  if (details == NULL) {
+    return NULL;
+  }
+  status = PyObject_CallFunctionObjArgs(status_class, code, details, NULL);
   Py_DECREF(details);
-  status = PyObject_CallObject(status_class, status_args);
-  Py_DECREF(status_args);
-  event_args =
-      Py_BuildValue("(OOOOOOO)", finish_event_kind, (PyObject *)c_event->tag,
-                    Py_None, Py_None, Py_None, Py_None, status);
+  if (status == NULL) {
+    return NULL;
+  }
+  event_args = PyTuple_Pack(7, finish_event_kind, (PyObject *)c_event->tag,
+                            Py_None, Py_None, Py_None, Py_None, status);
   Py_DECREF(status);
   return event_args;
 }
 
 static int pygrpc_completion_queue_init(CompletionQueue *self, PyObject *args,
                                         PyObject *kwds) {
+  static char *kwlist[] = {NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, ":CompletionQueue", kwlist)) {
+    return -1;
+  }
   self->c_completion_queue = grpc_completion_queue_create();
   return 0;
 }
@@ -262,7 +284,7 @@ static PyObject *pygrpc_completion_queue_get(CompletionQueue *self,
   PyObject *event_args;
   PyObject *event;
 
-  if (!(PyArg_ParseTuple(args, "O", &deadline))) {
+  if (!(PyArg_ParseTuple(args, "O:get", &deadline))) {
     return NULL;
   }
 
@@ -270,6 +292,9 @@ static PyObject *pygrpc_completion_queue_get(CompletionQueue *self,
     deadline_timespec = gpr_inf_future;
   } else {
     double_deadline = PyFloat_AsDouble(deadline);
+    if (PyErr_Occurred()) {
+      return NULL;
+    }
     deadline_timespec = gpr_time_from_nanos((long)(double_deadline * 1.0E9));
   }
 
@@ -339,7 +364,7 @@ static PyMethodDef methods[] = {
     {NULL}};
 
 PyTypeObject pygrpc_CompletionQueueType = {
-    PyObject_HEAD_INIT(NULL)0,                   /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_gprc.CompletionQueue",                     /*tp_name*/
     sizeof(CompletionQueue),                     /*tp_basicsize*/
     0,                                           /*tp_itemsize*/
@@ -375,6 +400,8 @@ PyTypeObject pygrpc_CompletionQueueType = {
     0,                                           /* tp_descr_set */
     0,                                           /* tp_dictoffset */
     (initproc)pygrpc_completion_queue_init,      /* tp_init */
+    0,                                           /* tp_alloc */
+    PyType_GenericNew,                           /* tp_new */
 };
 
 static int pygrpc_get_status_codes(PyObject *datatypes_module) {
@@ -503,7 +530,6 @@ int pygrpc_add_completion_queue(PyObject *module) {
   char *datatypes_module_path = "grpc._adapter._datatypes";
   PyObject *datatypes_module = PyImport_ImportModule(datatypes_module_path);
   if (datatypes_module == NULL) {
-    PyErr_SetString(PyExc_ImportError, datatypes_module_path);
     return -1;
   }
   status_class = PyObject_GetAttrString(datatypes_module, "Status");
@@ -512,29 +538,21 @@ int pygrpc_add_completion_queue(PyObject *module) {
   event_class = PyObject_GetAttrString(datatypes_module, "Event");
   if (status_class == NULL || service_acceptance_class == NULL ||
       event_class == NULL) {
-    PyErr_SetString(PyExc_ImportError, "Missing classes in _datatypes module!");
     return -1;
   }
   if (pygrpc_get_status_codes(datatypes_module) == -1) {
-    PyErr_SetString(PyExc_ImportError, "Status codes import broken!");
     return -1;
   }
   if (pygrpc_get_event_kinds(event_class) == -1) {
-    PyErr_SetString(PyExc_ImportError, "Event kinds import broken!");
     return -1;
   }
   Py_DECREF(datatypes_module);
 
-  pygrpc_CompletionQueueType.tp_new = PyType_GenericNew;
   if (PyType_Ready(&pygrpc_CompletionQueueType) < 0) {
-    PyErr_SetString(PyExc_RuntimeError,
-                    "Error defining pygrpc_CompletionQueueType!");
     return -1;
   }
   if (PyModule_AddObject(module, "CompletionQueue",
                          (PyObject *)&pygrpc_CompletionQueueType) == -1) {
-    PyErr_SetString(PyExc_ImportError,
-                    "Couldn't add CompletionQueue type to module!");
     return -1;
   }
   return 0;
diff --git a/src/python/src/grpc/_adapter/_lonely_rear_link_test.py b/src/python/src/grpc/_adapter/_lonely_rear_link_test.py
index fd502a1c817e2d1590abb3cb2a043bc83260719b..9a13309a1821210758ed1053247d68d1e948a8f7 100644
--- a/src/python/src/grpc/_adapter/_lonely_rear_link_test.py
+++ b/src/python/src/grpc/_adapter/_lonely_rear_link_test.py
@@ -83,7 +83,7 @@ class LonelyRearLinkTest(unittest.TestCase):
 
     with fore_link.condition:
       self.assertIsNot(fore_link.tickets[-1].kind, packets.Kind.COMPLETION)
-      
+
   @unittest.skip('TODO(nathaniel): This seems to have broken in the last few weeks; fix it.')
   def testLonelyClientCommencementPacket(self):
     self._perform_lonely_client_test_with_ticket_kind(
diff --git a/src/python/src/grpc/_adapter/_server.c b/src/python/src/grpc/_adapter/_server.c
index d4bf5fb8f645050aff1cd83ccddb4369afeb3e67..ae7ae5b5d23e9e99c7be78d4da4345fe682614ca 100644
--- a/src/python/src/grpc/_adapter/_server.c
+++ b/src/python/src/grpc/_adapter/_server.c
@@ -43,9 +43,11 @@
 static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) {
   const PyObject *completion_queue;
   PyObject *server_credentials;
-  if (!(PyArg_ParseTuple(args, "O!O", &pygrpc_CompletionQueueType,
-                         &completion_queue, &server_credentials))) {
-    self->c_server = NULL;
+  static char *kwlist[] = {"completion_queue", "server_credentials", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O:Server", kwlist,
+                                   &pygrpc_CompletionQueueType,
+                                   &completion_queue, &server_credentials)) {
     return -1;
   }
   if (server_credentials == Py_None) {
@@ -59,7 +61,9 @@ static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) {
         ((CompletionQueue *)completion_queue)->c_completion_queue, NULL);
     return 0;
   } else {
-    self->c_server = NULL;
+    PyErr_Format(PyExc_TypeError,
+                 "server_credentials must be _grpc.ServerCredentials, not %s",
+                 Py_TYPE(server_credentials)->tp_name);
     return -1;
   }
 }
@@ -74,7 +78,9 @@ static void pygrpc_server_dealloc(Server *self) {
 static PyObject *pygrpc_server_add_http2_addr(Server *self, PyObject *args) {
   const char *addr;
   int port;
-  PyArg_ParseTuple(args, "s", &addr);
+  if (!PyArg_ParseTuple(args, "s:add_http2_addr", &addr)) {
+    return NULL;
+  }
 
   port = grpc_server_add_http2_port(self->c_server, addr);
   if (port == 0) {
@@ -89,7 +95,9 @@ static PyObject *pygrpc_server_add_secure_http2_addr(Server *self,
                                                      PyObject *args) {
   const char *addr;
   int port;
-  PyArg_ParseTuple(args, "s", &addr);
+  if (!PyArg_ParseTuple(args, "s:add_secure_http2_addr", &addr)) {
+    return NULL;
+  }
   port = grpc_server_add_secure_http2_port(self->c_server, addr);
   if (port == 0) {
     PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!");
@@ -104,15 +112,10 @@ static PyObject *pygrpc_server_start(Server *self) {
   Py_RETURN_NONE;
 }
 
-static const PyObject *pygrpc_server_service(Server *self, PyObject *args) {
-  const PyObject *tag;
+static const PyObject *pygrpc_server_service(Server *self, PyObject *tag) {
   grpc_call_error call_error;
   const PyObject *result;
 
-  if (!(PyArg_ParseTuple(args, "O", &tag))) {
-    return NULL;
-  }
-
   call_error = grpc_server_request_call_old(self->c_server, (void *)tag);
 
   result = pygrpc_translate_call_error(call_error);
@@ -135,13 +138,13 @@ static PyMethodDef methods[] = {
      METH_VARARGS, "Add a secure HTTP2 address."},
     {"start", (PyCFunction)pygrpc_server_start, METH_NOARGS,
      "Starts the server."},
-    {"service", (PyCFunction)pygrpc_server_service, METH_VARARGS,
+    {"service", (PyCFunction)pygrpc_server_service, METH_O,
      "Services a call."},
     {"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."},
     {NULL}};
 
 static PyTypeObject pygrpc_ServerType = {
-    PyObject_HEAD_INIT(NULL)0,         /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_gprc.Server",                    /*tp_name*/
     sizeof(Server),                    /*tp_basicsize*/
     0,                                 /*tp_itemsize*/
@@ -177,17 +180,16 @@ static PyTypeObject pygrpc_ServerType = {
     0,                                 /* tp_descr_set */
     0,                                 /* tp_dictoffset */
     (initproc)pygrpc_server_init,      /* tp_init */
+    0,                                 /* tp_alloc */
+    PyType_GenericNew,                 /* tp_new */
 };
 
 int pygrpc_add_server(PyObject *module) {
-  pygrpc_ServerType.tp_new = PyType_GenericNew;
   if (PyType_Ready(&pygrpc_ServerType) < 0) {
-    PyErr_SetString(PyExc_RuntimeError, "Error defining pygrpc_ServerType!");
     return -1;
   }
   if (PyModule_AddObject(module, "Server", (PyObject *)&pygrpc_ServerType) ==
       -1) {
-    PyErr_SetString(PyExc_ImportError, "Couldn't add Server type to module!");
     return -1;
   }
   return 0;
diff --git a/src/python/src/grpc/_adapter/_server_credentials.c b/src/python/src/grpc/_adapter/_server_credentials.c
index ae85fd3eb752ce755679fe100dfc59a8faea8e85..06e6b94974aa7ba399b6c1bbe9a9b506f3699851 100644
--- a/src/python/src/grpc/_adapter/_server_credentials.c
+++ b/src/python/src/grpc/_adapter/_server_credentials.c
@@ -47,21 +47,20 @@ static int pygrpc_server_credentials_init(ServerCredentials *self,
   PyObject *iterator;
   int i;
   PyObject *pair;
+  static char *kwlist[] = {"root_credentials", "pair_sequence", NULL};
 
-  if (!(PyArg_ParseTuple(args, "zO", &root_certificates, &pair_sequence))) {
-    self->c_server_credentials = NULL;
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "zO:ServerCredentials", kwlist,
+                                   &root_certificates, &pair_sequence)) {
     return -1;
   }
 
   pair_count = PySequence_Length(pair_sequence);
   if (pair_count == -1) {
-    self->c_server_credentials = NULL;
     return -1;
   }
 
   iterator = PyObject_GetIter(pair_sequence);
   if (iterator == NULL) {
-    self->c_server_credentials = NULL;
     return -1;
   }
   pairs = gpr_malloc(pair_count * sizeof(grpc_ssl_pem_key_cert_pair));
@@ -72,8 +71,8 @@ static int pygrpc_server_credentials_init(ServerCredentials *self,
       error = 1;
       break;
     }
-    if (!(PyArg_ParseTuple(pair, "ss", &pairs[i].private_key,
-                           &pairs[i].cert_chain))) {
+    if (!PyArg_ParseTuple(pair, "ss", &pairs[i].private_key,
+                           &pairs[i].cert_chain)) {
       error = 1;
       Py_DECREF(pair);
       break;
@@ -83,7 +82,6 @@ static int pygrpc_server_credentials_init(ServerCredentials *self,
   Py_DECREF(iterator);
 
   if (error) {
-    self->c_server_credentials = NULL;
     gpr_free(pairs);
     return -1;
   } else {
@@ -102,7 +100,7 @@ static void pygrpc_server_credentials_dealloc(ServerCredentials *self) {
 }
 
 PyTypeObject pygrpc_ServerCredentialsType = {
-    PyObject_HEAD_INIT(NULL)0,                     /*ob_size*/
+    PyVarObject_HEAD_INIT(NULL, 0)
     "_grpc.ServerCredencials",                     /*tp_name*/
     sizeof(ServerCredentials),                     /*tp_basicsize*/
     0,                                             /*tp_itemsize*/
@@ -138,19 +136,16 @@ PyTypeObject pygrpc_ServerCredentialsType = {
     0,                                             /* tp_descr_set */
     0,                                             /* tp_dictoffset */
     (initproc)pygrpc_server_credentials_init,      /* tp_init */
+    0,                                             /* tp_alloc */
+    PyType_GenericNew,                             /* tp_new */
 };
 
 int pygrpc_add_server_credentials(PyObject *module) {
-  pygrpc_ServerCredentialsType.tp_new = PyType_GenericNew;
   if (PyType_Ready(&pygrpc_ServerCredentialsType) < 0) {
-    PyErr_SetString(PyExc_RuntimeError,
-                    "Error defining pygrpc_ServerCredentialsType!");
     return -1;
   }
   if (PyModule_AddObject(module, "ServerCredentials",
                          (PyObject *)&pygrpc_ServerCredentialsType) == -1) {
-    PyErr_SetString(PyExc_ImportError,
-                    "Couldn't add ServerCredentials type to module!");
     return -1;
   }
   return 0;
diff --git a/src/python/src/grpc/early_adopter/_face_utilities.py b/src/python/src/grpc/early_adopter/_face_utilities.py
index 714f2bb79cbd33e70123eccd3773fdd01925ff38..3e37b08752b172855c13e56e41b6e6f531152ce4 100644
--- a/src/python/src/grpc/early_adopter/_face_utilities.py
+++ b/src/python/src/grpc/early_adopter/_face_utilities.py
@@ -37,8 +37,8 @@ from grpc.early_adopter import interfaces
 
 class _InlineUnaryUnaryMethod(face_interfaces.InlineValueInValueOutMethod):
 
-  def __init__(self, unary_unary_rpc_method):
-    self._method = unary_unary_rpc_method
+  def __init__(self, unary_unary_server_rpc_method):
+    self._method = unary_unary_server_rpc_method
 
   def service(self, request, context):
     """See face_interfaces.InlineValueInValueOutMethod.service for spec."""
@@ -47,8 +47,8 @@ class _InlineUnaryUnaryMethod(face_interfaces.InlineValueInValueOutMethod):
 
 class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod):
 
-  def __init__(self, unary_stream_rpc_method):
-    self._method = unary_stream_rpc_method
+  def __init__(self, unary_stream_server_rpc_method):
+    self._method = unary_stream_server_rpc_method
 
   def service(self, request, context):
     """See face_interfaces.InlineValueInStreamOutMethod.service for spec."""
@@ -57,8 +57,8 @@ class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod):
 
 class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod):
 
-  def __init__(self, stream_unary_rpc_method):
-    self._method = stream_unary_rpc_method
+  def __init__(self, stream_unary_server_rpc_method):
+    self._method = stream_unary_server_rpc_method
 
   def service(self, request_iterator, context):
     """See face_interfaces.InlineStreamInValueOutMethod.service for spec."""
@@ -67,61 +67,99 @@ class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod):
 
 class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod):
 
-  def __init__(self, stream_stream_rpc_method):
-    self._method = stream_stream_rpc_method
+  def __init__(self, stream_stream_server_rpc_method):
+    self._method = stream_stream_server_rpc_method
 
   def service(self, request_iterator, context):
     """See face_interfaces.InlineStreamInStreamOutMethod.service for spec."""
     return self._method.service_stream_stream(request_iterator)
 
 
-class Breakdown(object):
+class ClientBreakdown(object):
+  """An intermediate representation of invocation-side views of RPC methods.
+
+  Attributes:
+    request_serializers: A dictionary from RPC method name to callable
+      behavior to be used serializing request values for the RPC.
+    response_deserializers: A dictionary from RPC method name to callable
+      behavior to be used deserializing response values for the RPC.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class _EasyClientBreakdown(
+    ClientBreakdown,
+    collections.namedtuple(
+        '_EasyClientBreakdown',
+        ('request_serializers', 'response_deserializers'))):
+  pass
+
+
+class ServerBreakdown(object):
   """An intermediate representation of implementations of RPC methods.
 
   Attributes:
-    unary_unary_methods:
-    unary_stream_methods:
-    stream_unary_methods:
-    stream_stream_methods:
-    request_serializers:
-    request_deserializers:
-    response_serializers:
-    response_deserializers:
+    unary_unary_methods: A dictionary from RPC method name to callable
+      behavior implementing the RPC method for unary-unary RPC methods.
+    unary_stream_methods: A dictionary from RPC method name to callable
+      behavior implementing the RPC method for unary-stream RPC methods.
+    stream_unary_methods: A dictionary from RPC method name to callable
+      behavior implementing the RPC method for stream-unary RPC methods.
+    stream_stream_methods: A dictionary from RPC method name to callable
+      behavior implementing the RPC method for stream-stream RPC methods.
+    request_deserializers: A dictionary from RPC method name to callable
+      behavior to be used deserializing request values for the RPC.
+    response_serializers: A dictionary from RPC method name to callable
+      behavior to be used serializing response values for the RPC.
   """
   __metaclass__ = abc.ABCMeta
 
 
 
-class _EasyBreakdown(
-    Breakdown,
+class _EasyServerBreakdown(
+    ServerBreakdown,
     collections.namedtuple(
-        '_EasyBreakdown',
-        ['unary_unary_methods', 'unary_stream_methods', 'stream_unary_methods',
-         'stream_stream_methods', 'request_serializers',
-         'request_deserializers', 'response_serializers',
-         'response_deserializers'])):
+        '_EasyServerBreakdown',
+        ('unary_unary_methods', 'unary_stream_methods', 'stream_unary_methods',
+         'stream_stream_methods', 'request_deserializers',
+         'response_serializers'))):
   pass
 
 
-def break_down(methods):
-  """Breaks down RPC methods.
+def client_break_down(methods):
+  """Derives a ClientBreakdown from several interfaces.ClientRpcMethods.
+
+  Args:
+    methods: A dictionary from RPC mthod name to
+      interfaces.ClientRpcMethod object describing the RPCs.
+
+  Returns:
+    A ClientBreakdown corresponding to the given methods.
+  """
+  request_serializers = {}
+  response_deserializers = {}
+  for name, method in methods.iteritems():
+    request_serializers[name] = method.serialize_request
+    response_deserializers[name] = method.deserialize_response
+  return _EasyClientBreakdown(request_serializers, response_deserializers)
+
+
+def server_break_down(methods):
+  """Derives a ServerBreakdown from several interfaces.ServerRpcMethods.
 
   Args:
     methods: A dictionary from RPC mthod name to
-      interfaces.RpcMethod object describing the RPCs.
+      interfaces.ServerRpcMethod object describing the RPCs.
 
   Returns:
-    A Breakdown corresponding to the given methods.
+    A ServerBreakdown corresponding to the given methods.
   """
   unary_unary = {}
   unary_stream = {}
   stream_unary = {}
   stream_stream = {}
-  request_serializers = {}
   request_deserializers = {}
   response_serializers = {}
-  response_deserializers = {}
-
   for name, method in methods.iteritems():
     cardinality = method.cardinality()
     if cardinality is interfaces.Cardinality.UNARY_UNARY:
@@ -132,12 +170,9 @@ def break_down(methods):
       stream_unary[name] = _InlineStreamUnaryMethod(method)
     elif cardinality is interfaces.Cardinality.STREAM_STREAM:
       stream_stream[name] = _InlineStreamStreamMethod(method)
-    request_serializers[name] = method.serialize_request
     request_deserializers[name] = method.deserialize_request
     response_serializers[name] = method.serialize_response
-    response_deserializers[name] = method.deserialize_response
 
-  return _EasyBreakdown(
+  return _EasyServerBreakdown(
       unary_unary, unary_stream, stream_unary, stream_stream,
-      request_serializers, request_deserializers, response_serializers,
-      response_deserializers)
+      request_deserializers, response_serializers)
diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py
index cd9dd5a57d6c181282f74d9a824f25bce683a0df..c549317d15d0108e97ef7e530e88bf819930fd16 100644
--- a/src/python/src/grpc/early_adopter/implementations.py
+++ b/src/python/src/grpc/early_adopter/implementations.py
@@ -92,7 +92,7 @@ class _Server(interfaces.Server):
 
 
 def _build_server(methods, port, private_key, certificate_chain):
-  breakdown = _face_utilities.break_down(methods)
+  breakdown = _face_utilities.server_break_down(methods)
   return _Server(breakdown, port, private_key, certificate_chain)
 
 
@@ -101,8 +101,8 @@ def insecure_server(methods, port):
 
   Args:
     methods: A dictionary from RPC method name to
-      interfaces.RpcMethod object describing the RPCs to be
-      serviced by the created server.
+      interfaces.ServerRpcMethod object describing the RPCs to
+      be serviced by the created server.
     port: The port on which to serve.
 
   Returns:
@@ -117,8 +117,8 @@ def secure_server(methods, port, private_key, certificate_chain):
 
   Args:
     methods: A dictionary from RPC method name to
-      interfaces.RpcMethod object describing the RPCs to be
-      serviced by the created server.
+      interfaces.ServerRpcMethod object describing the RPCs to
+      be serviced by the created server.
     port: The port on which to serve.
     private_key: A pem-encoded private key.
     certificate_chain: A pem-encoded certificate chain.
diff --git a/src/python/src/grpc/early_adopter/interfaces.py b/src/python/src/grpc/early_adopter/interfaces.py
index c2806c235cf396aee8241e9d02d07235cb918d22..0ec371f8e88472333899f19b987f0969de9af069 100644
--- a/src/python/src/grpc/early_adopter/interfaces.py
+++ b/src/python/src/grpc/early_adopter/interfaces.py
@@ -44,7 +44,7 @@ class Cardinality(enum.Enum):
 
 
 class RpcMethod(object):
-  """A sum type for the implementation of an RPC method."""
+  """A type for the common aspects of RPC method specifications."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
@@ -59,6 +59,11 @@ class RpcMethod(object):
     """
     raise NotImplementedError()
 
+
+class ClientRpcMethod(RpcMethod):
+  """Invocation-side description of an RPC method."""
+  __metaclass__ = abc.ABCMeta
+
   @abc.abstractmethod
   def serialize_request(self, request):
     """Serializes a request value.
@@ -72,6 +77,25 @@ class RpcMethod(object):
     """
     raise NotImplementedError()
 
+  @abc.abstractmethod
+  def deserialize_response(self, serialized_response):
+    """Deserializes a response value.
+
+    Args:
+      serialized_response: A bytestring that is the
+        serialization of a response value appropriate for this
+        RpcMethod.
+
+    Returns:
+      A response value corresponding to the given bytestring.
+    """
+    raise NotImplementedError()
+
+
+class ServerRpcMethod(RpcMethod):
+  """Service-side description of an RPC method."""
+  __metaclass__ = abc.ABCMeta
+
   @abc.abstractmethod
   def deserialize_request(self, serialized_request):
     """Deserializes a request value.
@@ -99,20 +123,6 @@ class RpcMethod(object):
     """
     raise NotImplementedError()
 
-  @abc.abstractmethod
-  def deserialize_response(self, serialized_response):
-    """Deserializes a response value.
-
-    Args:
-      serialized_response: A bytestring that is the
-        serialization of a response value appropriate for this
-        RpcMethod.
-
-    Returns:
-      A response value corresponding to the given bytestring.
-    """
-    raise NotImplementedError()
-
   @abc.abstractmethod
   def service_unary_unary(self, request):
     """Carries out this RPC.
@@ -181,7 +191,6 @@ class RpcMethod(object):
 class Server(object):
   """A GRPC Server."""
   __metaclass__ = abc.ABCMeta
-  
 
   @abc.abstractmethod
   def start(self):
diff --git a/src/python/src/grpc/early_adopter/utilities.py b/src/python/src/grpc/early_adopter/utilities.py
index a4ee253d8306443bdc293d0ed49fbb26c0b60e09..9277d3f6ad4f1defe05134841646541774dcd27a 100644
--- a/src/python/src/grpc/early_adopter/utilities.py
+++ b/src/python/src/grpc/early_adopter/utilities.py
@@ -32,7 +32,7 @@
 from grpc.early_adopter import interfaces
 
 
-class _RpcMethod(interfaces.RpcMethod):
+class _RpcMethod(interfaces.ClientRpcMethod, interfaces.ServerRpcMethod):
 
   def __init__(
       self, cardinality, unary_unary, unary_stream, stream_unary,
@@ -85,129 +85,181 @@ class _RpcMethod(interfaces.RpcMethod):
     return self._stream_stream(request_iterator)
 
 
-def unary_unary_rpc_method(
-    behavior, request_serializer, request_deserializer, response_serializer,
-    response_deserializer):
-  """Constructs an interfaces.RpcMethod for the given behavior.
+def unary_unary_client_rpc_method(request_serializer, response_deserializer):
+  """Constructs an interfaces.ClientRpcMethod for a unary-unary RPC method.
+
+  Args:
+    request_serializer: A callable that when called on a request
+      value returns a bytestring corresponding to that value.
+    response_deserializer: A callable that when called on a
+      bytestring returns the response value corresponding to
+      that bytestring.
+
+  Returns:
+    An interfaces.ClientRpcMethod constructed from the given
+      arguments representing a unary-request/unary-response RPC
+      method.
+  """
+  return _RpcMethod(
+      interfaces.Cardinality.UNARY_UNARY, None, None, None, None,
+      request_serializer, None, None, response_deserializer)
+
+
+def unary_stream_client_rpc_method(request_serializer, response_deserializer):
+  """Constructs an interfaces.ClientRpcMethod for a unary-stream RPC method.
+
+  Args:
+    request_serializer: A callable that when called on a request
+      value returns a bytestring corresponding to that value.
+    response_deserializer: A callable that when called on a
+      bytestring returns the response value corresponding to
+      that bytestring.
+
+  Returns:
+    An interfaces.ClientRpcMethod constructed from the given
+      arguments representing a unary-request/streaming-response
+      RPC method.
+  """
+  return _RpcMethod(
+      interfaces.Cardinality.UNARY_STREAM, None, None, None, None,
+      request_serializer, None, None, response_deserializer)
+
+
+def stream_unary_client_rpc_method(request_serializer, response_deserializer):
+  """Constructs an interfaces.ClientRpcMethod for a stream-unary RPC method.
+
+  Args:
+    request_serializer: A callable that when called on a request
+      value returns a bytestring corresponding to that value.
+    response_deserializer: A callable that when called on a
+      bytestring returns the response value corresponding to
+      that bytestring.
+
+  Returns:
+    An interfaces.ClientRpcMethod constructed from the given
+      arguments representing a streaming-request/unary-response
+      RPC method.
+  """
+  return _RpcMethod(
+      interfaces.Cardinality.STREAM_UNARY, None, None, None, None,
+      request_serializer, None, None, response_deserializer)
+
+
+def stream_stream_client_rpc_method(request_serializer, response_deserializer):
+  """Constructs an interfaces.ClientRpcMethod for a stream-stream RPC method.
+
+  Args:
+    request_serializer: A callable that when called on a request
+      value returns a bytestring corresponding to that value.
+    response_deserializer: A callable that when called on a
+      bytestring returns the response value corresponding to
+      that bytestring.
+
+  Returns:
+    An interfaces.ClientRpcMethod constructed from the given
+      arguments representing a
+      streaming-request/streaming-response RPC method.
+  """
+  return _RpcMethod(
+      interfaces.Cardinality.STREAM_STREAM, None, None, None, None,
+      request_serializer, None, None, response_deserializer)
+
+
+def unary_unary_server_rpc_method(
+    behavior, request_deserializer, response_serializer):
+  """Constructs an interfaces.ServerRpcMethod for the given behavior.
 
   Args:
     behavior: A callable that implements a unary-unary RPC
       method that accepts a single request and returns a single
       response.
-    request_serializer: A callable that when called on a request
-      value returns a bytestring corresponding to that value.
     request_deserializer: A callable that when called on a
       bytestring returns the request value corresponding to that
       bytestring.
     response_serializer: A callable that when called on a
       response value returns the bytestring corresponding to
       that value.
-    response_deserializer: A callable that when called on a
-      bytestring returns the response value corresponding to
-      that bytestring.
 
   Returns:
-    An interfaces.RpcMethod constructed from the given
+    An interfaces.ServerRpcMethod constructed from the given
       arguments representing a unary-request/unary-response RPC
       method.
   """
   return _RpcMethod(
       interfaces.Cardinality.UNARY_UNARY, behavior, None, None, None,
-      request_serializer, request_deserializer, response_serializer,
-      response_deserializer)
+      None, request_deserializer, response_serializer, None)
 
 
-def unary_stream_rpc_method(
-    behavior, request_serializer, request_deserializer, response_serializer,
-    response_deserializer):
-  """Constructs an interfaces.RpcMethod for the given behavior.
+def unary_stream_server_rpc_method(
+    behavior, request_deserializer, response_serializer):
+  """Constructs an interfaces.ServerRpcMethod for the given behavior.
 
   Args:
     behavior: A callable that implements a unary-stream RPC
       method that accepts a single request and returns an
       iterator of zero or more responses.
-    request_serializer: A callable that when called on a request
-      value returns a bytestring corresponding to that value.
     request_deserializer: A callable that when called on a
       bytestring returns the request value corresponding to that
       bytestring.
     response_serializer: A callable that when called on a
       response value returns the bytestring corresponding to
       that value.
-    response_deserializer: A callable that when called on a
-      bytestring returns the response value corresponding to
-      that bytestring.
 
   Returns:
-    An interfaces.RpcMethod constructed from the given
+    An interfaces.ServerRpcMethod constructed from the given
       arguments representing a unary-request/streaming-response
       RPC method.
   """
   return _RpcMethod(
       interfaces.Cardinality.UNARY_STREAM, None, behavior, None, None,
-      request_serializer, request_deserializer, response_serializer,
-      response_deserializer)
+      None, request_deserializer, response_serializer, None)
 
 
-def stream_unary_rpc_method(
-    behavior, request_serializer, request_deserializer, response_serializer,
-    response_deserializer):
-  """Constructs an interfaces.RpcMethod for the given behavior.
+def stream_unary_server_rpc_method(
+    behavior, request_deserializer, response_serializer):
+  """Constructs an interfaces.ServerRpcMethod for the given behavior.
 
   Args:
     behavior: A callable that implements a stream-unary RPC
       method that accepts an iterator of zero or more requests
       and returns a single response.
-    request_serializer: A callable that when called on a request
-      value returns a bytestring corresponding to that value.
     request_deserializer: A callable that when called on a
       bytestring returns the request value corresponding to that
       bytestring.
     response_serializer: A callable that when called on a
       response value returns the bytestring corresponding to
       that value.
-    response_deserializer: A callable that when called on a
-      bytestring returns the response value corresponding to
-      that bytestring.
 
   Returns:
-    An interfaces.RpcMethod constructed from the given
+    An interfaces.ServerRpcMethod constructed from the given
       arguments representing a streaming-request/unary-response
       RPC method.
   """
   return _RpcMethod(
       interfaces.Cardinality.STREAM_UNARY, None, None, behavior, None,
-      request_serializer, request_deserializer, response_serializer,
-      response_deserializer)
+      None, request_deserializer, response_serializer, None)
 
 
-def stream_stream_rpc_method(
-    behavior, request_serializer, request_deserializer, response_serializer,
-    response_deserializer):
-  """Constructs an interfaces.RpcMethod for the given behavior.
+def stream_stream_server_rpc_method(
+    behavior, request_deserializer, response_serializer):
+  """Constructs an interfaces.ServerRpcMethod for the given behavior.
 
   Args:
     behavior: A callable that implements a stream-stream RPC
       method that accepts an iterator of zero or more requests
       and returns an iterator of zero or more responses.
-    request_serializer: A callable that when called on a request
-      value returns a bytestring corresponding to that value.
     request_deserializer: A callable that when called on a
       bytestring returns the request value corresponding to that
       bytestring.
     response_serializer: A callable that when called on a
       response value returns the bytestring corresponding to
       that value.
-    response_deserializer: A callable that when called on a
-      bytestring returns the response value corresponding to
-      that bytestring.
 
   Returns:
-    An interfaces.RpcMethod constructed from the given
+    An interfaces.ServerRpcMethod constructed from the given
       arguments representing a
       streaming-request/streaming-response RPC method.
   """
   return _RpcMethod(
       interfaces.Cardinality.STREAM_STREAM, None, None, None, behavior,
-      request_serializer, request_deserializer, response_serializer,
-      response_deserializer)
+      None, request_deserializer, response_serializer, None)
diff --git a/src/python/src/grpc/framework/base/interfaces_test.py b/src/python/src/grpc/framework/base/interfaces_test_case.py
similarity index 100%
rename from src/python/src/grpc/framework/base/interfaces_test.py
rename to src/python/src/grpc/framework/base/interfaces_test_case.py
diff --git a/src/python/src/grpc/framework/base/packets/implementations_test.py b/src/python/src/grpc/framework/base/packets/implementations_test.py
index 628f4b39094dcbc2fc285898359a58af2cfb1a76..e5855700c727ca9bfebba494809286602e2f110c 100644
--- a/src/python/src/grpc/framework/base/packets/implementations_test.py
+++ b/src/python/src/grpc/framework/base/packets/implementations_test.py
@@ -31,7 +31,7 @@
 
 import unittest
 
-from grpc.framework.base import interfaces_test
+from grpc.framework.base import interfaces_test_case
 from grpc.framework.base import util
 from grpc.framework.base.packets import implementations
 from grpc.framework.foundation import logging_pool
@@ -42,7 +42,7 @@ MAXIMUM_TIMEOUT = 60
 
 
 class ImplementationsTest(
-    interfaces_test.FrontAndBackTest, unittest.TestCase):
+    interfaces_test_case.FrontAndBackTest, unittest.TestCase):
 
   def setUp(self):
     self.memory_transmission_pool = logging_pool.pool(POOL_MAX_WORKERS)
@@ -53,7 +53,7 @@ class ImplementationsTest(
     self.back_transmission_pool = logging_pool.pool(POOL_MAX_WORKERS)
     self.back_utility_pool = logging_pool.pool(POOL_MAX_WORKERS)
     self.test_pool = logging_pool.pool(POOL_MAX_WORKERS)
-    self.test_servicer = interfaces_test.TestServicer(self.test_pool)
+    self.test_servicer = interfaces_test_case.TestServicer(self.test_pool)
     self.front = implementations.front(
         self.front_work_pool, self.front_transmission_pool,
         self.front_utility_pool)
diff --git a/src/ruby/README.md b/src/ruby/README.md
index 7ece7e27065f811ee2c9f22363c57e2ac8288b8e..6e0e9db4a3cfe5bc67343635c5ae7052a2bf8834 100755
--- a/src/ruby/README.md
+++ b/src/ruby/README.md
@@ -1,38 +1,43 @@
 gRPC Ruby
 =========
 
-A Ruby implementation of gRPC, Google's RPC library.
+A Ruby implementation of gRPC.
 
+Status
+-------
+
+Alpha : Ready for early adopters
 
 INSTALLATION PREREQUISITES
 --------------------------
 
-This requires Ruby 2.x, as the rpc api surface uses keyword args.
+This requires Ruby 2.x, as the RPC API surface uses keyword args.
 
 
-INSTALLING
-----------
+QUICK - INSTALL
+---------------
 
-- Install the gRPC core library
-  TODO: describe this, once the core distribution mechanism is defined.
-```
-$ gem install grpc
+- Clone this repository.
+- Follow the instructions in [INSTALL](../../INSTALL) to install the gRPC C core.
+- Use bundler to install
+```sh
+$ # from this directory
+$ gem install bundler && bundle install
 ```
 
-
 Installing from source
 ----------------------
 
-- Build or Install the gRPC core
-E.g, from the root of the grpc [git repo](https://github.com/google/grpc)
-```
+- Build the gRPC C core
+E.g, from the root of the gRPC [git repo](https://github.com/google/grpc)
+```sh
 $ cd ../..
 $ make && sudo make install
 ```
 
 - Install Ruby 2.x. Consider doing this with [RVM](http://rvm.io), it's a nice way of controlling
   the exact ruby version that's used.
-```
+```sh
 $ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
 $ \curl -sSL https://get.rvm.io | bash -s stable --ruby
 $
@@ -45,8 +50,8 @@ $ # and that the rvm command is installed
 $ gem install bundler
 ```
 
-- Finally, install grpc ruby locally.
-```
+- Finally, install the gRPC gem locally.
+```sh
 $ cd <install_dir>
 $ bundle install
 $ rake  # compiles the extension, runs the unit tests, see rake -T for other options
@@ -60,7 +65,7 @@ Directory structure is the layout for [ruby extensions](http://guides.rubygems.o
 - ext:
   the gRPC ruby extension
 - lib:
-  the entrypoint grpc ruby library to be used in a 'require' statement
+  the entrypoint gRPC ruby library to be used in a 'require' statement
 - spec:
   Rspec unittest
 - bin:
@@ -69,6 +74,6 @@ Directory structure is the layout for [ruby extensions](http://guides.rubygems.o
 stub = Math::Math::Stub.new('my.test.math.server.com:8080')
 req = Math::DivArgs.new(dividend: 7, divisor: 3)
 logger.info("div(7/3): req=#{req.inspect}")
-resp = stub.div(req, INFINITE_FUTURE)
+resp = stub.div(req)
 logger.info("Answer: #{resp.inspect}")
 ```
diff --git a/src/ruby/bin/apis/google/protobuf/empty.rb b/src/ruby/bin/apis/google/protobuf/empty.rb
index 33e8a9281c7ebfc162a8c2d16ec6cec7dac1db99..2f6bbc950b6427a138b0efb7d4ed5b3f8097bef4 100644
--- a/src/ruby/bin/apis/google/protobuf/empty.rb
+++ b/src/ruby/bin/apis/google/protobuf/empty.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb
index 8ebac19d95a3e6f7be51da11b38a20454df41e25..6656a561309fd52d1b9eca88a95201e607aa70a2 100755
--- a/src/ruby/bin/apis/pubsub_demo.rb
+++ b/src/ruby/bin/apis/pubsub_demo.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb b/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb
index aa7893dbc7b19120972b69259693ff2f601e0ba5..d61431f17af11a35bd3d6d8cf98265ca1507034e 100644
--- a/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb
+++ b/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb b/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb
index 0023f4844ee145916c9a03da92910d1388340133..43c5265643acf217a8ddfcb6839ea831c06ba1a0 100644
--- a/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb
+++ b/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/interop/interop_client.rb b/src/ruby/bin/interop/interop_client.rb
index e29e22b8c151e35a502729c9c3655de8ff8beebd..50a14e3a961617cfa855fc2d9b3763d4e38742fc 100755
--- a/src/ruby/bin/interop/interop_client.rb
+++ b/src/ruby/bin/interop/interop_client.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -211,10 +211,8 @@ class NamedTests
   def compute_engine_creds
     resp = perform_large_unary(fill_username: true,
                                fill_oauth_scope: true)
-    assert(@args.oauth_scope.include?(resp.oauth_scope),
-           'service_account_creds: incorrect oauth_scope')
     assert_equal(@args.default_service_account, resp.username,
-                 'service_account_creds: incorrect username')
+                 'compute_engine_creds: incorrect username')
     p 'OK: compute_engine_creds'
   end
 
diff --git a/src/ruby/bin/interop/interop_server.rb b/src/ruby/bin/interop/interop_server.rb
index cc4d26087952fec6aa36afeffbdab564823892b7..b3b7d0c5a3a90f3eca27fac7ae34673f6197e6a6 100755
--- a/src/ruby/bin/interop/interop_server.rb
+++ b/src/ruby/bin/interop/interop_server.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/interop/test/cpp/interop/empty.rb b/src/ruby/bin/interop/test/cpp/interop/empty.rb
index acd4160d248509c87f22ba66fa59b1c2817a29c1..3579fa5ded80e6d32b500947d0e202857865f2f0 100644
--- a/src/ruby/bin/interop/test/cpp/interop/empty.rb
+++ b/src/ruby/bin/interop/test/cpp/interop/empty.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/interop/test/cpp/interop/messages.rb b/src/ruby/bin/interop/test/cpp/interop/messages.rb
index b86cd396a9f9a3e704653924677018b0e9eb9365..89c349b4060011b7cc1589a5aad6df8d4ca0d896 100644
--- a/src/ruby/bin/interop/test/cpp/interop/messages.rb
+++ b/src/ruby/bin/interop/test/cpp/interop/messages.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/interop/test/cpp/interop/test.rb b/src/ruby/bin/interop/test/cpp/interop/test.rb
index 0b391ed6af0ab4ba84ddac33bdbb397ff2e58061..5948b50eaa5cddae2ce7fac485b3d3db8bc32be5 100644
--- a/src/ruby/bin/interop/test/cpp/interop/test.rb
+++ b/src/ruby/bin/interop/test/cpp/interop/test.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/interop/test/cpp/interop/test_services.rb b/src/ruby/bin/interop/test/cpp/interop/test_services.rb
index 17b5461d3e3c20a0a02f2eeb35eff9e984f7a36f..5a3146c581b24b2ab7656f0237c1071e6cac963f 100644
--- a/src/ruby/bin/interop/test/cpp/interop/test_services.rb
+++ b/src/ruby/bin/interop/test/cpp/interop/test_services.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/math.proto b/src/ruby/bin/math.proto
index 2cf6a036aa4ce5565925ca5a5e3cb26df18bcfef..e34ad5e9672791f1db5fc1a5e40973f95ab2cc40 100755
--- a/src/ruby/bin/math.proto
+++ b/src/ruby/bin/math.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/src/ruby/bin/math.rb b/src/ruby/bin/math.rb
index 09d1e9858640e4ca8c9ca4daee61d69c8cb25c20..323993ed439e9cbd46668ac14180583de26ea174 100755
--- a/src/ruby/bin/math.rb
+++ b/src/ruby/bin/math.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb
index 7e838e23d1781c0ecca49054146ee4a58e0eb80c..cb085d4d42988e2a13809ae6b47fc7beb9259a68 100755
--- a/src/ruby/bin/math_client.rb
+++ b/src/ruby/bin/math_client.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb
index 55ee1d331410f0ed853b3bb20d4b0ec554b82657..93277e39320c4948cdd5fc46815da2feab4716ad 100755
--- a/src/ruby/bin/math_server.rb
+++ b/src/ruby/bin/math_server.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/math_services.rb b/src/ruby/bin/math_services.rb
index f6ca6fe060c942b63b7a60582a6bc7f3d75d48fc..cf58a53913fa970f4902da61102e5feffbae3ba2 100755
--- a/src/ruby/bin/math_services.rb
+++ b/src/ruby/bin/math_services.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/noproto_client.rb b/src/ruby/bin/noproto_client.rb
index 74bdfbb93a74022d51eed4feb6b5a87712cce424..44710520d297941fa2c541f434b2233d68bb6b10 100755
--- a/src/ruby/bin/noproto_client.rb
+++ b/src/ruby/bin/noproto_client.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/bin/noproto_server.rb b/src/ruby/bin/noproto_server.rb
index e34075c1f0c89b65a15976011107c030b2e47e7d..435f8f4ebf495aec964d271a1a609a47fc532014 100755
--- a/src/ruby/bin/noproto_server.rb
+++ b/src/ruby/bin/noproto_server.rb
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index cbf41eda8b7ac613510a425faeedfb2395f5037d..96c92e2be5ddaa9049dcf856db14574dd38434e2 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c
index f73b12c417feb280eaca0f1bb20071c106f9b95f..ff5a114de58048c78250f61a74f5d1533b63fac3 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.c
+++ b/src/ruby/ext/grpc/rb_byte_buffer.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -202,9 +202,9 @@ static VALUE grpc_rb_byte_buffer_init(VALUE self, VALUE src) {
 /* rb_cByteBuffer is the ruby class that proxies grpc_byte_buffer. */
 VALUE rb_cByteBuffer = Qnil;
 
-void Init_google_rpc_byte_buffer() {
+void Init_grpc_byte_buffer() {
   rb_cByteBuffer =
-      rb_define_class_under(rb_mGoogleRpcCore, "ByteBuffer", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "ByteBuffer", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(rb_cByteBuffer, grpc_rb_byte_buffer_alloc);
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.h b/src/ruby/ext/grpc/rb_byte_buffer.h
index 322c268f377fa4c5af916e6e5a0968342b8a0a95..6ef72f3e757fe2137acacb6159af4229c74ee0cb 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.h
+++ b/src/ruby/ext/grpc/rb_byte_buffer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
 extern VALUE rb_cByteBuffer;
 
 /* Initializes the ByteBuffer class. */
-void Init_google_rpc_byte_buffer();
+void Init_grpc_byte_buffer();
 
 /* grpc_rb_byte_buffer_create_with_mark creates a grpc_rb_byte_buffer with a
  * ruby mark object that will be kept alive while the byte_buffer is alive. */
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 5d72307668277df96173f0521ff5156b6e4247ad..b5a256d5a67d4b79ff6b8ab342506932761eff32 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -449,9 +449,9 @@ VALUE rb_cCall = Qnil;
    operations; */
 VALUE rb_eCallError = Qnil;
 
-void Init_google_rpc_error_codes() {
+void Init_grpc_error_codes() {
   /* Constants representing the error codes of grpc_call_error in grpc.h */
-  VALUE rb_RpcErrors = rb_define_module_under(rb_mGoogleRpcCore, "RpcErrors");
+  VALUE rb_RpcErrors = rb_define_module_under(rb_mGrpcCore, "RpcErrors");
   rb_define_const(rb_RpcErrors, "OK", UINT2NUM(GRPC_CALL_OK));
   rb_define_const(rb_RpcErrors, "ERROR", UINT2NUM(GRPC_CALL_ERROR));
   rb_define_const(rb_RpcErrors, "NOT_ON_SERVER",
@@ -500,11 +500,11 @@ void Init_google_rpc_error_codes() {
   rb_obj_freeze(rb_error_code_details);
 }
 
-void Init_google_rpc_call() {
+void Init_grpc_call() {
   /* CallError inherits from Exception to signal that it is non-recoverable */
   rb_eCallError =
-      rb_define_class_under(rb_mGoogleRpcCore, "CallError", rb_eException);
-  rb_cCall = rb_define_class_under(rb_mGoogleRpcCore, "Call", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "CallError", rb_eException);
+  rb_cCall = rb_define_class_under(rb_mGrpcCore, "Call", rb_cObject);
 
   /* Prevent allocation or inialization of the Call class */
   rb_define_alloc_func(rb_cCall, grpc_rb_cannot_alloc);
@@ -542,7 +542,7 @@ void Init_google_rpc_call() {
   hash_all_calls = rb_hash_new();
   rb_define_const(rb_cCall, "INTERNAL_ALL_CALLs", hash_all_calls);
 
-  Init_google_rpc_error_codes();
+  Init_grpc_error_codes();
 }
 
 /* Gets the call from the ruby object */
diff --git a/src/ruby/ext/grpc/rb_call.h b/src/ruby/ext/grpc/rb_call.h
index 965e9eef409d5bddb08548a7e5ea8ee8ddf36fee..bb51759a467bdd51b98051fee82e5910e5f48f06 100644
--- a/src/ruby/ext/grpc/rb_call.h
+++ b/src/ruby/ext/grpc/rb_call.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,6 @@ extern VALUE rb_cCall;
 extern VALUE rb_eCallError;
 
 /* Initializes the Call class. */
-void Init_google_rpc_call();
+void Init_grpc_call();
 
 #endif /* GRPC_RB_CALL_H_ */
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index 7c98e66c33d1287a619f6d274f3b34917b36e76b..2a48f46ce2eeaeec1d53aa532f7cd375f4ba8606 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -227,9 +227,9 @@ static VALUE grpc_rb_channel_destroy(VALUE self) {
 /* rb_cChannel is the ruby class that proxies grpc_channel. */
 VALUE rb_cChannel = Qnil;
 
-void Init_google_rpc_channel() {
+void Init_grpc_channel() {
   rb_cChannelArgs = rb_define_class("TmpChannelArgs", rb_cObject);
-  rb_cChannel = rb_define_class_under(rb_mGoogleRpcCore, "Channel", rb_cObject);
+  rb_cChannel = rb_define_class_under(rb_mGrpcCore, "Channel", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(rb_cChannel, grpc_rb_channel_alloc);
diff --git a/src/ruby/ext/grpc/rb_channel.h b/src/ruby/ext/grpc/rb_channel.h
index 6c1210e812dad11b4a3b92bbc7a6d9bed650a3e6..a582869cda4b32b00cfa617b3fb493e4d015388c 100644
--- a/src/ruby/ext/grpc/rb_channel.h
+++ b/src/ruby/ext/grpc/rb_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@
 extern VALUE rb_cChannel;
 
 /* Initializes the Channel class. */
-void Init_google_rpc_channel();
+void Init_grpc_channel();
 
 /* Gets the wrapped channel from the ruby wrapper */
 grpc_channel* grpc_rb_get_wrapped_channel(VALUE v);
diff --git a/src/ruby/ext/grpc/rb_channel_args.c b/src/ruby/ext/grpc/rb_channel_args.c
index cf492591284217d26b9a48fa6b127a024742d706..532ee5e78599822ccad0e3895b1ada48b8a59cbc 100644
--- a/src/ruby/ext/grpc/rb_channel_args.c
+++ b/src/ruby/ext/grpc/rb_channel_args.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/ext/grpc/rb_channel_args.h b/src/ruby/ext/grpc/rb_channel_args.h
index 07be66279309a66026ccd97707ee801dce4e86e0..78a333bd0826b25c57f3dad29907ef2065540f08 100644
--- a/src/ruby/ext/grpc/rb_channel_args.h
+++ b/src/ruby/ext/grpc/rb_channel_args.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/ext/grpc/rb_completion_queue.c b/src/ruby/ext/grpc/rb_completion_queue.c
index 47776a991a14bcef0cc111bb5247a9137e83463d..3fdbdd837a7e7866d3a245053695e52f6e484964 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.c
+++ b/src/ruby/ext/grpc/rb_completion_queue.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -159,9 +159,9 @@ static VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
 /* rb_cCompletionQueue is the ruby class that proxies grpc_completion_queue. */
 VALUE rb_cCompletionQueue = Qnil;
 
-void Init_google_rpc_completion_queue() {
+void Init_grpc_completion_queue() {
   rb_cCompletionQueue =
-      rb_define_class_under(rb_mGoogleRpcCore, "CompletionQueue", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "CompletionQueue", rb_cObject);
 
   /* constructor: uses an alloc func without an initializer. Using a simple
      alloc func works here as the grpc header does not specify any args for
diff --git a/src/ruby/ext/grpc/rb_completion_queue.h b/src/ruby/ext/grpc/rb_completion_queue.h
index c563662c2d42f0857018776cda447771d703c734..38025ea2d2e2488d81b7b879a89a1fa8f05e4c55 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.h
+++ b/src/ruby/ext/grpc/rb_completion_queue.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,6 @@ grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v);
 extern VALUE rb_cCompletionQueue;
 
 /* Initializes the CompletionQueue class. */
-void Init_google_rpc_completion_queue();
+void Init_grpc_completion_queue();
 
 #endif /* GRPC_RB_COMPLETION_QUEUE_H_ */
diff --git a/src/ruby/ext/grpc/rb_credentials.c b/src/ruby/ext/grpc/rb_credentials.c
index 87a5d0a299cda9c0f6d0dcf086c6a5725632fdc3..778270735bcda7f48dc489794b1075a97916f8d6 100644
--- a/src/ruby/ext/grpc/rb_credentials.c
+++ b/src/ruby/ext/grpc/rb_credentials.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -245,9 +245,9 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
 /* rb_cCredentials is the ruby class that proxies grpc_credentials. */
 VALUE rb_cCredentials = Qnil;
 
-void Init_google_rpc_credentials() {
+void Init_grpc_credentials() {
   rb_cCredentials =
-      rb_define_class_under(rb_mGoogleRpcCore, "Credentials", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "Credentials", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(rb_cCredentials, grpc_rb_credentials_alloc);
diff --git a/src/ruby/ext/grpc/rb_credentials.h b/src/ruby/ext/grpc/rb_credentials.h
index fada3639d5828949b770345ae886ea85e7e97f41..3b24397173639725f497006e7b7044556a7e23d2 100644
--- a/src/ruby/ext/grpc/rb_credentials.h
+++ b/src/ruby/ext/grpc/rb_credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
 extern VALUE rb_cCredentials;
 
 /* Initializes the ruby Credentials class. */
-void Init_google_rpc_credentials();
+void Init_grpc_credentials();
 
 /* Gets the wrapped credentials from the ruby wrapper */
 grpc_credentials* grpc_rb_get_wrapped_credentials(VALUE v);
diff --git a/src/ruby/ext/grpc/rb_event.c b/src/ruby/ext/grpc/rb_event.c
index 72c9dd2ec0031975091622f8214af6c1d89978e7..2e64af4c847cac31b4b9daea0128de4394375abd 100644
--- a/src/ruby/ext/grpc/rb_event.c
+++ b/src/ruby/ext/grpc/rb_event.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -312,10 +312,10 @@ VALUE rb_cEvent = Qnil;
    rpc event processing. */
 VALUE rb_eEventError = Qnil;
 
-void Init_google_rpc_event() {
+void Init_grpc_event() {
   rb_eEventError =
-      rb_define_class_under(rb_mGoogleRpcCore, "EventError", rb_eStandardError);
-  rb_cEvent = rb_define_class_under(rb_mGoogleRpcCore, "Event", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "EventError", rb_eStandardError);
+  rb_cEvent = rb_define_class_under(rb_mGrpcCore, "Event", rb_cObject);
 
   /* Prevent allocation or inialization from ruby. */
   rb_define_alloc_func(rb_cEvent, grpc_rb_cannot_alloc);
@@ -332,7 +332,7 @@ void Init_google_rpc_event() {
 
   /* Constants representing the completion types */
   rb_mCompletionType =
-      rb_define_module_under(rb_mGoogleRpcCore, "CompletionType");
+      rb_define_module_under(rb_mGrpcCore, "CompletionType");
   rb_define_const(rb_mCompletionType, "QUEUE_SHUTDOWN",
                   INT2NUM(GRPC_QUEUE_SHUTDOWN));
   rb_define_const(rb_mCompletionType, "OP_COMPLETE", INT2NUM(GRPC_OP_COMPLETE));
diff --git a/src/ruby/ext/grpc/rb_event.h b/src/ruby/ext/grpc/rb_event.h
index a406e9e9f17f0259e410b39158bf9591ead4446d..3105934b110dd7c66b539e9caf9d845dbe0fbe53 100644
--- a/src/ruby/ext/grpc/rb_event.h
+++ b/src/ruby/ext/grpc/rb_event.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,6 @@ extern VALUE rb_eEventError;
 VALUE grpc_rb_new_event(grpc_event *ev);
 
 /* Initializes the Event and EventError classes. */
-void Init_google_rpc_event();
+void Init_grpc_event();
 
 #endif /* GRPC_RB_EVENT_H_ */
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 8feefb047cca71a022b32c9eb860b184ae351c12..c7671c8a775098597e4f8b752d001de4c4d274cc 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -153,10 +153,10 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
   return t;
 }
 
-void Init_google_status_codes() {
+void Init_grpc_status_codes() {
   /* Constants representing the status codes or grpc_status_code in status.h */
   VALUE rb_mStatusCodes =
-      rb_define_module_under(rb_mGoogleRpcCore, "StatusCodes");
+      rb_define_module_under(rb_mGrpcCore, "StatusCodes");
   rb_define_const(rb_mStatusCodes, "OK", INT2NUM(GRPC_STATUS_OK));
   rb_define_const(rb_mStatusCodes, "CANCELLED", INT2NUM(GRPC_STATUS_CANCELLED));
   rb_define_const(rb_mStatusCodes, "UNKNOWN", INT2NUM(GRPC_STATUS_UNKNOWN));
@@ -214,11 +214,11 @@ VALUE grpc_rb_time_val_to_s(VALUE self) {
 }
 
 /* Adds a module with constants that map to gpr's static timeval structs. */
-void Init_google_time_consts() {
+void Init_grpc_time_consts() {
   VALUE rb_mTimeConsts =
-      rb_define_module_under(rb_mGoogleRpcCore, "TimeConsts");
+      rb_define_module_under(rb_mGrpcCore, "TimeConsts");
   rb_cTimeVal =
-      rb_define_class_under(rb_mGoogleRpcCore, "TimeSpec", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "TimeSpec", rb_cObject);
   rb_define_const(rb_mTimeConsts, "ZERO",
                   Data_Wrap_Struct(rb_cTimeVal, GC_NOT_MARKED, GC_DONT_FREE,
                                    (void *)&gpr_time_0));
@@ -240,37 +240,35 @@ void Init_google_time_consts() {
 
 void grpc_rb_shutdown(void *vm) { grpc_shutdown(); }
 
-/* Initialize the Google RPC module structs */
+/* Initialize the GRPC module structs */
 
 /* rb_sNewServerRpc is the struct that holds new server rpc details. */
 VALUE rb_sNewServerRpc = Qnil;
 /* rb_sStatus is the struct that holds status details. */
 VALUE rb_sStatus = Qnil;
 
-/* Initialize the Google RPC module. */
-VALUE rb_mGoogle = Qnil;
-VALUE rb_mGoogleRPC = Qnil;
-VALUE rb_mGoogleRpcCore = Qnil;
+/* Initialize the GRPC module. */
+VALUE rb_mGRPC = Qnil;
+VALUE rb_mGrpcCore = Qnil;
 
 void Init_grpc() {
   grpc_init();
   ruby_vm_at_exit(grpc_rb_shutdown);
-  rb_mGoogle = rb_define_module("Google");
-  rb_mGoogleRPC = rb_define_module_under(rb_mGoogle, "RPC");
-  rb_mGoogleRpcCore = rb_define_module_under(rb_mGoogleRPC, "Core");
+  rb_mGRPC = rb_define_module("GRPC");
+  rb_mGrpcCore = rb_define_module_under(rb_mGRPC, "Core");
   rb_sNewServerRpc = rb_struct_define("NewServerRpc", "method", "host",
                                       "deadline", "metadata", NULL);
   rb_sStatus = rb_struct_define("Status", "code", "details", "metadata", NULL);
 
-  Init_google_rpc_byte_buffer();
-  Init_google_rpc_event();
-  Init_google_rpc_channel();
-  Init_google_rpc_completion_queue();
-  Init_google_rpc_call();
-  Init_google_rpc_credentials();
-  Init_google_rpc_metadata();
-  Init_google_rpc_server();
-  Init_google_rpc_server_credentials();
-  Init_google_status_codes();
-  Init_google_time_consts();
+  Init_grpc_byte_buffer();
+  Init_grpc_event();
+  Init_grpc_channel();
+  Init_grpc_completion_queue();
+  Init_grpc_call();
+  Init_grpc_credentials();
+  Init_grpc_metadata();
+  Init_grpc_server();
+  Init_grpc_server_credentials();
+  Init_grpc_status_codes();
+  Init_grpc_time_consts();
 }
diff --git a/src/ruby/ext/grpc/rb_grpc.h b/src/ruby/ext/grpc/rb_grpc.h
index d5e8930fca6c5c50dc7646f251a24d38adc62784..851f5ee69fa67c864e6c17fc9b5c79ccbe8de4a3 100644
--- a/src/ruby/ext/grpc/rb_grpc.h
+++ b/src/ruby/ext/grpc/rb_grpc.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,11 +38,8 @@
 #include <ruby.h>
 #include <grpc/support/time.h>
 
-/* rb_mGoogle is the top-level Google module. */
-extern VALUE rb_mGoogle;
-
-/* rb_mGoogleRpcCore is the module containing the ruby wrapper GRPC classes. */
-extern VALUE rb_mGoogleRpcCore;
+/* rb_mGrpcCore is the module containing the ruby wrapper GRPC classes. */
+extern VALUE rb_mGrpcCore;
 
 /* Class used to wrap timeval structs. */
 extern VALUE rb_cTimeVal;
diff --git a/src/ruby/ext/grpc/rb_metadata.c b/src/ruby/ext/grpc/rb_metadata.c
index 88eb62ab738c6731815fb343113f3c3c08132cb1..7622a8c57ed036f2fefd7d1d6255079cd56b0a3e 100644
--- a/src/ruby/ext/grpc/rb_metadata.c
+++ b/src/ruby/ext/grpc/rb_metadata.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -187,9 +187,9 @@ static VALUE grpc_rb_metadata_value(VALUE self) {
 
 /* rb_cMetadata is the Metadata class whose instances proxy grpc_metadata. */
 VALUE rb_cMetadata = Qnil;
-void Init_google_rpc_metadata() {
+void Init_grpc_metadata() {
   rb_cMetadata =
-      rb_define_class_under(rb_mGoogleRpcCore, "Metadata", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "Metadata", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(rb_cMetadata, grpc_rb_metadata_alloc);
diff --git a/src/ruby/ext/grpc/rb_metadata.h b/src/ruby/ext/grpc/rb_metadata.h
index 329ef15c68a54da3165d4aea29b5a8a8030ea959..251072f658d885a37096c0757602d84d86e157ac 100644
--- a/src/ruby/ext/grpc/rb_metadata.h
+++ b/src/ruby/ext/grpc/rb_metadata.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,6 @@ extern VALUE grpc_rb_metadata_create_with_mark(VALUE mark, grpc_metadata* md);
 grpc_metadata* grpc_rb_get_wrapped_metadata(VALUE v);
 
 /* Initializes the Metadata class. */
-void Init_google_rpc_metadata();
+void Init_grpc_metadata();
 
 #endif /* GRPC_RB_METADATA_H_ */
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index e68843e12b1ef2d41e979e584951ab553fb6e88a..5954e27d0249e8315f67553dc2aeadf4b0cf396a 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -251,8 +251,8 @@ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
   return INT2NUM(recvd_port);
 }
 
-void Init_google_rpc_server() {
-  rb_cServer = rb_define_class_under(rb_mGoogleRpcCore, "Server", rb_cObject);
+void Init_grpc_server() {
+  rb_cServer = rb_define_class_under(rb_mGrpcCore, "Server", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(rb_cServer, grpc_rb_server_alloc);
diff --git a/src/ruby/ext/grpc/rb_server.h b/src/ruby/ext/grpc/rb_server.h
index 92047efd18758f6353b033429d623897a25fa701..2726b9a50af422e24571d66c67b6536b0b24425a 100644
--- a/src/ruby/ext/grpc/rb_server.h
+++ b/src/ruby/ext/grpc/rb_server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
 extern VALUE rb_cServer;
 
 /* Initializes the Server class. */
-void Init_google_rpc_server();
+void Init_grpc_server();
 
 /* Gets the wrapped server from the ruby wrapper */
 grpc_server* grpc_rb_get_wrapped_server(VALUE v);
diff --git a/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c
index 4f6c67ea5e3b6936bcd229bd38cb7dbc03829fad..fb02987870622e2a1f62bb6a2fd431fa099b06ea 100644
--- a/src/ruby/ext/grpc/rb_server_credentials.c
+++ b/src/ruby/ext/grpc/rb_server_credentials.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -184,9 +184,9 @@ static VALUE grpc_rb_server_credentials_init(VALUE self, VALUE pem_root_certs,
    grpc_server_credentials. */
 VALUE rb_cServerCredentials = Qnil;
 
-void Init_google_rpc_server_credentials() {
+void Init_grpc_server_credentials() {
   rb_cServerCredentials =
-      rb_define_class_under(rb_mGoogleRpcCore, "ServerCredentials", rb_cObject);
+      rb_define_class_under(rb_mGrpcCore, "ServerCredentials", rb_cObject);
 
   /* Allocates an object managed by the ruby runtime */
   rb_define_alloc_func(rb_cServerCredentials, grpc_rb_server_credentials_alloc);
diff --git a/src/ruby/ext/grpc/rb_server_credentials.h b/src/ruby/ext/grpc/rb_server_credentials.h
index 2a2e1fbc822696f61bf64942b230f5376a77cc2f..ef377195a0535b51d2d8e0b5b85c87a346c712fb 100644
--- a/src/ruby/ext/grpc/rb_server_credentials.h
+++ b/src/ruby/ext/grpc/rb_server_credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@
 extern VALUE rb_cServerCredentials;
 
 /* Initializes the ruby ServerCredentials class. */
-void Init_google_rpc_server_credentials();
+void Init_grpc_server_credentials();
 
 /* Gets the wrapped server_credentials from the ruby wrapper */
 grpc_server_credentials* grpc_rb_get_wrapped_server_credentials(VALUE v);
diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec
index c479cc961676528a90d860c78ee42c65e278ff34..bc59c234e5a4ecf1246344ef61641917855183b2 100755
--- a/src/ruby/grpc.gemspec
+++ b/src/ruby/grpc.gemspec
@@ -5,12 +5,12 @@ require 'grpc/version'
 
 Gem::Specification.new do |s|
   s.name          = 'grpc'
-  s.version       = Google::RPC::VERSION
+  s.version       = GRPC::VERSION
   s.authors       = ['gRPC Authors']
-  s.email         = 'tbetbetbe@gmail.com'
+  s.email         = 'temiola@google.com'
   s.homepage      = 'https://github.com/google/grpc/tree/master/src/ruby'
-  s.summary       = 'Google RPC system in Ruby'
-  s.description   = 'Send RPCs from Ruby using Google\'s RPC system'
+  s.summary       = 'GRPC system in Ruby'
+  s.description   = 'Send RPCs from Ruby using GRPC'
 
   s.files         = `git ls-files`.split("\n")
   s.test_files    = `git ls-files -- spec/*`.split("\n")
diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb
index 758ac0c2d1662d4cec01321afef76a80e6a062f8..a2a609f59ee96d8dbb93cb7aaf3ddcd428e782c3 100644
--- a/src/ruby/lib/grpc.rb
+++ b/src/ruby/lib/grpc.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,3 @@ require 'grpc/generic/active_call'
 require 'grpc/generic/client_stub'
 require 'grpc/generic/service'
 require 'grpc/generic/rpc_server'
-
-# alias GRPC
-GRPC = Google::RPC
diff --git a/src/ruby/lib/grpc/auth/compute_engine.rb b/src/ruby/lib/grpc/auth/compute_engine.rb
index 9004bef46e5d8e0b44bffbcd2db03d46b81cf525..5cb1e1a4dcfaa26b56077e52059bc4b6f463d94f 100644
--- a/src/ruby/lib/grpc/auth/compute_engine.rb
+++ b/src/ruby/lib/grpc/auth/compute_engine.rb
@@ -30,39 +30,37 @@
 require 'faraday'
 require 'grpc/auth/signet'
 
-module Google
-  module RPC
-    # Module Auth provides classes that provide Google-specific authentication
-    # used to access Google gRPC services.
-    module Auth
-      # Extends Signet::OAuth2::Client so that the auth token is obtained from
-      # the GCE metadata server.
-      class GCECredentials < Signet::OAuth2::Client
-        COMPUTE_AUTH_TOKEN_URI = 'http://metadata/computeMetadata/v1/'\
-                                 'instance/service-accounts/default/token'
-        COMPUTE_CHECK_URI = 'http://metadata.google.internal'
+module GRPC
+  # Module Auth provides classes that provide Google-specific authentication
+  # used to access Google gRPC services.
+  module Auth
+    # Extends Signet::OAuth2::Client so that the auth token is obtained from
+    # the GCE metadata server.
+    class GCECredentials < Signet::OAuth2::Client
+      COMPUTE_AUTH_TOKEN_URI = 'http://metadata/computeMetadata/v1/'\
+                               'instance/service-accounts/default/token'
+      COMPUTE_CHECK_URI = 'http://metadata.google.internal'
 
-        # Detect if this appear to be a GCE instance, by checking if metadata
-        # is available
-        def self.on_gce?(options = {})
-          c = options[:connection] || Faraday.default_connection
-          resp = c.get(COMPUTE_CHECK_URI)
-          return false unless resp.status == 200
-          return false unless resp.headers.key?('Metadata-Flavor')
-          return resp.headers['Metadata-Flavor'] == 'Google'
-        rescue Faraday::ConnectionFailed
-          return false
-        end
+      # Detect if this appear to be a GCE instance, by checking if metadata
+      # is available
+      def self.on_gce?(options = {})
+        c = options[:connection] || Faraday.default_connection
+        resp = c.get(COMPUTE_CHECK_URI)
+        return false unless resp.status == 200
+        return false unless resp.headers.key?('Metadata-Flavor')
+        return resp.headers['Metadata-Flavor'] == 'Google'
+      rescue Faraday::ConnectionFailed
+        return false
+      end
 
-        # Overrides the super class method to change how access tokens are
-        # fetched.
-        def fetch_access_token(options = {})
-          c = options[:connection] || Faraday.default_connection
-          c.headers = { 'Metadata-Flavor' => 'Google' }
-          resp = c.get(COMPUTE_AUTH_TOKEN_URI)
-          Signet::OAuth2.parse_credentials(resp.body,
-                                           resp.headers['content-type'])
-        end
+      # Overrides the super class method to change how access tokens are
+      # fetched.
+      def fetch_access_token(options = {})
+        c = options[:connection] || Faraday.default_connection
+        c.headers = { 'Metadata-Flavor' => 'Google' }
+        resp = c.get(COMPUTE_AUTH_TOKEN_URI)
+        Signet::OAuth2.parse_credentials(resp.body,
+                                         resp.headers['content-type'])
       end
     end
   end
diff --git a/src/ruby/lib/grpc/auth/service_account.rb b/src/ruby/lib/grpc/auth/service_account.rb
index 35b5cbfe2de1ff5eff7ee66719ddc586cf661988..14b81a9e034f9527caf46146390b36f2930b867c 100644
--- a/src/ruby/lib/grpc/auth/service_account.rb
+++ b/src/ruby/lib/grpc/auth/service_account.rb
@@ -39,29 +39,27 @@ def read_json_key(json_key_io)
   [json_key['private_key'], json_key['client_email']]
 end
 
-module Google
-  module RPC
-    # Module Auth provides classes that provide Google-specific authentication
-    # used to access Google gRPC services.
-    module Auth
-      # Authenticates requests using Google's Service Account credentials.
-      # (cf https://developers.google.com/accounts/docs/OAuth2ServiceAccount)
-      class ServiceAccountCredentials < Signet::OAuth2::Client
-        TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
-        AUDIENCE = TOKEN_CRED_URI
+module GRPC
+  # Module Auth provides classes that provide Google-specific authentication
+  # used to access Google gRPC services.
+  module Auth
+    # Authenticates requests using Google's Service Account credentials.
+    # (cf https://developers.google.com/accounts/docs/OAuth2ServiceAccount)
+    class ServiceAccountCredentials < Signet::OAuth2::Client
+      TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
+      AUDIENCE = TOKEN_CRED_URI
 
-        # Initializes a ServiceAccountCredentials.
-        #
-        # @param scope [string|array] the scope(s) to access
-        # @param json_key_io [IO] an IO from which the JSON key can be read
-        def initialize(scope, json_key_io)
-          private_key, client_email = read_json_key(json_key_io)
-          super(token_credential_uri: TOKEN_CRED_URI,
-                audience: AUDIENCE,
-                scope: scope,
-                issuer: client_email,
-                signing_key: OpenSSL::PKey::RSA.new(private_key))
-        end
+      # Initializes a ServiceAccountCredentials.
+      #
+      # @param scope [string|array] the scope(s) to access
+      # @param json_key_io [IO] an IO from which the JSON key can be read
+      def initialize(scope, json_key_io)
+        private_key, client_email = read_json_key(json_key_io)
+        super(token_credential_uri: TOKEN_CRED_URI,
+              audience: AUDIENCE,
+              scope: scope,
+              issuer: client_email,
+              signing_key: OpenSSL::PKey::RSA.new(private_key))
       end
     end
   end
diff --git a/src/ruby/lib/grpc/core/event.rb b/src/ruby/lib/grpc/core/event.rb
index 9a333589c214267666f7ef4d3737ab8e9e1aa9ff..194aa8ecac93026d5dbffe31c159ccefbbb2a690 100644
--- a/src/ruby/lib/grpc/core/event.rb
+++ b/src/ruby/lib/grpc/core/event.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,16 +27,17 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-module Google
-  module RPC
-    module Core
-      # Event is a class defined in the c extension
-      #
-      # Here, we add an inspect method.
-      class Event
-        def inspect
-          "<#{self.class}: type:#{type}, tag:#{tag} result:#{result}>"
-        end
+require 'grpc'
+
+# GRPC contains the General RPC module.
+module GRPC
+  module Core
+    # Event is a class defined in the c extension
+    #
+    # Here, we add an inspect method.
+    class Event
+      def inspect
+        "<#{self.class}: type:#{type}, tag:#{tag} result:#{result}>"
       end
     end
   end
diff --git a/src/ruby/lib/grpc/core/time_consts.rb b/src/ruby/lib/grpc/core/time_consts.rb
index 6876dcb02eb4bab02b4afedc199299db06630b86..7750cb0febb0db62e8abf6380880b56d1f1e658b 100644
--- a/src/ruby/lib/grpc/core/time_consts.rb
+++ b/src/ruby/lib/grpc/core/time_consts.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,44 +29,43 @@
 
 require 'grpc'
 
-module Google
-  module RPC
-    module Core
-      # TimeConsts is a module from the C extension.
+# GRPC contains the General RPC module.
+module GRPC
+  module Core
+    # TimeConsts is a module from the C extension.
+    #
+    # Here it's re-opened to add a utility func.
+    module TimeConsts
+      # Converts a time delta to an absolute deadline.
       #
-      # Here it's re-opened to add a utility func.
-      module TimeConsts
-        # Converts a time delta to an absolute deadline.
-        #
-        # Assumes timeish is a relative time, and converts its to an absolute,
-        # with following exceptions:
-        #
-        # * if timish is one of the TimeConsts.TimeSpec constants the value is
-        # preserved.
-        # * timish < 0 => TimeConsts.INFINITE_FUTURE
-        # * timish == 0 => TimeConsts.ZERO
-        #
-        # @param timeish [Number|TimeSpec]
-        # @return timeish [Number|TimeSpec]
-        def from_relative_time(timeish)
-          if timeish.is_a? TimeSpec
-            timeish
-          elsif timeish.nil?
-            TimeConsts::ZERO
-          elsif !timeish.is_a? Numeric
-            fail(TypeError,
-                 "Cannot make an absolute deadline from #{timeish.inspect}")
-          elsif timeish < 0
-            TimeConsts::INFINITE_FUTURE
-          elsif timeish == 0
-            TimeConsts::ZERO
-          else
-            Time.now + timeish
-          end
+      # Assumes timeish is a relative time, and converts its to an absolute,
+      # with following exceptions:
+      #
+      # * if timish is one of the TimeConsts.TimeSpec constants the value is
+      # preserved.
+      # * timish < 0 => TimeConsts.INFINITE_FUTURE
+      # * timish == 0 => TimeConsts.ZERO
+      #
+      # @param timeish [Number|TimeSpec]
+      # @return timeish [Number|TimeSpec]
+      def from_relative_time(timeish)
+        if timeish.is_a? TimeSpec
+          timeish
+        elsif timeish.nil?
+          TimeConsts::ZERO
+        elsif !timeish.is_a? Numeric
+          fail(TypeError,
+               "Cannot make an absolute deadline from #{timeish.inspect}")
+        elsif timeish < 0
+          TimeConsts::INFINITE_FUTURE
+        elsif timeish == 0
+          TimeConsts::ZERO
+        else
+          Time.now + timeish
         end
-
-        module_function :from_relative_time
       end
+
+      module_function :from_relative_time
     end
   end
 end
diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index 70a92bfed771d861f1ccc3b65f3a38af2feef5d8..58944872b54196d5e810202c9fc6e60698e32099 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,35 +29,33 @@
 
 require 'grpc'
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    # OutOfTime is an exception class that indicates that an RPC exceeded its
-    # deadline.
-    OutOfTime = Class.new(StandardError)
+# GRPC contains the General RPC module.
+module GRPC
+  # OutOfTime is an exception class that indicates that an RPC exceeded its
+  # deadline.
+  OutOfTime = Class.new(StandardError)
 
-    # BadStatus is an exception class that indicates that an error occurred at
-    # either end of a GRPC connection.  When raised, it indicates that a status
-    # error should be returned to the other end of a GRPC connection; when
-    # caught it means that this end received a status error.
-    class BadStatus < StandardError
-      attr_reader :code, :details
+  # BadStatus is an exception class that indicates that an error occurred at
+  # either end of a GRPC connection.  When raised, it indicates that a status
+  # error should be returned to the other end of a GRPC connection; when
+  # caught it means that this end received a status error.
+  class BadStatus < StandardError
+    attr_reader :code, :details
 
-      # @param code [Numeric] the status code
-      # @param details [String] the details of the exception
-      def initialize(code, details = 'unknown cause')
-        super("#{code}:#{details}")
-        @code = code
-        @details = details
-      end
+    # @param code [Numeric] the status code
+    # @param details [String] the details of the exception
+    def initialize(code, details = 'unknown cause')
+      super("#{code}:#{details}")
+      @code = code
+      @details = details
+    end
 
-      # Converts the exception to a GRPC::Status for use in the networking
-      # wrapper layer.
-      #
-      # @return [Status] with the same code and details
-      def to_status
-        Status.new(code, details)
-      end
+    # Converts the exception to a GRPC::Status for use in the networking
+    # wrapper layer.
+    #
+    # @return [Status] with the same code and details
+    def to_status
+      Status.new(code, details)
     end
   end
 end
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index 6c2b6e91c24ae91101fa0c0355a5b01fc9146eb8..7b69f1f6d0d461b0ae45dd2437a5b7fc7d42db7c 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -36,502 +36,500 @@ def assert_event_type(ev, want)
   fail "Unexpected rpc event: got #{got}, want #{want}" unless got == want
 end
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    # The ActiveCall class provides simple methods for sending marshallable
-    # data to a call
-    class ActiveCall
-      include Core::CompletionType
-      include Core::StatusCodes
-      include Core::TimeConsts
-      attr_reader(:deadline)
-
-      # client_invoke begins a client invocation.
-      #
-      # Flow Control note: this blocks until flow control accepts that client
-      # request can go ahead.
-      #
-      # deadline is the absolute deadline for the call.
-      #
-      # == Keyword Arguments ==
-      # any keyword arguments are treated as metadata to be sent to the server
-      # if a keyword value is a list, multiple metadata for it's key are sent
-      #
-      # @param call [Call] a call on which to start and invocation
-      # @param q [CompletionQueue] the completion queue
-      # @param deadline [Fixnum,TimeSpec] the deadline
-      def self.client_invoke(call, q, _deadline, **kw)
-        fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
-        unless q.is_a? Core::CompletionQueue
-          fail(ArgumentError, 'not a CompletionQueue')
-        end
-        call.add_metadata(kw) if kw.length > 0
-        client_metadata_read = Object.new
-        finished_tag = Object.new
-        call.invoke(q, client_metadata_read, finished_tag)
-        [finished_tag, client_metadata_read]
-      end
-
-      # Creates an ActiveCall.
-      #
-      # ActiveCall should only be created after a call is accepted.  That
-      # means different things on a client and a server.  On the client, the
-      # call is accepted after calling call.invoke.  On the server, this is
-      # after call.accept.
-      #
-      # #initialize cannot determine if the call is accepted or not; so if a
-      # call that's not accepted is used here, the error won't be visible until
-      # the ActiveCall methods are called.
-      #
-      # deadline is the absolute deadline for the call.
-      #
-      # @param call [Call] the call used by the ActiveCall
-      # @param q [CompletionQueue] the completion queue used to accept
-      #          the call
-      # @param marshal [Function] f(obj)->string that marshal requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [Fixnum] the deadline for the call to complete
-      # @param finished_tag [Object] the object used as the call's finish tag,
-      #                              if the call has begun
-      # @param read_metadata_tag [Object] the object used as the call's finish
-      #                                   tag, if the call has begun
-      # @param started [true|false] indicates if the call has begun
-      def initialize(call, q, marshal, unmarshal, deadline, finished_tag: nil,
-                     read_metadata_tag: nil, started: true)
-        fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
-        unless q.is_a? Core::CompletionQueue
-          fail(ArgumentError, 'not a CompletionQueue')
-        end
-        @call = call
-        @cq = q
-        @deadline = deadline
-        @finished_tag = finished_tag
-        @read_metadata_tag = read_metadata_tag
-        @marshal = marshal
-        @started = started
-        @unmarshal = unmarshal
+# GRPC contains the General RPC module.
+module GRPC
+  # The ActiveCall class provides simple methods for sending marshallable
+  # data to a call
+  class ActiveCall
+    include Core::CompletionType
+    include Core::StatusCodes
+    include Core::TimeConsts
+    attr_reader(:deadline)
+
+    # client_invoke begins a client invocation.
+    #
+    # Flow Control note: this blocks until flow control accepts that client
+    # request can go ahead.
+    #
+    # deadline is the absolute deadline for the call.
+    #
+    # == Keyword Arguments ==
+    # any keyword arguments are treated as metadata to be sent to the server
+    # if a keyword value is a list, multiple metadata for it's key are sent
+    #
+    # @param call [Call] a call on which to start and invocation
+    # @param q [CompletionQueue] the completion queue
+    # @param deadline [Fixnum,TimeSpec] the deadline
+    def self.client_invoke(call, q, _deadline, **kw)
+      fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
+      unless q.is_a? Core::CompletionQueue
+        fail(ArgumentError, 'not a CompletionQueue')
       end
+      call.add_metadata(kw) if kw.length > 0
+      client_metadata_read = Object.new
+      finished_tag = Object.new
+      call.invoke(q, client_metadata_read, finished_tag)
+      [finished_tag, client_metadata_read]
+    end
 
-      # Obtains the status of the call.
-      #
-      # this value is nil until the call completes
-      # @return this call's status
-      def status
-        @call.status
+    # Creates an ActiveCall.
+    #
+    # ActiveCall should only be created after a call is accepted.  That
+    # means different things on a client and a server.  On the client, the
+    # call is accepted after calling call.invoke.  On the server, this is
+    # after call.accept.
+    #
+    # #initialize cannot determine if the call is accepted or not; so if a
+    # call that's not accepted is used here, the error won't be visible until
+    # the ActiveCall methods are called.
+    #
+    # deadline is the absolute deadline for the call.
+    #
+    # @param call [Call] the call used by the ActiveCall
+    # @param q [CompletionQueue] the completion queue used to accept
+    #          the call
+    # @param marshal [Function] f(obj)->string that marshal requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [Fixnum] the deadline for the call to complete
+    # @param finished_tag [Object] the object used as the call's finish tag,
+    #                              if the call has begun
+    # @param read_metadata_tag [Object] the object used as the call's finish
+    #                                   tag, if the call has begun
+    # @param started [true|false] indicates if the call has begun
+    def initialize(call, q, marshal, unmarshal, deadline, finished_tag: nil,
+                   read_metadata_tag: nil, started: true)
+      fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
+      unless q.is_a? Core::CompletionQueue
+        fail(ArgumentError, 'not a CompletionQueue')
       end
+      @call = call
+      @cq = q
+      @deadline = deadline
+      @finished_tag = finished_tag
+      @read_metadata_tag = read_metadata_tag
+      @marshal = marshal
+      @started = started
+      @unmarshal = unmarshal
+    end
 
-      # Obtains the metadata of the call.
-      #
-      # At the start of the call this will be nil.  During the call this gets
-      # some values as soon as the other end of the connection acknowledges the
-      # request.
-      #
-      # @return this calls's metadata
-      def metadata
-        @call.metadata
-      end
+    # Obtains the status of the call.
+    #
+    # this value is nil until the call completes
+    # @return this call's status
+    def status
+      @call.status
+    end
 
-      # Cancels the call.
-      #
-      # Cancels the call.  The call does not return any result, but once this it
-      # has been called, the call should eventually terminate.  Due to potential
-      # races between the execution of the cancel and the in-flight request, the
-      # result of the call after calling #cancel is indeterminate:
-      #
-      # - the call may terminate with a BadStatus exception, with code=CANCELLED
-      # - the call may terminate with OK Status, and return a response
-      # - the call may terminate with a different BadStatus exception if that
-      #   was happening
-      def cancel
-        @call.cancel
-      end
+    # Obtains the metadata of the call.
+    #
+    # At the start of the call this will be nil.  During the call this gets
+    # some values as soon as the other end of the connection acknowledges the
+    # request.
+    #
+    # @return this calls's metadata
+    def metadata
+      @call.metadata
+    end
 
-      # indicates if the call is shutdown
-      def shutdown
-        @shutdown ||= false
-      end
+    # Cancels the call.
+    #
+    # Cancels the call.  The call does not return any result, but once this it
+    # has been called, the call should eventually terminate.  Due to potential
+    # races between the execution of the cancel and the in-flight request, the
+    # result of the call after calling #cancel is indeterminate:
+    #
+    # - the call may terminate with a BadStatus exception, with code=CANCELLED
+    # - the call may terminate with OK Status, and return a response
+    # - the call may terminate with a different BadStatus exception if that
+    #   was happening
+    def cancel
+      @call.cancel
+    end
 
-      # indicates if the call is cancelled.
-      def cancelled
-        @cancelled ||= false
-      end
+    # indicates if the call is shutdown
+    def shutdown
+      @shutdown ||= false
+    end
 
-      # multi_req_view provides a restricted view of this ActiveCall for use
-      # in a server client-streaming handler.
-      def multi_req_view
-        MultiReqView.new(self)
-      end
+    # indicates if the call is cancelled.
+    def cancelled
+      @cancelled ||= false
+    end
 
-      # single_req_view provides a restricted view of this ActiveCall for use in
-      # a server request-response handler.
-      def single_req_view
-        SingleReqView.new(self)
-      end
+    # multi_req_view provides a restricted view of this ActiveCall for use
+    # in a server client-streaming handler.
+    def multi_req_view
+      MultiReqView.new(self)
+    end
 
-      # operation provides a restricted view of this ActiveCall for use as
-      # a Operation.
-      def operation
-        Operation.new(self)
-      end
+    # single_req_view provides a restricted view of this ActiveCall for use in
+    # a server request-response handler.
+    def single_req_view
+      SingleReqView.new(self)
+    end
 
-      # writes_done indicates that all writes are completed.
-      #
-      # It blocks until the remote endpoint acknowledges by sending a FINISHED
-      # event, unless assert_finished is set to false.  Any calls to
-      # #remote_send after this call will fail.
-      #
-      # @param assert_finished [true, false] when true(default), waits for
-      # FINISHED.
-      def writes_done(assert_finished = true)
-        @call.writes_done(self)
-        ev = @cq.pluck(self, INFINITE_FUTURE)
-        begin
-          assert_event_type(ev, FINISH_ACCEPTED)
-          logger.debug("Writes done: waiting for finish? #{assert_finished}")
-        ensure
-          ev.close
-        end
+    # operation provides a restricted view of this ActiveCall for use as
+    # a Operation.
+    def operation
+      Operation.new(self)
+    end
 
-        return unless assert_finished
-        ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
-        fail 'unexpected nil event' if ev.nil?
+    # writes_done indicates that all writes are completed.
+    #
+    # It blocks until the remote endpoint acknowledges by sending a FINISHED
+    # event, unless assert_finished is set to false.  Any calls to
+    # #remote_send after this call will fail.
+    #
+    # @param assert_finished [true, false] when true(default), waits for
+    # FINISHED.
+    def writes_done(assert_finished = true)
+      @call.writes_done(self)
+      ev = @cq.pluck(self, INFINITE_FUTURE)
+      begin
+        assert_event_type(ev, FINISH_ACCEPTED)
+        logger.debug("Writes done: waiting for finish? #{assert_finished}")
+      ensure
         ev.close
-        @call.status
       end
 
-      # finished waits until the call is completed.
-      #
-      # It blocks until the remote endpoint acknowledges by sending a FINISHED
-      # event.
-      def finished
-        ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
-        begin
-          fail "unexpected event: #{ev.inspect}" unless ev.type == FINISHED
-          if @call.metadata.nil?
-            @call.metadata = ev.result.metadata
-          else
-            @call.metadata.merge!(ev.result.metadata)
-          end
-
-          if ev.result.code != Core::StatusCodes::OK
-            fail BadStatus.new(ev.result.code, ev.result.details)
-          end
-          res = ev.result
-        ensure
-          ev.close
-        end
-        res
-      end
+      return unless assert_finished
+      ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
+      fail 'unexpected nil event' if ev.nil?
+      ev.close
+      @call.status
+    end
 
-      # remote_send sends a request to the remote endpoint.
-      #
-      # It blocks until the remote endpoint acknowledges by sending a
-      # WRITE_ACCEPTED.  req can be marshalled already.
-      #
-      # @param req [Object, String] the object to send or it's marshal form.
-      # @param marshalled [false, true] indicates if the object is already
-      # marshalled.
-      def remote_send(req, marshalled = false)
-        assert_queue_is_ready
-        logger.debug("sending #{req.inspect}, marshalled? #{marshalled}")
-        if marshalled
-          payload = req
+    # finished waits until the call is completed.
+    #
+    # It blocks until the remote endpoint acknowledges by sending a FINISHED
+    # event.
+    def finished
+      ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
+      begin
+        fail "unexpected event: #{ev.inspect}" unless ev.type == FINISHED
+        if @call.metadata.nil?
+          @call.metadata = ev.result.metadata
         else
-          payload = @marshal.call(req)
-        end
-        @call.start_write(Core::ByteBuffer.new(payload), self)
-
-        # call queue#pluck, and wait for WRITE_ACCEPTED, so as not to return
-        # until the flow control allows another send on this call.
-        ev = @cq.pluck(self, INFINITE_FUTURE)
-        begin
-          assert_event_type(ev, WRITE_ACCEPTED)
-        ensure
-          ev.close
+          @call.metadata.merge!(ev.result.metadata)
         end
-      end
 
-      # send_status sends a status to the remote endpoint
-      #
-      # @param code [int] the status code to send
-      # @param details [String] details
-      # @param assert_finished [true, false] when true(default), waits for
-      # FINISHED.
-      def send_status(code = OK, details = '', assert_finished = false)
-        assert_queue_is_ready
-        @call.start_write_status(code, details, self)
-        ev = @cq.pluck(self, INFINITE_FUTURE)
-        begin
-          assert_event_type(ev, FINISH_ACCEPTED)
-        ensure
-          ev.close
+        if ev.result.code != Core::StatusCodes::OK
+          fail BadStatus.new(ev.result.code, ev.result.details)
         end
-        logger.debug("Status sent: #{code}:'#{details}'")
-        return finished if assert_finished
-        nil
+        res = ev.result
+      ensure
+        ev.close
       end
+      res
+    end
 
-      # remote_read reads a response from the remote endpoint.
-      #
-      # It blocks until the remote endpoint sends a READ or FINISHED event.  On
-      # a READ, it returns the response after unmarshalling it. On
-      # FINISHED, it returns nil if the status is OK, otherwise raising
-      # BadStatus
-      def remote_read
-        if @call.metadata.nil? && !@read_metadata_tag.nil?
-          ev = @cq.pluck(@read_metadata_tag, INFINITE_FUTURE)
-          assert_event_type(ev, CLIENT_METADATA_READ)
-          @call.metadata = ev.result
-          @read_metadata_tag = nil
-        end
+    # remote_send sends a request to the remote endpoint.
+    #
+    # It blocks until the remote endpoint acknowledges by sending a
+    # WRITE_ACCEPTED.  req can be marshalled already.
+    #
+    # @param req [Object, String] the object to send or it's marshal form.
+    # @param marshalled [false, true] indicates if the object is already
+    # marshalled.
+    def remote_send(req, marshalled = false)
+      assert_queue_is_ready
+      logger.debug("sending #{req.inspect}, marshalled? #{marshalled}")
+      if marshalled
+        payload = req
+      else
+        payload = @marshal.call(req)
+      end
+      @call.start_write(Core::ByteBuffer.new(payload), self)
+
+      # call queue#pluck, and wait for WRITE_ACCEPTED, so as not to return
+      # until the flow control allows another send on this call.
+      ev = @cq.pluck(self, INFINITE_FUTURE)
+      begin
+        assert_event_type(ev, WRITE_ACCEPTED)
+      ensure
+        ev.close
+      end
+    end
 
-        @call.start_read(self)
-        ev = @cq.pluck(self, INFINITE_FUTURE)
-        begin
-          assert_event_type(ev, READ)
-          logger.debug("received req: #{ev.result.inspect}")
-          unless ev.result.nil?
-            logger.debug("received req.to_s: #{ev.result}")
-            res = @unmarshal.call(ev.result.to_s)
-            logger.debug("received_req (unmarshalled): #{res.inspect}")
-            return res
-          end
-        ensure
-          ev.close
-        end
-        logger.debug('found nil; the final response has been sent')
-        nil
+    # send_status sends a status to the remote endpoint
+    #
+    # @param code [int] the status code to send
+    # @param details [String] details
+    # @param assert_finished [true, false] when true(default), waits for
+    # FINISHED.
+    def send_status(code = OK, details = '', assert_finished = false)
+      assert_queue_is_ready
+      @call.start_write_status(code, details, self)
+      ev = @cq.pluck(self, INFINITE_FUTURE)
+      begin
+        assert_event_type(ev, FINISH_ACCEPTED)
+      ensure
+        ev.close
       end
+      logger.debug("Status sent: #{code}:'#{details}'")
+      return finished if assert_finished
+      nil
+    end
 
-      # each_remote_read passes each response to the given block or returns an
-      # enumerator the responses if no block is given.
-      #
-      # == Enumerator ==
-      #
-      # * #next blocks until the remote endpoint sends a READ or FINISHED
-      # * for each read, enumerator#next yields the response
-      # * on status
-      #    * if it's is OK, enumerator#next raises StopException
-      #    * if is not OK, enumerator#next raises RuntimeException
-      #
-      # == Block ==
-      #
-      # * if provided it is executed for each response
-      # * the call blocks until no more responses are provided
-      #
-      # @return [Enumerator] if no block was given
-      def each_remote_read
-        return enum_for(:each_remote_read) unless block_given?
-        loop do
-          resp = remote_read
-          break if resp.is_a? Struct::Status  # is an OK status
-          break if resp.nil?  # the last response was received
-          yield resp
-        end
+    # remote_read reads a response from the remote endpoint.
+    #
+    # It blocks until the remote endpoint sends a READ or FINISHED event.  On
+    # a READ, it returns the response after unmarshalling it. On
+    # FINISHED, it returns nil if the status is OK, otherwise raising
+    # BadStatus
+    def remote_read
+      if @call.metadata.nil? && !@read_metadata_tag.nil?
+        ev = @cq.pluck(@read_metadata_tag, INFINITE_FUTURE)
+        assert_event_type(ev, CLIENT_METADATA_READ)
+        @call.metadata = ev.result
+        @read_metadata_tag = nil
       end
 
-      # each_remote_read_then_finish passes each response to the given block or
-      # returns an enumerator of the responses if no block is given.
-      #
-      # It is like each_remote_read, but it blocks on finishing on detecting
-      # the final message.
-      #
-      # == Enumerator ==
-      #
-      # * #next blocks until the remote endpoint sends a READ or FINISHED
-      # * for each read, enumerator#next yields the response
-      # * on status
-      #    * if it's is OK, enumerator#next raises StopException
-      #    * if is not OK, enumerator#next raises RuntimeException
-      #
-      # == Block ==
-      #
-      # * if provided it is executed for each response
-      # * the call blocks until no more responses are provided
-      #
-      # @return [Enumerator] if no block was given
-      def each_remote_read_then_finish
-        return enum_for(:each_remote_read_then_finish) unless block_given?
-        loop do
-          resp = remote_read
-          break if resp.is_a? Struct::Status  # is an OK status
-          if resp.nil?  # the last response was received, but not finished yet
-            finished
-            break
-          end
-          yield resp
+      @call.start_read(self)
+      ev = @cq.pluck(self, INFINITE_FUTURE)
+      begin
+        assert_event_type(ev, READ)
+        logger.debug("received req: #{ev.result.inspect}")
+        unless ev.result.nil?
+          logger.debug("received req.to_s: #{ev.result}")
+          res = @unmarshal.call(ev.result.to_s)
+          logger.debug("received_req (unmarshalled): #{res.inspect}")
+          return res
         end
+      ensure
+        ev.close
       end
+      logger.debug('found nil; the final response has been sent')
+      nil
+    end
 
-      # request_response sends a request to a GRPC server, and returns the
-      # response.
-      #
-      # == Keyword Arguments ==
-      # any keyword arguments are treated as metadata to be sent to the server
-      # if a keyword value is a list, multiple metadata for it's key are sent
-      #
-      # @param req [Object] the request sent to the server
-      # @return [Object] the response received from the server
-      def request_response(req, **kw)
-        start_call(**kw) unless @started
-        remote_send(req)
-        writes_done(false)
-        response = remote_read
-        finished unless response.is_a? Struct::Status
-        response
+    # each_remote_read passes each response to the given block or returns an
+    # enumerator the responses if no block is given.
+    #
+    # == Enumerator ==
+    #
+    # * #next blocks until the remote endpoint sends a READ or FINISHED
+    # * for each read, enumerator#next yields the response
+    # * on status
+    #    * if it's is OK, enumerator#next raises StopException
+    #    * if is not OK, enumerator#next raises RuntimeException
+    #
+    # == Block ==
+    #
+    # * if provided it is executed for each response
+    # * the call blocks until no more responses are provided
+    #
+    # @return [Enumerator] if no block was given
+    def each_remote_read
+      return enum_for(:each_remote_read) unless block_given?
+      loop do
+        resp = remote_read
+        break if resp.is_a? Struct::Status  # is an OK status
+        break if resp.nil?  # the last response was received
+        yield resp
       end
+    end
 
-      # client_streamer sends a stream of requests to a GRPC server, and
-      # returns a single response.
-      #
-      # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
-      # #each enumeration protocol. In the simplest case, requests will be an
-      # array of marshallable objects; in typical case it will be an Enumerable
-      # that allows dynamic construction of the marshallable objects.
-      #
-      # == Keyword Arguments ==
-      # any keyword arguments are treated as metadata to be sent to the server
-      # if a keyword value is a list, multiple metadata for it's key are sent
-      #
-      # @param requests [Object] an Enumerable of requests to send
-      # @return [Object] the response received from the server
-      def client_streamer(requests, **kw)
-        start_call(**kw) unless @started
-        requests.each { |r| remote_send(r) }
-        writes_done(false)
-        response = remote_read
-        finished unless response.is_a? Struct::Status
-        response
+    # each_remote_read_then_finish passes each response to the given block or
+    # returns an enumerator of the responses if no block is given.
+    #
+    # It is like each_remote_read, but it blocks on finishing on detecting
+    # the final message.
+    #
+    # == Enumerator ==
+    #
+    # * #next blocks until the remote endpoint sends a READ or FINISHED
+    # * for each read, enumerator#next yields the response
+    # * on status
+    #    * if it's is OK, enumerator#next raises StopException
+    #    * if is not OK, enumerator#next raises RuntimeException
+    #
+    # == Block ==
+    #
+    # * if provided it is executed for each response
+    # * the call blocks until no more responses are provided
+    #
+    # @return [Enumerator] if no block was given
+    def each_remote_read_then_finish
+      return enum_for(:each_remote_read_then_finish) unless block_given?
+      loop do
+        resp = remote_read
+        break if resp.is_a? Struct::Status  # is an OK status
+        if resp.nil?  # the last response was received, but not finished yet
+          finished
+          break
+        end
+        yield resp
       end
+    end
 
-      # server_streamer sends one request to the GRPC server, which yields a
-      # stream of responses.
-      #
-      # responses provides an enumerator over the streamed responses, i.e. it
-      # follows Ruby's #each iteration protocol.  The enumerator blocks while
-      # waiting for each response, stops when the server signals that no
-      # further responses will be supplied.  If the implicit block is provided,
-      # it is executed with each response as the argument and no result is
-      # returned.
-      #
-      # == Keyword Arguments ==
-      # any keyword arguments are treated as metadata to be sent to the server
-      # if a keyword value is a list, multiple metadata for it's key are sent
-      # any keyword arguments are treated as metadata to be sent to the server.
-      #
-      # @param req [Object] the request sent to the server
-      # @return [Enumerator|nil] a response Enumerator
-      def server_streamer(req, **kw)
-        start_call(**kw) unless @started
-        remote_send(req)
-        writes_done(false)
-        replies = enum_for(:each_remote_read_then_finish)
-        return replies unless block_given?
-        replies.each { |r| yield r }
-      end
+    # request_response sends a request to a GRPC server, and returns the
+    # response.
+    #
+    # == Keyword Arguments ==
+    # any keyword arguments are treated as metadata to be sent to the server
+    # if a keyword value is a list, multiple metadata for it's key are sent
+    #
+    # @param req [Object] the request sent to the server
+    # @return [Object] the response received from the server
+    def request_response(req, **kw)
+      start_call(**kw) unless @started
+      remote_send(req)
+      writes_done(false)
+      response = remote_read
+      finished unless response.is_a? Struct::Status
+      response
+    end
 
-      # bidi_streamer sends a stream of requests to the GRPC server, and yields
-      # a stream of responses.
-      #
-      # This method takes an Enumerable of requests, and returns and enumerable
-      # of responses.
-      #
-      # == requests ==
-      #
-      # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
-      # #each enumeration protocol. In the simplest case, requests will be an
-      # array of marshallable objects; in typical case it will be an
-      # Enumerable that allows dynamic construction of the marshallable
-      # objects.
-      #
-      # == responses ==
-      #
-      # This is an enumerator of responses.  I.e, its #next method blocks
-      # waiting for the next response.  Also, if at any point the block needs
-      # to consume all the remaining responses, this can be done using #each or
-      # #collect.  Calling #each or #collect should only be done if
-      # the_call#writes_done has been called, otherwise the block will loop
-      # forever.
-      #
-      # == Keyword Arguments ==
-      # any keyword arguments are treated as metadata to be sent to the server
-      # if a keyword value is a list, multiple metadata for it's key are sent
-      #
-      # @param requests [Object] an Enumerable of requests to send
-      # @return [Enumerator, nil] a response Enumerator
-      def bidi_streamer(requests, **kw, &blk)
-        start_call(**kw) unless @started
-        bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline,
-                          @finished_tag)
-        bd.run_on_client(requests, &blk)
-      end
+    # client_streamer sends a stream of requests to a GRPC server, and
+    # returns a single response.
+    #
+    # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
+    # #each enumeration protocol. In the simplest case, requests will be an
+    # array of marshallable objects; in typical case it will be an Enumerable
+    # that allows dynamic construction of the marshallable objects.
+    #
+    # == Keyword Arguments ==
+    # any keyword arguments are treated as metadata to be sent to the server
+    # if a keyword value is a list, multiple metadata for it's key are sent
+    #
+    # @param requests [Object] an Enumerable of requests to send
+    # @return [Object] the response received from the server
+    def client_streamer(requests, **kw)
+      start_call(**kw) unless @started
+      requests.each { |r| remote_send(r) }
+      writes_done(false)
+      response = remote_read
+      finished unless response.is_a? Struct::Status
+      response
+    end
 
-      # run_server_bidi orchestrates a BiDi stream processing on a server.
-      #
-      # N.B. gen_each_reply is a func(Enumerable<Requests>)
-      #
-      # It takes an enumerable of requests as an arg, in case there is a
-      # relationship between the stream of requests and the stream of replies.
-      #
-      # This does not mean that must necessarily be one.  E.g, the replies
-      # produced by gen_each_reply could ignore the received_msgs
-      #
-      # @param gen_each_reply [Proc] generates the BiDi stream replies
-      def run_server_bidi(gen_each_reply)
-        bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline,
-                          @finished_tag)
-        bd.run_on_server(gen_each_reply)
-      end
+    # server_streamer sends one request to the GRPC server, which yields a
+    # stream of responses.
+    #
+    # responses provides an enumerator over the streamed responses, i.e. it
+    # follows Ruby's #each iteration protocol.  The enumerator blocks while
+    # waiting for each response, stops when the server signals that no
+    # further responses will be supplied.  If the implicit block is provided,
+    # it is executed with each response as the argument and no result is
+    # returned.
+    #
+    # == Keyword Arguments ==
+    # any keyword arguments are treated as metadata to be sent to the server
+    # if a keyword value is a list, multiple metadata for it's key are sent
+    # any keyword arguments are treated as metadata to be sent to the server.
+    #
+    # @param req [Object] the request sent to the server
+    # @return [Enumerator|nil] a response Enumerator
+    def server_streamer(req, **kw)
+      start_call(**kw) unless @started
+      remote_send(req)
+      writes_done(false)
+      replies = enum_for(:each_remote_read_then_finish)
+      return replies unless block_given?
+      replies.each { |r| yield r }
+    end
+
+    # bidi_streamer sends a stream of requests to the GRPC server, and yields
+    # a stream of responses.
+    #
+    # This method takes an Enumerable of requests, and returns and enumerable
+    # of responses.
+    #
+    # == requests ==
+    #
+    # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
+    # #each enumeration protocol. In the simplest case, requests will be an
+    # array of marshallable objects; in typical case it will be an
+    # Enumerable that allows dynamic construction of the marshallable
+    # objects.
+    #
+    # == responses ==
+    #
+    # This is an enumerator of responses.  I.e, its #next method blocks
+    # waiting for the next response.  Also, if at any point the block needs
+    # to consume all the remaining responses, this can be done using #each or
+    # #collect.  Calling #each or #collect should only be done if
+    # the_call#writes_done has been called, otherwise the block will loop
+    # forever.
+    #
+    # == Keyword Arguments ==
+    # any keyword arguments are treated as metadata to be sent to the server
+    # if a keyword value is a list, multiple metadata for it's key are sent
+    #
+    # @param requests [Object] an Enumerable of requests to send
+    # @return [Enumerator, nil] a response Enumerator
+    def bidi_streamer(requests, **kw, &blk)
+      start_call(**kw) unless @started
+      bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline,
+                        @finished_tag)
+      bd.run_on_client(requests, &blk)
+    end
 
-      private
+    # run_server_bidi orchestrates a BiDi stream processing on a server.
+    #
+    # N.B. gen_each_reply is a func(Enumerable<Requests>)
+    #
+    # It takes an enumerable of requests as an arg, in case there is a
+    # relationship between the stream of requests and the stream of replies.
+    #
+    # This does not mean that must necessarily be one.  E.g, the replies
+    # produced by gen_each_reply could ignore the received_msgs
+    #
+    # @param gen_each_reply [Proc] generates the BiDi stream replies
+    def run_server_bidi(gen_each_reply)
+      bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline,
+                        @finished_tag)
+      bd.run_on_server(gen_each_reply)
+    end
 
-      def start_call(**kw)
-        tags = ActiveCall.client_invoke(@call, @cq, @deadline, **kw)
-        @finished_tag, @read_metadata_tag = tags
-        @started = true
-      end
+    private
 
-      def self.view_class(*visible_methods)
-        Class.new do
-          extend ::Forwardable
-          def_delegators :@wrapped, *visible_methods
+    def start_call(**kw)
+      tags = ActiveCall.client_invoke(@call, @cq, @deadline, **kw)
+      @finished_tag, @read_metadata_tag = tags
+      @started = true
+    end
 
-          # @param wrapped [ActiveCall] the call whose methods are shielded
-          def initialize(wrapped)
-            @wrapped = wrapped
-          end
+    def self.view_class(*visible_methods)
+      Class.new do
+        extend ::Forwardable
+        def_delegators :@wrapped, *visible_methods
+
+        # @param wrapped [ActiveCall] the call whose methods are shielded
+        def initialize(wrapped)
+          @wrapped = wrapped
         end
       end
+    end
 
-      # SingleReqView limits access to an ActiveCall's methods for use in server
-      # handlers that receive just one request.
-      SingleReqView = view_class(:cancelled, :deadline)
-
-      # MultiReqView limits access to an ActiveCall's methods for use in
-      # server client_streamer handlers.
-      MultiReqView = view_class(:cancelled, :deadline, :each_queued_msg,
-                                :each_remote_read)
-
-      # Operation limits access to an ActiveCall's methods for use as
-      # a Operation on the client.
-      Operation = view_class(:cancel, :cancelled, :deadline, :execute,
-                             :metadata, :status)
-
-      # confirms that no events are enqueued, and that the queue is not
-      # shutdown.
-      def assert_queue_is_ready
-        ev = nil
-        begin
-          ev = @cq.pluck(self, ZERO)
-          fail "unexpected event #{ev.inspect}" unless ev.nil?
-        rescue OutOfTime
-          logging.debug('timed out waiting for next event')
-          # expected, nothing should be on the queue and the deadline was ZERO,
-          # except things using another tag
-        ensure
-          ev.close unless ev.nil?
-        end
+    # SingleReqView limits access to an ActiveCall's methods for use in server
+    # handlers that receive just one request.
+    SingleReqView = view_class(:cancelled, :deadline)
+
+    # MultiReqView limits access to an ActiveCall's methods for use in
+    # server client_streamer handlers.
+    MultiReqView = view_class(:cancelled, :deadline, :each_queued_msg,
+                              :each_remote_read)
+
+    # Operation limits access to an ActiveCall's methods for use as
+    # a Operation on the client.
+    Operation = view_class(:cancel, :cancelled, :deadline, :execute,
+                           :metadata, :status)
+
+    # confirms that no events are enqueued, and that the queue is not
+    # shutdown.
+    def assert_queue_is_ready
+      ev = nil
+      begin
+        ev = @cq.pluck(self, ZERO)
+        fail "unexpected event #{ev.inspect}" unless ev.nil?
+      rescue OutOfTime
+        logging.debug('timed out waiting for next event')
+        # expected, nothing should be on the queue and the deadline was ZERO,
+        # except things using another tag
+      ensure
+        ev.close unless ev.nil?
       end
     end
   end
diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 099d57151c090b5be60887fd8e1b9cf50a087867..c66deaae60836e6396c269e65214da698e0f37a5 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -36,186 +36,184 @@ def assert_event_type(ev, want)
   fail("Unexpected rpc event: got #{got}, want #{want}") unless got == want
 end
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    # The BiDiCall class orchestrates exection of a BiDi stream on a client or
-    # server.
-    class BidiCall
-      include Core::CompletionType
-      include Core::StatusCodes
-      include Core::TimeConsts
+# GRPC contains the General RPC module.
+module GRPC
+  # The BiDiCall class orchestrates exection of a BiDi stream on a client or
+  # server.
+  class BidiCall
+    include Core::CompletionType
+    include Core::StatusCodes
+    include Core::TimeConsts
 
-      # Creates a BidiCall.
-      #
-      # BidiCall should only be created after a call is accepted.  That means
-      # different things on a client and a server.  On the client, the call is
-      # accepted after call.invoke. On the server, this is after call.accept.
-      #
-      # #initialize cannot determine if the call is accepted or not; so if a
-      # call that's not accepted is used here, the error won't be visible until
-      # the BidiCall#run is called.
-      #
-      # deadline is the absolute deadline for the call.
-      #
-      # @param call [Call] the call used by the ActiveCall
-      # @param q [CompletionQueue] the completion queue used to accept
-      #          the call
-      # @param marshal [Function] f(obj)->string that marshal requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [Fixnum] the deadline for the call to complete
-      # @param finished_tag [Object] the object used as the call's finish tag,
-      def initialize(call, q, marshal, unmarshal, deadline, finished_tag)
-        fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
-        unless q.is_a? Core::CompletionQueue
-          fail(ArgumentError, 'not a CompletionQueue')
-        end
-        @call = call
-        @cq = q
-        @deadline = deadline
-        @finished_tag = finished_tag
-        @marshal = marshal
-        @readq = Queue.new
-        @unmarshal = unmarshal
+    # Creates a BidiCall.
+    #
+    # BidiCall should only be created after a call is accepted.  That means
+    # different things on a client and a server.  On the client, the call is
+    # accepted after call.invoke. On the server, this is after call.accept.
+    #
+    # #initialize cannot determine if the call is accepted or not; so if a
+    # call that's not accepted is used here, the error won't be visible until
+    # the BidiCall#run is called.
+    #
+    # deadline is the absolute deadline for the call.
+    #
+    # @param call [Call] the call used by the ActiveCall
+    # @param q [CompletionQueue] the completion queue used to accept
+    #          the call
+    # @param marshal [Function] f(obj)->string that marshal requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [Fixnum] the deadline for the call to complete
+    # @param finished_tag [Object] the object used as the call's finish tag,
+    def initialize(call, q, marshal, unmarshal, deadline, finished_tag)
+      fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
+      unless q.is_a? Core::CompletionQueue
+        fail(ArgumentError, 'not a CompletionQueue')
       end
+      @call = call
+      @cq = q
+      @deadline = deadline
+      @finished_tag = finished_tag
+      @marshal = marshal
+      @readq = Queue.new
+      @unmarshal = unmarshal
+    end
 
-      # Begins orchestration of the Bidi stream for a client sending requests.
-      #
-      # The method either returns an Enumerator of the responses, or accepts a
-      # block that can be invoked with each response.
-      #
-      # @param requests the Enumerable of requests to send
-      # @return an Enumerator of requests to yield
-      def run_on_client(requests, &blk)
-        enq_th = start_write_loop(requests)
-        loop_th = start_read_loop
-        replies = each_queued_msg
-        return replies if blk.nil?
-        replies.each { |r| blk.call(r) }
-        enq_th.join
-        loop_th.join
-      end
+    # Begins orchestration of the Bidi stream for a client sending requests.
+    #
+    # The method either returns an Enumerator of the responses, or accepts a
+    # block that can be invoked with each response.
+    #
+    # @param requests the Enumerable of requests to send
+    # @return an Enumerator of requests to yield
+    def run_on_client(requests, &blk)
+      enq_th = start_write_loop(requests)
+      loop_th = start_read_loop
+      replies = each_queued_msg
+      return replies if blk.nil?
+      replies.each { |r| blk.call(r) }
+      enq_th.join
+      loop_th.join
+    end
 
-      # Begins orchestration of the Bidi stream for a server generating replies.
-      #
-      # N.B. gen_each_reply is a func(Enumerable<Requests>)
-      #
-      # It takes an enumerable of requests as an arg, in case there is a
-      # relationship between the stream of requests and the stream of replies.
-      #
-      # This does not mean that must necessarily be one.  E.g, the replies
-      # produced by gen_each_reply could ignore the received_msgs
-      #
-      # @param gen_each_reply [Proc] generates the BiDi stream replies.
-      def run_on_server(gen_each_reply)
-        replys = gen_each_reply.call(each_queued_msg)
-        enq_th = start_write_loop(replys, is_client: false)
-        loop_th = start_read_loop
-        loop_th.join
-        enq_th.join
-      end
+    # Begins orchestration of the Bidi stream for a server generating replies.
+    #
+    # N.B. gen_each_reply is a func(Enumerable<Requests>)
+    #
+    # It takes an enumerable of requests as an arg, in case there is a
+    # relationship between the stream of requests and the stream of replies.
+    #
+    # This does not mean that must necessarily be one.  E.g, the replies
+    # produced by gen_each_reply could ignore the received_msgs
+    #
+    # @param gen_each_reply [Proc] generates the BiDi stream replies.
+    def run_on_server(gen_each_reply)
+      replys = gen_each_reply.call(each_queued_msg)
+      enq_th = start_write_loop(replys, is_client: false)
+      loop_th = start_read_loop
+      loop_th.join
+      enq_th.join
+    end
 
-      private
+    private
 
-      END_OF_READS = :end_of_reads
-      END_OF_WRITES = :end_of_writes
+    END_OF_READS = :end_of_reads
+    END_OF_WRITES = :end_of_writes
 
-      # 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
-          logger.debug("each_queued_msg: msg##{count}")
-          count += 1
-          req = @readq.pop
-          throw req if req.is_a? StandardError
-          break if req.equal?(END_OF_READS)
-          yield req
-        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
+        logger.debug("each_queued_msg: msg##{count}")
+        count += 1
+        req = @readq.pop
+        throw req if req.is_a? StandardError
+        break if req.equal?(END_OF_READS)
+        yield req
       end
+    end
 
-      # during bidi-streaming, read the requests to send from a separate thread
-      # read so that read_loop does not block waiting for requests to read.
-      def start_write_loop(requests, is_client: true)
-        Thread.new do  # TODO: run on a thread pool
-          write_tag = Object.new
-          begin
-            count = 0
-            requests.each do |req|
-              count += 1
-              payload = @marshal.call(req)
-              @call.start_write(Core::ByteBuffer.new(payload), write_tag)
-              ev = @cq.pluck(write_tag, INFINITE_FUTURE)
-              begin
-                assert_event_type(ev, WRITE_ACCEPTED)
-              ensure
-                ev.close
-              end
+    # during bidi-streaming, read the requests to send from a separate thread
+    # read so that read_loop does not block waiting for requests to read.
+    def start_write_loop(requests, is_client: true)
+      Thread.new do  # TODO: run on a thread pool
+        write_tag = Object.new
+        begin
+          count = 0
+          requests.each do |req|
+            count += 1
+            payload = @marshal.call(req)
+            @call.start_write(Core::ByteBuffer.new(payload), write_tag)
+            ev = @cq.pluck(write_tag, INFINITE_FUTURE)
+            begin
+              assert_event_type(ev, WRITE_ACCEPTED)
+            ensure
+              ev.close
             end
-            if is_client
-              @call.writes_done(write_tag)
-              ev = @cq.pluck(write_tag, INFINITE_FUTURE)
-              begin
-                assert_event_type(ev, FINISH_ACCEPTED)
-              ensure
-                ev.close
-              end
-              logger.debug("bidi-client: sent #{count} reqs, waiting to finish")
-              ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
-              begin
-                assert_event_type(ev, FINISHED)
-              ensure
-                ev.close
-              end
-              logger.debug('bidi-client: finished received')
+          end
+          if is_client
+            @call.writes_done(write_tag)
+            ev = @cq.pluck(write_tag, INFINITE_FUTURE)
+            begin
+              assert_event_type(ev, FINISH_ACCEPTED)
+            ensure
+              ev.close
             end
-          rescue StandardError => e
-            logger.warn('bidi: write_loop failed')
-            logger.warn(e)
+            logger.debug("bidi-client: sent #{count} reqs, waiting to finish")
+            ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
+            begin
+              assert_event_type(ev, FINISHED)
+            ensure
+              ev.close
+            end
+            logger.debug('bidi-client: finished received')
           end
+        rescue StandardError => e
+          logger.warn('bidi: write_loop failed')
+          logger.warn(e)
         end
       end
+    end
 
-      # starts the read loop
-      def start_read_loop
-        Thread.new do
-          begin
-            read_tag = Object.new
-            count = 0
-
-            # queue the initial read before beginning the loop
-            loop do
-              logger.debug("waiting for read #{count}")
-              count += 1
-              @call.start_read(read_tag)
-              ev = @cq.pluck(read_tag, INFINITE_FUTURE)
-              begin
-                assert_event_type(ev, READ)
+    # starts the read loop
+    def start_read_loop
+      Thread.new do
+        begin
+          read_tag = Object.new
+          count = 0
 
-                # handle the next event.
-                if ev.result.nil?
-                  @readq.push(END_OF_READS)
-                  logger.debug('done reading!')
-                  break
-                end
+          # queue the initial read before beginning the loop
+          loop do
+            logger.debug("waiting for read #{count}")
+            count += 1
+            @call.start_read(read_tag)
+            ev = @cq.pluck(read_tag, INFINITE_FUTURE)
+            begin
+              assert_event_type(ev, READ)
 
-                # push the latest read onto the queue and continue reading
-                logger.debug("received req: #{ev.result}")
-                res = @unmarshal.call(ev.result.to_s)
-                @readq.push(res)
-              ensure
-                ev.close
+              # handle the next event.
+              if ev.result.nil?
+                @readq.push(END_OF_READS)
+                logger.debug('done reading!')
+                break
               end
-            end
 
-          rescue StandardError => e
-            logger.warn('bidi: read_loop failed')
-            logger.warn(e)
-            @readq.push(e)  # let each_queued_msg terminate with this error
+              # push the latest read onto the queue and continue reading
+              logger.debug("received req: #{ev.result}")
+              res = @unmarshal.call(ev.result.to_s)
+              @readq.push(res)
+            ensure
+              ev.close
+            end
           end
+
+        rescue StandardError => e
+          logger.warn('bidi: read_loop failed')
+          logger.warn(e)
+          @readq.push(e)  # let each_queued_msg terminate with this error
         end
       end
     end
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 7e13de19ca5bd126f60a729137d1d68b6f232577..7fc0d83501a1f0415dbaa9f939b98d3e0e4358d2 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -30,381 +30,379 @@
 require 'grpc/generic/active_call'
 require 'xray/thread_dump_signal_handler'
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    # ClientStub represents an endpoint used to send requests to GRPC servers.
-    class ClientStub
-      include Core::StatusCodes
+# GRPC contains the General RPC module.
+module GRPC
+  # ClientStub represents an endpoint used to send requests to GRPC servers.
+  class ClientStub
+    include Core::StatusCodes
 
-      # Default deadline is 5 seconds.
-      DEFAULT_DEADLINE = 5
+    # Default deadline is 5 seconds.
+    DEFAULT_DEADLINE = 5
 
-      # Creates a new ClientStub.
-      #
-      # Minimally, a stub is created with the just the host of the gRPC service
-      # it wishes to access, e.g.,
-      #
-      # my_stub = ClientStub.new(example.host.com:50505)
-      #
-      # Any arbitrary keyword arguments are treated as channel arguments used to
-      # configure the RPC connection to the host.
-      #
-      # There are some specific keyword args that are not used to configure the
-      # channel:
-      #
-      # - :channel_override
-      # when present, this must be a pre-created GRPC::Channel.  If it's
-      # present the host and arbitrary keyword arg areignored, and the RPC
-      # connection uses this channel.
-      #
-      # - :deadline
-      # when present, this is the default deadline used for calls
-      #
-      # - :update_metadata
-      # when present, this a func that takes a hash and returns a hash
-      # it can be used to update metadata, i.e, remove, change or update
-      # amend metadata values.
-      #
-      # @param host [String] the host the stub connects to
-      # @param q [Core::CompletionQueue] used to wait for events
-      # @param channel_override [Core::Channel] a pre-created channel
-      # @param deadline [Number] the default deadline to use in requests
-      # @param creds [Core::Credentials] the channel
-      # @param update_metadata a func that updates metadata as described above
-      # @param kw [KeywordArgs]the channel arguments
-      def initialize(host, q,
-                     channel_override:nil,
-                     deadline: DEFAULT_DEADLINE,
-                     creds: nil,
-                     update_metadata: nil,
-                     **kw)
-        unless q.is_a? Core::CompletionQueue
-          fail(ArgumentError, 'not a CompletionQueue')
-        end
-        @queue = q
+    # Creates a new ClientStub.
+    #
+    # Minimally, a stub is created with the just the host of the gRPC service
+    # it wishes to access, e.g.,
+    #
+    # my_stub = ClientStub.new(example.host.com:50505)
+    #
+    # Any arbitrary keyword arguments are treated as channel arguments used to
+    # configure the RPC connection to the host.
+    #
+    # There are some specific keyword args that are not used to configure the
+    # channel:
+    #
+    # - :channel_override
+    # when present, this must be a pre-created GRPC::Channel.  If it's
+    # present the host and arbitrary keyword arg areignored, and the RPC
+    # connection uses this channel.
+    #
+    # - :deadline
+    # when present, this is the default deadline used for calls
+    #
+    # - :update_metadata
+    # when present, this a func that takes a hash and returns a hash
+    # it can be used to update metadata, i.e, remove, change or update
+    # amend metadata values.
+    #
+    # @param host [String] the host the stub connects to
+    # @param q [Core::CompletionQueue] used to wait for events
+    # @param channel_override [Core::Channel] a pre-created channel
+    # @param deadline [Number] the default deadline to use in requests
+    # @param creds [Core::Credentials] the channel
+    # @param update_metadata a func that updates metadata as described above
+    # @param kw [KeywordArgs]the channel arguments
+    def initialize(host, q,
+                   channel_override:nil,
+                   deadline: DEFAULT_DEADLINE,
+                   creds: nil,
+                   update_metadata: nil,
+                   **kw)
+      unless q.is_a? Core::CompletionQueue
+        fail(ArgumentError, 'not a CompletionQueue')
+      end
+      @queue = q
 
-        # set the channel instance
-        if !channel_override.nil?
-          ch = channel_override
-          fail(ArgumentError, 'not a Channel') unless ch.is_a? Core::Channel
+      # set the channel instance
+      if !channel_override.nil?
+        ch = channel_override
+        fail(ArgumentError, 'not a Channel') unless ch.is_a? Core::Channel
+      else
+        if creds.nil?
+          ch = Core::Channel.new(host, kw)
+        elsif !creds.is_a?(Core::Credentials)
+          fail(ArgumentError, 'not a Credentials')
         else
-          if creds.nil?
-            ch = Core::Channel.new(host, kw)
-          elsif !creds.is_a?(Core::Credentials)
-            fail(ArgumentError, 'not a Credentials')
-          else
-            ch = Core::Channel.new(host, kw, creds)
-          end
+          ch = Core::Channel.new(host, kw, creds)
         end
-        @ch = ch
-
-        @update_metadata = nil
-        unless update_metadata.nil?
-          unless update_metadata.is_a? Proc
-            fail(ArgumentError, 'update_metadata is not a Proc')
-          end
-          @update_metadata = update_metadata
-        end
-
-        @host = host
-        @deadline = deadline
       end
+      @ch = ch
 
-      # request_response sends a request to a GRPC server, and returns the
-      # response.
-      #
-      # == Flow Control ==
-      # This is a blocking call.
-      #
-      # * it does not return until a response is received.
-      #
-      # * the requests is sent only when GRPC core's flow control allows it to
-      #   be sent.
-      #
-      # == Errors ==
-      # An RuntimeError is raised if
-      #
-      # * the server responds with a non-OK status
-      #
-      # * the deadline is exceeded
-      #
-      # == Return Value ==
-      #
-      # If return_op is false, the call returns the response
-      #
-      # If return_op is true, the call returns an Operation, calling execute
-      # on the Operation returns the response.
-      #
-      # == Keyword Args ==
-      #
-      # Unspecified keyword arguments are treated as metadata to be sent to the
-      # server.
-      #
-      # @param method [String] the RPC method to call on the GRPC server
-      # @param req [Object] the request sent to the server
-      # @param marshal [Function] f(obj)->string that marshals requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [Numeric] (optional) the max completion time in seconds
-      # @param return_op [true|false] return an Operation if true
-      # @return [Object] the response received from the server
-      def request_response(method, req, marshal, unmarshal, deadline = nil,
-                           return_op: false, **kw)
-        c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
-        md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
-        return c.request_response(req, **md) unless return_op
-
-        # return the operation view of the active_call; define #execute as a
-        # new method for this instance that invokes #request_response.
-        op = c.operation
-        op.define_singleton_method(:execute) do
-          c.request_response(req, **md)
+      @update_metadata = nil
+      unless update_metadata.nil?
+        unless update_metadata.is_a? Proc
+          fail(ArgumentError, 'update_metadata is not a Proc')
         end
-        op
+        @update_metadata = update_metadata
       end
 
-      # client_streamer sends a stream of requests to a GRPC server, and
-      # returns a single response.
-      #
-      # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
-      # #each enumeration protocol. In the simplest case, requests will be an
-      # array of marshallable objects; in typical case it will be an Enumerable
-      # that allows dynamic construction of the marshallable objects.
-      #
-      # == Flow Control ==
-      # This is a blocking call.
-      #
-      # * it does not return until a response is received.
-      #
-      # * each requests is sent only when GRPC core's flow control allows it to
-      #   be sent.
-      #
-      # == Errors ==
-      # An RuntimeError is raised if
-      #
-      # * the server responds with a non-OK status
-      #
-      # * the deadline is exceeded
-      #
-      # == Return Value ==
-      #
-      # If return_op is false, the call consumes the requests and returns
-      # the response.
-      #
-      # If return_op is true, the call returns the response.
-      #
-      # == Keyword Args ==
-      #
-      # Unspecified keyword arguments are treated as metadata to be sent to the
-      # server.
-      #
-      # @param method [String] the RPC method to call on the GRPC server
-      # @param requests [Object] an Enumerable of requests to send
-      # @param marshal [Function] f(obj)->string that marshals requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [Numeric] the max completion time in seconds
-      # @param return_op [true|false] return an Operation if true
-      # @return [Object|Operation] the response received from the server
-      def client_streamer(method, requests, marshal, unmarshal, deadline = nil,
-                          return_op: false, **kw)
-        c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
-        md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
-        return c.client_streamer(requests, **md) unless return_op
+      @host = host
+      @deadline = deadline
+    end
+
+    # request_response sends a request to a GRPC server, and returns the
+    # response.
+    #
+    # == Flow Control ==
+    # This is a blocking call.
+    #
+    # * it does not return until a response is received.
+    #
+    # * the requests is sent only when GRPC core's flow control allows it to
+    #   be sent.
+    #
+    # == Errors ==
+    # An RuntimeError is raised if
+    #
+    # * the server responds with a non-OK status
+    #
+    # * the deadline is exceeded
+    #
+    # == Return Value ==
+    #
+    # If return_op is false, the call returns the response
+    #
+    # If return_op is true, the call returns an Operation, calling execute
+    # on the Operation returns the response.
+    #
+    # == Keyword Args ==
+    #
+    # Unspecified keyword arguments are treated as metadata to be sent to the
+    # server.
+    #
+    # @param method [String] the RPC method to call on the GRPC server
+    # @param req [Object] the request sent to the server
+    # @param marshal [Function] f(obj)->string that marshals requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [Numeric] (optional) the max completion time in seconds
+    # @param return_op [true|false] return an Operation if true
+    # @return [Object] the response received from the server
+    def request_response(method, req, marshal, unmarshal, deadline = nil,
+                         return_op: false, **kw)
+      c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+      md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
+      return c.request_response(req, **md) unless return_op
 
-        # return the operation view of the active_call; define #execute as a
-        # new method for this instance that invokes #client_streamer.
-        op = c.operation
-        op.define_singleton_method(:execute) do
-          c.client_streamer(requests, **md)
-        end
-        op
+      # return the operation view of the active_call; define #execute as a
+      # new method for this instance that invokes #request_response.
+      op = c.operation
+      op.define_singleton_method(:execute) do
+        c.request_response(req, **md)
       end
+      op
+    end
 
-      # server_streamer sends one request to the GRPC server, which yields a
-      # stream of responses.
-      #
-      # responses provides an enumerator over the streamed responses, i.e. it
-      # follows Ruby's #each iteration protocol.  The enumerator blocks while
-      # waiting for each response, stops when the server signals that no
-      # further responses will be supplied.  If the implicit block is provided,
-      # it is executed with each response as the argument and no result is
-      # returned.
-      #
-      # == Flow Control ==
-      # This is a blocking call.
-      #
-      # * the request is sent only when GRPC core's flow control allows it to
-      #   be sent.
-      #
-      # * the request will not complete until the server sends the final
-      #   response followed by a status message.
-      #
-      # == Errors ==
-      # An RuntimeError is raised if
-      #
-      # * the server responds with a non-OK status when any response is
-      # * retrieved
-      #
-      # * the deadline is exceeded
-      #
-      # == Return Value ==
-      #
-      # if the return_op is false, the return value is an Enumerator of the
-      # results, unless a block is provided, in which case the block is
-      # executed with each response.
-      #
-      # if return_op is true, the function returns an Operation whose #execute
-      # method runs server streamer call. Again, Operation#execute either
-      # calls the given block with each response or returns an Enumerator of the
-      # responses.
-      #
-      # == Keyword Args ==
-      #
-      # Unspecified keyword arguments are treated as metadata to be sent to the
-      # server.
-      #
-      # @param method [String] the RPC method to call on the GRPC server
-      # @param req [Object] the request sent to the server
-      # @param marshal [Function] f(obj)->string that marshals requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [Numeric] the max completion time in seconds
-      # @param return_op [true|false]return an Operation if true
-      # @param blk [Block] when provided, is executed for each response
-      # @return [Enumerator|Operation|nil] as discussed above
-      def server_streamer(method, req, marshal, unmarshal, deadline = nil,
-                          return_op: false, **kw, &blk)
-        c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
-        md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
-        return c.server_streamer(req, **md, &blk) unless return_op
+    # client_streamer sends a stream of requests to a GRPC server, and
+    # returns a single response.
+    #
+    # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
+    # #each enumeration protocol. In the simplest case, requests will be an
+    # array of marshallable objects; in typical case it will be an Enumerable
+    # that allows dynamic construction of the marshallable objects.
+    #
+    # == Flow Control ==
+    # This is a blocking call.
+    #
+    # * it does not return until a response is received.
+    #
+    # * each requests is sent only when GRPC core's flow control allows it to
+    #   be sent.
+    #
+    # == Errors ==
+    # An RuntimeError is raised if
+    #
+    # * the server responds with a non-OK status
+    #
+    # * the deadline is exceeded
+    #
+    # == Return Value ==
+    #
+    # If return_op is false, the call consumes the requests and returns
+    # the response.
+    #
+    # If return_op is true, the call returns the response.
+    #
+    # == Keyword Args ==
+    #
+    # Unspecified keyword arguments are treated as metadata to be sent to the
+    # server.
+    #
+    # @param method [String] the RPC method to call on the GRPC server
+    # @param requests [Object] an Enumerable of requests to send
+    # @param marshal [Function] f(obj)->string that marshals requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [Numeric] the max completion time in seconds
+    # @param return_op [true|false] return an Operation if true
+    # @return [Object|Operation] the response received from the server
+    def client_streamer(method, requests, marshal, unmarshal, deadline = nil,
+                        return_op: false, **kw)
+      c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+      md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
+      return c.client_streamer(requests, **md) unless return_op
 
-        # return the operation view of the active_call; define #execute
-        # as a new method for this instance that invokes #server_streamer
-        op = c.operation
-        op.define_singleton_method(:execute) do
-          c.server_streamer(req, **md, &blk)
-        end
-        op
+      # return the operation view of the active_call; define #execute as a
+      # new method for this instance that invokes #client_streamer.
+      op = c.operation
+      op.define_singleton_method(:execute) do
+        c.client_streamer(requests, **md)
       end
+      op
+    end
 
-      # bidi_streamer sends a stream of requests to the GRPC server, and yields
-      # a stream of responses.
-      #
-      # This method takes an Enumerable of requests, and returns and enumerable
-      # of responses.
-      #
-      # == requests ==
-      #
-      # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
-      # #each enumeration protocol. In the simplest case, requests will be an
-      # array of marshallable objects; in typical case it will be an
-      # Enumerable that allows dynamic construction of the marshallable
-      # objects.
-      #
-      # == responses ==
-      #
-      # This is an enumerator of responses.  I.e, its #next method blocks
-      # waiting for the next response.  Also, if at any point the block needs
-      # to consume all the remaining responses, this can be done using #each or
-      # #collect.  Calling #each or #collect should only be done if
-      # the_call#writes_done has been called, otherwise the block will loop
-      # forever.
-      #
-      # == Flow Control ==
-      # This is a blocking call.
-      #
-      # * the call completes when the next call to provided block returns
-      # * [False]
-      #
-      # * the execution block parameters are two objects for sending and
-      #   receiving responses, each of which blocks waiting for flow control.
-      #   E.g, calles to bidi_call#remote_send will wait until flow control
-      #   allows another write before returning; and obviously calls to
-      #   responses#next block until the next response is available.
-      #
-      # == Termination ==
-      #
-      # As well as sending and receiving messages, the block passed to the
-      # function is also responsible for:
-      #
-      # * calling bidi_call#writes_done to indicate no further reqs will be
-      #   sent.
-      #
-      # * returning false if once the bidi stream is functionally completed.
-      #
-      # Note that response#next will indicate that there are no further
-      # responses by throwing StopIteration, but can only happen either
-      # if bidi_call#writes_done is called.
-      #
-      # To terminate the RPC correctly the block:
-      #
-      # * must call bidi#writes_done and then
-      #
-      #    * either return false as soon as there is no need for other responses
-      #
-      #    * loop on responses#next until no further responses are available
-      #
-      # == Errors ==
-      # An RuntimeError is raised if
-      #
-      # * the server responds with a non-OK status when any response is
-      # * retrieved
-      #
-      # * the deadline is exceeded
-      #
-      #
-      # == Keyword Args ==
-      #
-      # Unspecified keyword arguments are treated as metadata to be sent to the
-      # server.
-      #
-      # == Return Value ==
-      #
-      # if the return_op is false, the return value is an Enumerator of the
-      # results, unless a block is provided, in which case the block is
-      # executed with each response.
-      #
-      # if return_op is true, the function returns an Operation whose #execute
-      # method runs the Bidi call. Again, Operation#execute either calls a
-      # given block with each response or returns an Enumerator of the
-      # responses.
-      #
-      # @param method [String] the RPC method to call on the GRPC server
-      # @param requests [Object] an Enumerable of requests to send
-      # @param marshal [Function] f(obj)->string that marshals requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [Numeric] (optional) the max completion time in seconds
-      # @param blk [Block] when provided, is executed for each response
-      # @param return_op [true|false] return an Operation if true
-      # @return [Enumerator|nil|Operation] as discussed above
-      def bidi_streamer(method, requests, marshal, unmarshal, deadline = nil,
+    # server_streamer sends one request to the GRPC server, which yields a
+    # stream of responses.
+    #
+    # responses provides an enumerator over the streamed responses, i.e. it
+    # follows Ruby's #each iteration protocol.  The enumerator blocks while
+    # waiting for each response, stops when the server signals that no
+    # further responses will be supplied.  If the implicit block is provided,
+    # it is executed with each response as the argument and no result is
+    # returned.
+    #
+    # == Flow Control ==
+    # This is a blocking call.
+    #
+    # * the request is sent only when GRPC core's flow control allows it to
+    #   be sent.
+    #
+    # * the request will not complete until the server sends the final
+    #   response followed by a status message.
+    #
+    # == Errors ==
+    # An RuntimeError is raised if
+    #
+    # * the server responds with a non-OK status when any response is
+    # * retrieved
+    #
+    # * the deadline is exceeded
+    #
+    # == Return Value ==
+    #
+    # if the return_op is false, the return value is an Enumerator of the
+    # results, unless a block is provided, in which case the block is
+    # executed with each response.
+    #
+    # if return_op is true, the function returns an Operation whose #execute
+    # method runs server streamer call. Again, Operation#execute either
+    # calls the given block with each response or returns an Enumerator of the
+    # responses.
+    #
+    # == Keyword Args ==
+    #
+    # Unspecified keyword arguments are treated as metadata to be sent to the
+    # server.
+    #
+    # @param method [String] the RPC method to call on the GRPC server
+    # @param req [Object] the request sent to the server
+    # @param marshal [Function] f(obj)->string that marshals requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [Numeric] the max completion time in seconds
+    # @param return_op [true|false]return an Operation if true
+    # @param blk [Block] when provided, is executed for each response
+    # @return [Enumerator|Operation|nil] as discussed above
+    def server_streamer(method, req, marshal, unmarshal, deadline = nil,
                         return_op: false, **kw, &blk)
-        c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
-        md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
-        return c.bidi_streamer(requests, **md, &blk) unless return_op
+      c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+      md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
+      return c.server_streamer(req, **md, &blk) unless return_op
 
-        # return the operation view of the active_call; define #execute
-        # as a new method for this instance that invokes #bidi_streamer
-        op = c.operation
-        op.define_singleton_method(:execute) do
-          c.bidi_streamer(requests, **md, &blk)
-        end
-        op
+      # return the operation view of the active_call; define #execute
+      # as a new method for this instance that invokes #server_streamer
+      op = c.operation
+      op.define_singleton_method(:execute) do
+        c.server_streamer(req, **md, &blk)
       end
+      op
+    end
 
-      private
+    # bidi_streamer sends a stream of requests to the GRPC server, and yields
+    # a stream of responses.
+    #
+    # This method takes an Enumerable of requests, and returns and enumerable
+    # of responses.
+    #
+    # == requests ==
+    #
+    # requests provides an 'iterable' of Requests. I.e. it follows Ruby's
+    # #each enumeration protocol. In the simplest case, requests will be an
+    # array of marshallable objects; in typical case it will be an
+    # Enumerable that allows dynamic construction of the marshallable
+    # objects.
+    #
+    # == responses ==
+    #
+    # This is an enumerator of responses.  I.e, its #next method blocks
+    # waiting for the next response.  Also, if at any point the block needs
+    # to consume all the remaining responses, this can be done using #each or
+    # #collect.  Calling #each or #collect should only be done if
+    # the_call#writes_done has been called, otherwise the block will loop
+    # forever.
+    #
+    # == Flow Control ==
+    # This is a blocking call.
+    #
+    # * the call completes when the next call to provided block returns
+    # * [False]
+    #
+    # * the execution block parameters are two objects for sending and
+    #   receiving responses, each of which blocks waiting for flow control.
+    #   E.g, calles to bidi_call#remote_send will wait until flow control
+    #   allows another write before returning; and obviously calls to
+    #   responses#next block until the next response is available.
+    #
+    # == Termination ==
+    #
+    # As well as sending and receiving messages, the block passed to the
+    # function is also responsible for:
+    #
+    # * calling bidi_call#writes_done to indicate no further reqs will be
+    #   sent.
+    #
+    # * returning false if once the bidi stream is functionally completed.
+    #
+    # Note that response#next will indicate that there are no further
+    # responses by throwing StopIteration, but can only happen either
+    # if bidi_call#writes_done is called.
+    #
+    # To terminate the RPC correctly the block:
+    #
+    # * must call bidi#writes_done and then
+    #
+    #    * either return false as soon as there is no need for other responses
+    #
+    #    * loop on responses#next until no further responses are available
+    #
+    # == Errors ==
+    # An RuntimeError is raised if
+    #
+    # * the server responds with a non-OK status when any response is
+    # * retrieved
+    #
+    # * the deadline is exceeded
+    #
+    #
+    # == Keyword Args ==
+    #
+    # Unspecified keyword arguments are treated as metadata to be sent to the
+    # server.
+    #
+    # == Return Value ==
+    #
+    # if the return_op is false, the return value is an Enumerator of the
+    # results, unless a block is provided, in which case the block is
+    # executed with each response.
+    #
+    # if return_op is true, the function returns an Operation whose #execute
+    # method runs the Bidi call. Again, Operation#execute either calls a
+    # given block with each response or returns an Enumerator of the
+    # responses.
+    #
+    # @param method [String] the RPC method to call on the GRPC server
+    # @param requests [Object] an Enumerable of requests to send
+    # @param marshal [Function] f(obj)->string that marshals requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [Numeric] (optional) the max completion time in seconds
+    # @param blk [Block] when provided, is executed for each response
+    # @param return_op [true|false] return an Operation if true
+    # @return [Enumerator|nil|Operation] as discussed above
+    def bidi_streamer(method, requests, marshal, unmarshal, deadline = nil,
+                      return_op: false, **kw, &blk)
+      c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+      md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
+      return c.bidi_streamer(requests, **md, &blk) unless return_op
 
-      # Creates a new active stub
-      #
-      # @param ch [GRPC::Channel] the channel used to create the stub.
-      # @param marshal [Function] f(obj)->string that marshals requests
-      # @param unmarshal [Function] f(string)->obj that unmarshals responses
-      # @param deadline [TimeConst]
-      def new_active_call(ch, marshal, unmarshal, deadline = nil)
-        absolute_deadline = Core::TimeConsts.from_relative_time(deadline)
-        call = @ch.create_call(ch, @host, absolute_deadline)
-        ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline,
-                       started: false)
+      # return the operation view of the active_call; define #execute
+      # as a new method for this instance that invokes #bidi_streamer
+      op = c.operation
+      op.define_singleton_method(:execute) do
+        c.bidi_streamer(requests, **md, &blk)
       end
+      op
+    end
+
+    private
+
+    # Creates a new active stub
+    #
+    # @param ch [GRPC::Channel] the channel used to create the stub.
+    # @param marshal [Function] f(obj)->string that marshals requests
+    # @param unmarshal [Function] f(string)->obj that unmarshals responses
+    # @param deadline [TimeConst]
+    def new_active_call(ch, marshal, unmarshal, deadline = nil)
+      absolute_deadline = Core::TimeConsts.from_relative_time(deadline)
+      call = @ch.create_call(ch, @host, absolute_deadline)
+      ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline,
+                     started: false)
     end
   end
 end
diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb
index 876397a6e70ea8b4c98cbef350ca0d044f2e2c44..5e3d3c9f9cfcbd47fab7b4151d147314fbc596f7 100644
--- a/src/ruby/lib/grpc/generic/rpc_desc.rb
+++ b/src/ruby/lib/grpc/generic/rpc_desc.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,123 +29,122 @@
 
 require 'grpc/grpc'
 
-module Google
-  module RPC
-    # RpcDesc is a Descriptor of an RPC method.
-    class RpcDesc < Struct.new(:name, :input, :output, :marshal_method,
-                               :unmarshal_method)
-      include Core::StatusCodes
+# GRPC contains the General RPC module.
+module GRPC
+  # RpcDesc is a Descriptor of an RPC method.
+  class RpcDesc < Struct.new(:name, :input, :output, :marshal_method,
+                             :unmarshal_method)
+    include Core::StatusCodes
 
-      # Used to wrap a message class to indicate that it needs to be streamed.
-      class Stream
-        attr_accessor :type
+    # Used to wrap a message class to indicate that it needs to be streamed.
+    class Stream
+      attr_accessor :type
 
-        def initialize(type)
-          @type = type
-        end
+      def initialize(type)
+        @type = type
       end
+    end
 
-      # @return [Proc] { |instance| marshalled(instance) }
-      def marshal_proc
-        proc { |o| o.class.method(marshal_method).call(o).to_s }
-      end
+    # @return [Proc] { |instance| marshalled(instance) }
+    def marshal_proc
+      proc { |o| o.class.method(marshal_method).call(o).to_s }
+    end
 
-      # @param [:input, :output] target determines whether to produce the an
-      #                          unmarshal Proc for the rpc input parameter or
-      #                          its output parameter
-      #
-      # @return [Proc] An unmarshal proc { |marshalled(instance)| instance }
-      def unmarshal_proc(target)
-        fail ArgumentError unless [:input, :output].include?(target)
-        unmarshal_class = method(target).call
-        unmarshal_class = unmarshal_class.type if unmarshal_class.is_a? Stream
-        proc { |o| unmarshal_class.method(unmarshal_method).call(o) }
-      end
+    # @param [:input, :output] target determines whether to produce the an
+    #                          unmarshal Proc for the rpc input parameter or
+    #                          its output parameter
+    #
+    # @return [Proc] An unmarshal proc { |marshalled(instance)| instance }
+    def unmarshal_proc(target)
+      fail ArgumentError unless [:input, :output].include?(target)
+      unmarshal_class = method(target).call
+      unmarshal_class = unmarshal_class.type if unmarshal_class.is_a? Stream
+      proc { |o| unmarshal_class.method(unmarshal_method).call(o) }
+    end
 
-      def run_server_method(active_call, mth)
-        # While a server method is running, it might be cancelled, its deadline
-        # might be reached, the handler could throw an unknown error, or a
-        # well-behaved handler could throw a StatusError.
-        if request_response?
-          req = active_call.remote_read
-          resp = mth.call(req, active_call.single_req_view)
-          active_call.remote_send(resp)
-        elsif client_streamer?
-          resp = mth.call(active_call.multi_req_view)
-          active_call.remote_send(resp)
-        elsif server_streamer?
-          req = active_call.remote_read
-          replys = mth.call(req, active_call.single_req_view)
-          replys.each { |r| active_call.remote_send(r) }
-        else  # is a bidi_stream
-          active_call.run_server_bidi(mth)
-        end
-        send_status(active_call, OK, 'OK')
-      rescue BadStatus => e
-        # this is raised by handlers that want GRPC to send an application
-        # error code and detail message.
-        logger.debug("app err: #{active_call}, status:#{e.code}:#{e.details}")
-        send_status(active_call, e.code, e.details)
-      rescue Core::CallError => e
-        # This is raised by GRPC internals but should rarely, if ever happen.
-        # Log it, but don't notify the other endpoint..
-        logger.warn("failed call: #{active_call}\n#{e}")
-      rescue OutOfTime
-        # This is raised when active_call#method.call exceeeds the deadline
-        # event.  Send a status of deadline exceeded
-        logger.warn("late call: #{active_call}")
-        send_status(active_call, DEADLINE_EXCEEDED, 'late')
-      rescue Core::EventError => e
-        # This is raised by GRPC internals but should rarely, if ever happen.
-        # Log it, but don't notify the other endpoint..
-        logger.warn("failed call: #{active_call}\n#{e}")
-      rescue StandardError => e
-        # This will usuaally be an unhandled error in the handling code.
-        # Send back a UNKNOWN status to the client
-        logger.warn("failed handler: #{active_call}; sending status:UNKNOWN")
-        logger.warn(e)
-        send_status(active_call, UNKNOWN, 'no reason given')
+    def run_server_method(active_call, mth)
+      # While a server method is running, it might be cancelled, its deadline
+      # might be reached, the handler could throw an unknown error, or a
+      # well-behaved handler could throw a StatusError.
+      if request_response?
+        req = active_call.remote_read
+        resp = mth.call(req, active_call.single_req_view)
+        active_call.remote_send(resp)
+      elsif client_streamer?
+        resp = mth.call(active_call.multi_req_view)
+        active_call.remote_send(resp)
+      elsif server_streamer?
+        req = active_call.remote_read
+        replys = mth.call(req, active_call.single_req_view)
+        replys.each { |r| active_call.remote_send(r) }
+      else  # is a bidi_stream
+        active_call.run_server_bidi(mth)
       end
+      send_status(active_call, OK, 'OK')
+    rescue BadStatus => e
+      # this is raised by handlers that want GRPC to send an application
+      # error code and detail message.
+      logger.debug("app err: #{active_call}, status:#{e.code}:#{e.details}")
+      send_status(active_call, e.code, e.details)
+    rescue Core::CallError => e
+      # This is raised by GRPC internals but should rarely, if ever happen.
+      # Log it, but don't notify the other endpoint..
+      logger.warn("failed call: #{active_call}\n#{e}")
+    rescue OutOfTime
+      # This is raised when active_call#method.call exceeeds the deadline
+      # event.  Send a status of deadline exceeded
+      logger.warn("late call: #{active_call}")
+      send_status(active_call, DEADLINE_EXCEEDED, 'late')
+    rescue Core::EventError => e
+      # This is raised by GRPC internals but should rarely, if ever happen.
+      # Log it, but don't notify the other endpoint..
+      logger.warn("failed call: #{active_call}\n#{e}")
+    rescue StandardError => e
+      # This will usuaally be an unhandled error in the handling code.
+      # Send back a UNKNOWN status to the client
+      logger.warn("failed handler: #{active_call}; sending status:UNKNOWN")
+      logger.warn(e)
+      send_status(active_call, UNKNOWN, 'no reason given')
+    end
 
-      def assert_arity_matches(mth)
-        if request_response? || server_streamer?
-          if mth.arity != 2
-            fail arity_error(mth, 2, "should be #{mth.name}(req, call)")
-          end
-        else
-          if mth.arity != 1
-            fail arity_error(mth, 1, "should be #{mth.name}(call)")
-          end
+    def assert_arity_matches(mth)
+      if request_response? || server_streamer?
+        if mth.arity != 2
+          fail arity_error(mth, 2, "should be #{mth.name}(req, call)")
+        end
+      else
+        if mth.arity != 1
+          fail arity_error(mth, 1, "should be #{mth.name}(call)")
         end
       end
+    end
 
-      def request_response?
-        !input.is_a?(Stream) && !output.is_a?(Stream)
-      end
+    def request_response?
+      !input.is_a?(Stream) && !output.is_a?(Stream)
+    end
 
-      def client_streamer?
-        input.is_a?(Stream) && !output.is_a?(Stream)
-      end
+    def client_streamer?
+      input.is_a?(Stream) && !output.is_a?(Stream)
+    end
 
-      def server_streamer?
-        !input.is_a?(Stream) && output.is_a?(Stream)
-      end
+    def server_streamer?
+      !input.is_a?(Stream) && output.is_a?(Stream)
+    end
 
-      def bidi_streamer?
-        input.is_a?(Stream) && output.is_a?(Stream)
-      end
+    def bidi_streamer?
+      input.is_a?(Stream) && output.is_a?(Stream)
+    end
 
-      def arity_error(mth, want, msg)
-        "##{mth.name}: bad arg count; got:#{mth.arity}, want:#{want}, #{msg}"
-      end
+    def arity_error(mth, want, msg)
+      "##{mth.name}: bad arg count; got:#{mth.arity}, want:#{want}, #{msg}"
+    end
 
-      def send_status(active_client, code, details)
-        details = 'Not sure why' if details.nil?
-        active_client.send_status(code, details)
-      rescue StandardError => e
-        logger.warn("Could not send status #{code}:#{details}")
-        logger.warn(e)
-      end
+    def send_status(active_client, code, details)
+      details = 'Not sure why' if details.nil?
+      active_client.send_status(code, details)
+    rescue StandardError => e
+      logger.warn("Could not send status #{code}:#{details}")
+      logger.warn(e)
     end
   end
 end
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 40c5ec118e3c7dbaf5b82c29fdb6b79726aeebfc..6938f718922cfc21b463b2cbf8aa70f12218d038 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -33,372 +33,370 @@ require 'grpc/generic/service'
 require 'thread'
 require 'xray/thread_dump_signal_handler'
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    # RpcServer hosts a number of services and makes them available on the
-    # network.
-    class RpcServer
-      include Core::CompletionType
-      include Core::TimeConsts
-      extend ::Forwardable
-
-      def_delegators :@server, :add_http2_port
-
-      # Default thread pool size is 3
-      DEFAULT_POOL_SIZE = 3
-
-      # Default max_waiting_requests size is 20
-      DEFAULT_MAX_WAITING_REQUESTS = 20
-
-      # Creates a new RpcServer.
-      #
-      # The RPC server is configured using keyword arguments.
-      #
-      # There are some specific keyword args used to configure the RpcServer
-      # instance, however other arbitrary are allowed and when present are used
-      # to configure the listeninng connection set up by the RpcServer.
-      #
-      # * server_override: which if passed must be a [GRPC::Core::Server].  When
-      # present.
-      #
-      # * poll_period: when present, the server polls for new events with this
-      # period
-      #
-      # * pool_size: the size of the thread pool the server uses to run its
-      # threads
-      #
-      # * completion_queue_override: when supplied, this will be used as the
-      # completion_queue that the server uses to receive network events,
-      # otherwise its creates a new instance itself
-      #
-      # * creds: [GRPC::Core::ServerCredentials]
-      # the credentials used to secure the server
-      #
-      # * max_waiting_requests: the maximum number of requests that are not
-      # being handled to allow. When this limit is exceeded, the server responds
-      # with not available to new requests
-      def initialize(pool_size:DEFAULT_POOL_SIZE,
-                     max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
-                     poll_period:INFINITE_FUTURE,
-                     completion_queue_override:nil,
-                     creds:nil,
-                     server_override:nil,
-                     **kw)
-        if completion_queue_override.nil?
-          cq = Core::CompletionQueue.new
-        else
-          cq = completion_queue_override
-          unless cq.is_a? Core::CompletionQueue
-            fail(ArgumentError, 'not a CompletionQueue')
-          end
+# GRPC contains the General RPC module.
+module GRPC
+  # RpcServer hosts a number of services and makes them available on the
+  # network.
+  class RpcServer
+    include Core::CompletionType
+    include Core::TimeConsts
+    extend ::Forwardable
+
+    def_delegators :@server, :add_http2_port
+
+    # Default thread pool size is 3
+    DEFAULT_POOL_SIZE = 3
+
+    # Default max_waiting_requests size is 20
+    DEFAULT_MAX_WAITING_REQUESTS = 20
+
+    # Creates a new RpcServer.
+    #
+    # The RPC server is configured using keyword arguments.
+    #
+    # There are some specific keyword args used to configure the RpcServer
+    # instance, however other arbitrary are allowed and when present are used
+    # to configure the listeninng connection set up by the RpcServer.
+    #
+    # * server_override: which if passed must be a [GRPC::Core::Server].  When
+    # present.
+    #
+    # * poll_period: when present, the server polls for new events with this
+    # period
+    #
+    # * pool_size: the size of the thread pool the server uses to run its
+    # threads
+    #
+    # * completion_queue_override: when supplied, this will be used as the
+    # completion_queue that the server uses to receive network events,
+    # otherwise its creates a new instance itself
+    #
+    # * creds: [GRPC::Core::ServerCredentials]
+    # the credentials used to secure the server
+    #
+    # * max_waiting_requests: the maximum number of requests that are not
+    # being handled to allow. When this limit is exceeded, the server responds
+    # with not available to new requests
+    def initialize(pool_size:DEFAULT_POOL_SIZE,
+                   max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
+                   poll_period:INFINITE_FUTURE,
+                   completion_queue_override:nil,
+                   creds:nil,
+                   server_override:nil,
+                   **kw)
+      if completion_queue_override.nil?
+        cq = Core::CompletionQueue.new
+      else
+        cq = completion_queue_override
+        unless cq.is_a? Core::CompletionQueue
+          fail(ArgumentError, 'not a CompletionQueue')
         end
-        @cq = cq
+      end
+      @cq = cq
 
-        if server_override.nil?
-          if creds.nil?
-            srv = Core::Server.new(@cq, kw)
-          elsif !creds.is_a? Core::ServerCredentials
-            fail(ArgumentError, 'not a ServerCredentials')
-          else
-            srv = Core::Server.new(@cq, kw, creds)
-          end
+      if server_override.nil?
+        if creds.nil?
+          srv = Core::Server.new(@cq, kw)
+        elsif !creds.is_a? Core::ServerCredentials
+          fail(ArgumentError, 'not a ServerCredentials')
         else
-          srv = server_override
-          fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server
+          srv = Core::Server.new(@cq, kw, creds)
         end
-        @server = srv
-
-        @pool_size = pool_size
-        @max_waiting_requests = max_waiting_requests
-        @poll_period = poll_period
-        @run_mutex = Mutex.new
-        @run_cond = ConditionVariable.new
-        @pool = Pool.new(@pool_size)
+      else
+        srv = server_override
+        fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server
       end
+      @server = srv
+
+      @pool_size = pool_size
+      @max_waiting_requests = max_waiting_requests
+      @poll_period = poll_period
+      @run_mutex = Mutex.new
+      @run_cond = ConditionVariable.new
+      @pool = Pool.new(@pool_size)
+    end
 
-      # stops a running server
-      #
-      # the call has no impact if the server is already stopped, otherwise
-      # server's current call loop is it's last.
-      def stop
-        return unless @running
-        @stopped = true
-        @pool.stop
-      end
+    # stops a running server
+    #
+    # the call has no impact if the server is already stopped, otherwise
+    # server's current call loop is it's last.
+    def stop
+      return unless @running
+      @stopped = true
+      @pool.stop
+    end
 
-      # determines if the server is currently running
-      def running?
-        @running ||= false
-      end
+    # determines if the server is currently running
+    def running?
+      @running ||= false
+    end
 
-      # Is called from other threads to wait for #run to start up the server.
-      #
-      # If run has not been called, this returns immediately.
-      #
-      # @param timeout [Numeric] number of seconds to wait
-      # @result [true, false] true if the server is running, false otherwise
-      def wait_till_running(timeout = 0.1)
-        end_time, sleep_period = Time.now + timeout, (1.0 * timeout) / 100
-        while Time.now < end_time
-          @run_mutex.synchronize { @run_cond.wait(@run_mutex) } unless running?
-          sleep(sleep_period)
-        end
-        running?
+    # Is called from other threads to wait for #run to start up the server.
+    #
+    # If run has not been called, this returns immediately.
+    #
+    # @param timeout [Numeric] number of seconds to wait
+    # @result [true, false] true if the server is running, false otherwise
+    def wait_till_running(timeout = 0.1)
+      end_time, sleep_period = Time.now + timeout, (1.0 * timeout) / 100
+      while Time.now < end_time
+        @run_mutex.synchronize { @run_cond.wait(@run_mutex) } unless running?
+        sleep(sleep_period)
       end
+      running?
+    end
 
-      # determines if the server is currently stopped
-      def stopped?
-        @stopped ||= false
-      end
+    # determines if the server is currently stopped
+    def stopped?
+      @stopped ||= false
+    end
 
-      # handle registration of classes
-      #
-      # service is either a class that includes GRPC::GenericService and whose
-      # #new function can be called without argument or any instance of such a
-      # class.
-      #
-      # E.g, after
-      #
-      # class Divider
-      #   include GRPC::GenericService
-      #   rpc :div DivArgs, DivReply    # single request, single response
-      #   def initialize(optional_arg='default option') # no args
-      #     ...
-      #   end
-      #
-      # srv = GRPC::RpcServer.new(...)
-      #
-      # # Either of these works
-      #
-      # srv.handle(Divider)
-      #
-      # # or
-      #
-      # srv.handle(Divider.new('replace optional arg'))
-      #
-      # It raises RuntimeError:
-      # - if service is not valid service class or object
-      # - its handler methods are already registered
-      # - if the server is already running
-      #
-      # @param service [Object|Class] a service class or object as described
-      #        above
-      def handle(service)
-        fail 'cannot add services if the server is running' if running?
-        fail 'cannot add services if the server is stopped' if stopped?
-        cls = service.is_a?(Class) ? service : service.class
-        assert_valid_service_class(cls)
-        add_rpc_descs_for(service)
-      end
+    # handle registration of classes
+    #
+    # service is either a class that includes GRPC::GenericService and whose
+    # #new function can be called without argument or any instance of such a
+    # class.
+    #
+    # E.g, after
+    #
+    # class Divider
+    #   include GRPC::GenericService
+    #   rpc :div DivArgs, DivReply    # single request, single response
+    #   def initialize(optional_arg='default option') # no args
+    #     ...
+    #   end
+    #
+    # srv = GRPC::RpcServer.new(...)
+    #
+    # # Either of these works
+    #
+    # srv.handle(Divider)
+    #
+    # # or
+    #
+    # srv.handle(Divider.new('replace optional arg'))
+    #
+    # It raises RuntimeError:
+    # - if service is not valid service class or object
+    # - its handler methods are already registered
+    # - if the server is already running
+    #
+    # @param service [Object|Class] a service class or object as described
+    #        above
+    def handle(service)
+      fail 'cannot add services if the server is running' if running?
+      fail 'cannot add services if the server is stopped' if stopped?
+      cls = service.is_a?(Class) ? service : service.class
+      assert_valid_service_class(cls)
+      add_rpc_descs_for(service)
+    end
 
-      # runs the server
-      #
-      # - if no rpc_descs are registered, this exits immediately, otherwise it
-      #   continues running permanently and does not return until program exit.
-      #
-      # - #running? returns true after this is called, until #stop cause the
-      #   the server to stop.
-      def run
-        if rpc_descs.size == 0
-          logger.warn('did not run as no services were present')
-          return
-        end
-        @run_mutex.synchronize do
-          @running = true
-          @run_cond.signal
+    # runs the server
+    #
+    # - if no rpc_descs are registered, this exits immediately, otherwise it
+    #   continues running permanently and does not return until program exit.
+    #
+    # - #running? returns true after this is called, until #stop cause the
+    #   the server to stop.
+    def run
+      if rpc_descs.size == 0
+        logger.warn('did not run as no services were present')
+        return
+      end
+      @run_mutex.synchronize do
+        @running = true
+        @run_cond.signal
+      end
+      @pool.start
+      @server.start
+      server_tag = Object.new
+      until stopped?
+        @server.request_call(server_tag)
+        ev = @cq.pluck(server_tag, @poll_period)
+        next if ev.nil?
+        if ev.type != SERVER_RPC_NEW
+          logger.warn("bad evt: got:#{ev.type}, want:#{SERVER_RPC_NEW}")
+          ev.close
+          next
         end
-        @pool.start
-        @server.start
-        server_tag = Object.new
-        until stopped?
-          @server.request_call(server_tag)
-          ev = @cq.pluck(server_tag, @poll_period)
-          next if ev.nil?
-          if ev.type != SERVER_RPC_NEW
-            logger.warn("bad evt: got:#{ev.type}, want:#{SERVER_RPC_NEW}")
-            ev.close
-            next
-          end
-          c = new_active_server_call(ev.call, ev.result)
-          unless c.nil?
-            mth = ev.result.method.to_sym
-            ev.close
-            @pool.schedule(c) do |call|
-              rpc_descs[mth].run_server_method(call, rpc_handlers[mth])
-            end
+        c = new_active_server_call(ev.call, ev.result)
+        unless c.nil?
+          mth = ev.result.method.to_sym
+          ev.close
+          @pool.schedule(c) do |call|
+            rpc_descs[mth].run_server_method(call, rpc_handlers[mth])
           end
         end
-        @running = false
       end
+      @running = false
+    end
 
-      def new_active_server_call(call, new_server_rpc)
-        # Accept the call.  This is necessary even if a status is to be sent
-        # back immediately
-        finished_tag = Object.new
-        call_queue = Core::CompletionQueue.new
-        call.metadata = new_server_rpc.metadata  # store the metadata
-        call.server_accept(call_queue, finished_tag)
-        call.server_end_initial_metadata
-
-        # Send UNAVAILABLE if there are too many unprocessed jobs
-        jobs_count, max = @pool.jobs_waiting, @max_waiting_requests
-        logger.info("waiting: #{jobs_count}, max: #{max}")
-        if @pool.jobs_waiting > @max_waiting_requests
-          logger.warn("NOT AVAILABLE: too many jobs_waiting: #{new_server_rpc}")
-          noop = proc { |x| x }
-          c = ActiveCall.new(call, call_queue, noop, noop,
-                             new_server_rpc.deadline,
-                             finished_tag: finished_tag)
-          c.send_status(StatusCodes::UNAVAILABLE, '')
-          return nil
-        end
-
-        # Send NOT_FOUND if the method does not exist
-        mth = new_server_rpc.method.to_sym
-        unless rpc_descs.key?(mth)
-          logger.warn("NOT_FOUND: #{new_server_rpc}")
-          noop = proc { |x| x }
-          c = ActiveCall.new(call, call_queue, noop, noop,
-                             new_server_rpc.deadline,
-                             finished_tag: finished_tag)
-          c.send_status(StatusCodes::NOT_FOUND, '')
-          return nil
-        end
+    def new_active_server_call(call, new_server_rpc)
+      # Accept the call.  This is necessary even if a status is to be sent
+      # back immediately
+      finished_tag = Object.new
+      call_queue = Core::CompletionQueue.new
+      call.metadata = new_server_rpc.metadata  # store the metadata
+      call.server_accept(call_queue, finished_tag)
+      call.server_end_initial_metadata
+
+      # Send UNAVAILABLE if there are too many unprocessed jobs
+      jobs_count, max = @pool.jobs_waiting, @max_waiting_requests
+      logger.info("waiting: #{jobs_count}, max: #{max}")
+      if @pool.jobs_waiting > @max_waiting_requests
+        logger.warn("NOT AVAILABLE: too many jobs_waiting: #{new_server_rpc}")
+        noop = proc { |x| x }
+        c = ActiveCall.new(call, call_queue, noop, noop,
+                           new_server_rpc.deadline,
+                           finished_tag: finished_tag)
+        c.send_status(StatusCodes::UNAVAILABLE, '')
+        return nil
+      end
 
-        # Create the ActiveCall
-        rpc_desc = rpc_descs[mth]
-        logger.info("deadline is #{new_server_rpc.deadline}; (now=#{Time.now})")
-        ActiveCall.new(call, call_queue,
-                       rpc_desc.marshal_proc, rpc_desc.unmarshal_proc(:input),
-                       new_server_rpc.deadline, finished_tag: finished_tag)
+      # Send NOT_FOUND if the method does not exist
+      mth = new_server_rpc.method.to_sym
+      unless rpc_descs.key?(mth)
+        logger.warn("NOT_FOUND: #{new_server_rpc}")
+        noop = proc { |x| x }
+        c = ActiveCall.new(call, call_queue, noop, noop,
+                           new_server_rpc.deadline,
+                           finished_tag: finished_tag)
+        c.send_status(StatusCodes::NOT_FOUND, '')
+        return nil
       end
 
-      # Pool is a simple thread pool for running server requests.
-      class Pool
-        def initialize(size)
-          fail 'pool size must be positive' unless size > 0
-          @jobs = Queue.new
-          @size = size
-          @stopped = false
-          @stop_mutex = Mutex.new
-          @stop_cond = ConditionVariable.new
-          @workers = []
-        end
+      # Create the ActiveCall
+      rpc_desc = rpc_descs[mth]
+      logger.info("deadline is #{new_server_rpc.deadline}; (now=#{Time.now})")
+      ActiveCall.new(call, call_queue,
+                     rpc_desc.marshal_proc, rpc_desc.unmarshal_proc(:input),
+                     new_server_rpc.deadline, finished_tag: finished_tag)
+    end
 
-        # Returns the number of jobs waiting
-        def jobs_waiting
-          @jobs.size
-        end
+    # Pool is a simple thread pool for running server requests.
+    class Pool
+      def initialize(size)
+        fail 'pool size must be positive' unless size > 0
+        @jobs = Queue.new
+        @size = size
+        @stopped = false
+        @stop_mutex = Mutex.new
+        @stop_cond = ConditionVariable.new
+        @workers = []
+      end
 
-        # Runs the given block on the queue with the provided args.
-        #
-        # @param args the args passed blk when it is called
-        # @param blk the block to call
-        def schedule(*args, &blk)
-          fail 'already stopped' if @stopped
-          return if blk.nil?
-          logger.info('schedule another job')
-          @jobs << [blk, args]
-        end
+      # Returns the number of jobs waiting
+      def jobs_waiting
+        @jobs.size
+      end
+
+      # Runs the given block on the queue with the provided args.
+      #
+      # @param args the args passed blk when it is called
+      # @param blk the block to call
+      def schedule(*args, &blk)
+        fail 'already stopped' if @stopped
+        return if blk.nil?
+        logger.info('schedule another job')
+        @jobs << [blk, args]
+      end
 
-        # Starts running the jobs in the thread pool.
-        def start
-          fail 'already stopped' if @stopped
-          until @workers.size == @size.to_i
-            next_thread = Thread.new do
-              catch(:exit) do  # allows { throw :exit } to kill a thread
-                loop do
-                  begin
-                    blk, args = @jobs.pop
-                    blk.call(*args)
-                  rescue StandardError => e
-                    logger.warn('Error in worker thread')
-                    logger.warn(e)
-                  end
+      # Starts running the jobs in the thread pool.
+      def start
+        fail 'already stopped' if @stopped
+        until @workers.size == @size.to_i
+          next_thread = Thread.new do
+            catch(:exit) do  # allows { throw :exit } to kill a thread
+              loop do
+                begin
+                  blk, args = @jobs.pop
+                  blk.call(*args)
+                rescue StandardError => e
+                  logger.warn('Error in worker thread')
+                  logger.warn(e)
                 end
               end
+            end
 
-              # removes the threads from workers, and signal when all the
-              # threads are complete.
-              @stop_mutex.synchronize do
-                @workers.delete(Thread.current)
-                @stop_cond.signal if @workers.size == 0
-              end
+            # removes the threads from workers, and signal when all the
+            # threads are complete.
+            @stop_mutex.synchronize do
+              @workers.delete(Thread.current)
+              @stop_cond.signal if @workers.size == 0
             end
-            @workers << next_thread
           end
+          @workers << next_thread
         end
+      end
 
-        # Stops the jobs in the pool
-        def stop
-          logger.info('stopping, will wait for all the workers to exit')
-          @workers.size.times { schedule { throw :exit } }
-          @stopped = true
+      # Stops the jobs in the pool
+      def stop
+        logger.info('stopping, will wait for all the workers to exit')
+        @workers.size.times { schedule { throw :exit } }
+        @stopped = true
 
-          # TODO: allow configuration of the keepalive period
-          keep_alive = 5
-          @stop_mutex.synchronize do
-            @stop_cond.wait(@stop_mutex, keep_alive) if @workers.size > 0
-          end
+        # TODO: allow configuration of the keepalive period
+        keep_alive = 5
+        @stop_mutex.synchronize do
+          @stop_cond.wait(@stop_mutex, keep_alive) if @workers.size > 0
+        end
 
-          # Forcibly shutdown any threads that are still alive.
-          if @workers.size > 0
-            logger.warn("forcibly terminating #{@workers.size} worker(s)")
-            @workers.each do |t|
-              next unless t.alive?
-              begin
-                t.exit
-              rescue StandardError => e
-                logger.warn('error while terminating a worker')
-                logger.warn(e)
-              end
+        # Forcibly shutdown any threads that are still alive.
+        if @workers.size > 0
+          logger.warn("forcibly terminating #{@workers.size} worker(s)")
+          @workers.each do |t|
+            next unless t.alive?
+            begin
+              t.exit
+            rescue StandardError => e
+              logger.warn('error while terminating a worker')
+              logger.warn(e)
             end
           end
-
-          logger.info('stopped, all workers are shutdown')
         end
+
+        logger.info('stopped, all workers are shutdown')
       end
+    end
 
-      protected
+    protected
 
-      def rpc_descs
-        @rpc_descs ||= {}
-      end
+    def rpc_descs
+      @rpc_descs ||= {}
+    end
 
-      def rpc_handlers
-        @rpc_handlers ||= {}
-      end
+    def rpc_handlers
+      @rpc_handlers ||= {}
+    end
 
-      private
+    private
 
-      def assert_valid_service_class(cls)
-        unless cls.include?(GenericService)
-          fail "#{cls} should 'include GenericService'"
-        end
-        if cls.rpc_descs.size == 0
-          fail "#{cls} should specify some rpc descriptions"
-        end
-        cls.assert_rpc_descs_have_methods
+    def assert_valid_service_class(cls)
+      unless cls.include?(GenericService)
+        fail "#{cls} should 'include GenericService'"
+      end
+      if cls.rpc_descs.size == 0
+        fail "#{cls} should specify some rpc descriptions"
       end
+      cls.assert_rpc_descs_have_methods
+    end
 
-      def add_rpc_descs_for(service)
-        cls = service.is_a?(Class) ? service : service.class
-        specs = rpc_descs
-        handlers = rpc_handlers
-        cls.rpc_descs.each_pair do |name, spec|
-          route = "/#{cls.service_name}/#{name}".to_sym
-          if specs.key? route
-            fail "Cannot add rpc #{route} from #{spec}, already registered"
+    def add_rpc_descs_for(service)
+      cls = service.is_a?(Class) ? service : service.class
+      specs = rpc_descs
+      handlers = rpc_handlers
+      cls.rpc_descs.each_pair do |name, spec|
+        route = "/#{cls.service_name}/#{name}".to_sym
+        if specs.key? route
+          fail "Cannot add rpc #{route} from #{spec}, already registered"
+        else
+          specs[route] = spec
+          if service.is_a?(Class)
+            handlers[route] = cls.new.method(name.to_s.underscore.to_sym)
           else
-            specs[route] = spec
-            if service.is_a?(Class)
-              handlers[route] = cls.new.method(name.to_s.underscore.to_sym)
-            else
-              handlers[route] = service.method(name.to_s.underscore.to_sym)
-            end
-            logger.info("handling #{route} with #{handlers[route]}")
+            handlers[route] = service.method(name.to_s.underscore.to_sym)
           end
+          logger.info("handling #{route} with #{handlers[route]}")
         end
       end
     end
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index ff37617ccfad39f5f72dcb42ec805015a30867f4..61d187163549374eec70dbc3d4bf8437b7d7a5ca 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -48,188 +48,186 @@ class String
   end
 end
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    # Provides behaviour used to implement schema-derived service classes.
-    #
-    # Is intended to be used to support both client and server
-    # IDL-schema-derived servers.
-    module GenericService
-      # Used to indicate that a name has already been specified
-      class DuplicateRpcName < StandardError
-        def initialize(name)
-          super("rpc (#{name}) is already defined")
-        end
+# GRPC contains the General RPC module.
+module GRPC
+  # Provides behaviour used to implement schema-derived service classes.
+  #
+  # Is intended to be used to support both client and server
+  # IDL-schema-derived servers.
+  module GenericService
+    # Used to indicate that a name has already been specified
+    class DuplicateRpcName < StandardError
+      def initialize(name)
+        super("rpc (#{name}) is already defined")
       end
+    end
 
-      # Provides a simple DSL to describe RPC services.
+    # Provides a simple DSL to describe RPC services.
+    #
+    # E.g, a Maths service that uses the serializable messages DivArgs,
+    # DivReply and Num might define its endpoint uses the following way:
+    #
+    # rpc :div DivArgs, DivReply    # single request, single response
+    # rpc :sum stream(Num), Num     # streamed input, single response
+    # rpc :fib FibArgs, stream(Num) # single request, streamed response
+    # rpc :div_many stream(DivArgs), stream(DivReply)
+    #                               # streamed req and resp
+    #
+    # Each 'rpc' adds an RpcDesc to classes including this module, and
+    # #assert_rpc_descs_have_methods is used to ensure the including class
+    # provides methods with signatures that support all the descriptors.
+    module Dsl
+      # This configures the method names that the serializable message
+      # implementation uses to marshal and unmarshal messages.
       #
-      # E.g, a Maths service that uses the serializable messages DivArgs,
-      # DivReply and Num might define its endpoint uses the following way:
+      # - unmarshal_class method must be a class method on the serializable
+      # message type that takes a string (byte stream) and produces and object
       #
-      # rpc :div DivArgs, DivReply    # single request, single response
-      # rpc :sum stream(Num), Num     # streamed input, single response
-      # rpc :fib FibArgs, stream(Num) # single request, streamed response
-      # rpc :div_many stream(DivArgs), stream(DivReply)
-      #                               # streamed req and resp
+      # - marshal_class_method is called on a serializable message instance
+      # and produces a serialized string.
       #
-      # Each 'rpc' adds an RpcDesc to classes including this module, and
-      # #assert_rpc_descs_have_methods is used to ensure the including class
-      # provides methods with signatures that support all the descriptors.
-      module Dsl
-        # This configures the method names that the serializable message
-        # implementation uses to marshal and unmarshal messages.
-        #
-        # - unmarshal_class method must be a class method on the serializable
-        # message type that takes a string (byte stream) and produces and object
-        #
-        # - marshal_class_method is called on a serializable message instance
-        # and produces a serialized string.
-        #
-        # The Dsl verifies that the types in the descriptor have both the
-        # unmarshal and marshal methods.
-        attr_writer(:marshal_class_method, :unmarshal_class_method)
-
-        # This allows configuration of the service name.
-        attr_accessor(:service_name)
-
-        # Adds an RPC spec.
-        #
-        # Takes the RPC name and the classes representing the types to be
-        # serialized, and adds them to the including classes rpc_desc hash.
-        #
-        # input and output should both have the methods #marshal and #unmarshal
-        # that are responsible for writing and reading an object instance from a
-        # byte buffer respectively.
-        #
-        # @param name [String] the name of the rpc
-        # @param input [Object] the input parameter's class
-        # @param output [Object] the output parameter's class
-        def rpc(name, input, output)
-          fail(DuplicateRpcName, name) if rpc_descs.key? name
-          assert_can_marshal(input)
-          assert_can_marshal(output)
-          rpc_descs[name] = RpcDesc.new(name, input, output,
-                                        marshal_class_method,
-                                        unmarshal_class_method)
-        end
+      # The Dsl verifies that the types in the descriptor have both the
+      # unmarshal and marshal methods.
+      attr_writer(:marshal_class_method, :unmarshal_class_method)
 
-        def inherited(subclass)
-          # Each subclass should have a distinct class variable with its own
-          # rpc_descs
-          subclass.rpc_descs.merge!(rpc_descs)
-          subclass.service_name = service_name
-        end
+      # This allows configuration of the service name.
+      attr_accessor(:service_name)
 
-        # the name of the instance method used to marshal events to a byte
-        # stream.
-        def marshal_class_method
-          @marshal_class_method ||= :marshal
-        end
+      # Adds an RPC spec.
+      #
+      # Takes the RPC name and the classes representing the types to be
+      # serialized, and adds them to the including classes rpc_desc hash.
+      #
+      # input and output should both have the methods #marshal and #unmarshal
+      # that are responsible for writing and reading an object instance from a
+      # byte buffer respectively.
+      #
+      # @param name [String] the name of the rpc
+      # @param input [Object] the input parameter's class
+      # @param output [Object] the output parameter's class
+      def rpc(name, input, output)
+        fail(DuplicateRpcName, name) if rpc_descs.key? name
+        assert_can_marshal(input)
+        assert_can_marshal(output)
+        rpc_descs[name] = RpcDesc.new(name, input, output,
+                                      marshal_class_method,
+                                      unmarshal_class_method)
+      end
 
-        # the name of the class method used to unmarshal from a byte stream.
-        def unmarshal_class_method
-          @unmarshal_class_method ||= :unmarshal
-        end
+      def inherited(subclass)
+        # Each subclass should have a distinct class variable with its own
+        # rpc_descs
+        subclass.rpc_descs.merge!(rpc_descs)
+        subclass.service_name = service_name
+      end
 
-        def assert_can_marshal(cls)
-          cls = cls.type if cls.is_a? RpcDesc::Stream
-          mth = unmarshal_class_method
-          unless cls.methods.include? mth
-            fail(ArgumentError, "#{cls} needs #{cls}.#{mth}")
-          end
-          mth = marshal_class_method
-          return if cls.methods.include? mth
+      # the name of the instance method used to marshal events to a byte
+      # stream.
+      def marshal_class_method
+        @marshal_class_method ||= :marshal
+      end
+
+      # the name of the class method used to unmarshal from a byte stream.
+      def unmarshal_class_method
+        @unmarshal_class_method ||= :unmarshal
+      end
+
+      def assert_can_marshal(cls)
+        cls = cls.type if cls.is_a? RpcDesc::Stream
+        mth = unmarshal_class_method
+        unless cls.methods.include? mth
           fail(ArgumentError, "#{cls} needs #{cls}.#{mth}")
         end
+        mth = marshal_class_method
+        return if cls.methods.include? mth
+        fail(ArgumentError, "#{cls} needs #{cls}.#{mth}")
+      end
 
-        # @param cls [Class] the class of a serializable type
-        # @return cls wrapped in a RpcDesc::Stream
-        def stream(cls)
-          assert_can_marshal(cls)
-          RpcDesc::Stream.new(cls)
-        end
+      # @param cls [Class] the class of a serializable type
+      # @return cls wrapped in a RpcDesc::Stream
+      def stream(cls)
+        assert_can_marshal(cls)
+        RpcDesc::Stream.new(cls)
+      end
 
-        # the RpcDescs defined for this GenericService, keyed by name.
-        def rpc_descs
-          @rpc_descs ||= {}
-        end
+      # the RpcDescs defined for this GenericService, keyed by name.
+      def rpc_descs
+        @rpc_descs ||= {}
+      end
 
-        # Creates a rpc client class with methods for accessing the methods
-        # currently in rpc_descs.
-        def rpc_stub_class
-          descs = rpc_descs
-          route_prefix = service_name
-          Class.new(ClientStub) do
-            # @param host [String] the host the stub connects to
-            # @param kw [KeywordArgs] the channel arguments, plus any optional
-            #                         args for configuring the client's channel
-            def initialize(host, **kw)
-              super(host, Core::CompletionQueue.new, **kw)
-            end
+      # Creates a rpc client class with methods for accessing the methods
+      # currently in rpc_descs.
+      def rpc_stub_class
+        descs = rpc_descs
+        route_prefix = service_name
+        Class.new(ClientStub) do
+          # @param host [String] the host the stub connects to
+          # @param kw [KeywordArgs] the channel arguments, plus any optional
+          #                         args for configuring the client's channel
+          def initialize(host, **kw)
+            super(host, Core::CompletionQueue.new, **kw)
+          end
 
-            # Used define_method to add a method for each rpc_desc.  Each method
-            # calls the base class method for the given descriptor.
-            descs.each_pair do |name, desc|
-              mth_name = name.to_s.underscore.to_sym
-              marshal = desc.marshal_proc
-              unmarshal = desc.unmarshal_proc(:output)
-              route = "/#{route_prefix}/#{name}"
-              if desc.request_response?
-                define_method(mth_name) do |req, deadline = nil|
-                  logger.debug("calling #{@host}:#{route}")
-                  request_response(route, req, marshal, unmarshal, deadline)
-                end
-              elsif desc.client_streamer?
-                define_method(mth_name) do |reqs, deadline = nil|
-                  logger.debug("calling #{@host}:#{route}")
-                  client_streamer(route, reqs, marshal, unmarshal, deadline)
-                end
-              elsif desc.server_streamer?
-                define_method(mth_name) do |req, deadline = nil, &blk|
-                  logger.debug("calling #{@host}:#{route}")
-                  server_streamer(route, req, marshal, unmarshal, deadline,
-                                  &blk)
-                end
-              else  # is a bidi_stream
-                define_method(mth_name) do |reqs, deadline = nil, &blk|
-                  logger.debug("calling #{@host}:#{route}")
-                  bidi_streamer(route, reqs, marshal, unmarshal, deadline, &blk)
-                end
+          # Used define_method to add a method for each rpc_desc.  Each method
+          # calls the base class method for the given descriptor.
+          descs.each_pair do |name, desc|
+            mth_name = name.to_s.underscore.to_sym
+            marshal = desc.marshal_proc
+            unmarshal = desc.unmarshal_proc(:output)
+            route = "/#{route_prefix}/#{name}"
+            if desc.request_response?
+              define_method(mth_name) do |req, deadline = nil|
+                logger.debug("calling #{@host}:#{route}")
+                request_response(route, req, marshal, unmarshal, deadline)
+              end
+            elsif desc.client_streamer?
+              define_method(mth_name) do |reqs, deadline = nil|
+                logger.debug("calling #{@host}:#{route}")
+                client_streamer(route, reqs, marshal, unmarshal, deadline)
+              end
+            elsif desc.server_streamer?
+              define_method(mth_name) do |req, deadline = nil, &blk|
+                logger.debug("calling #{@host}:#{route}")
+                server_streamer(route, req, marshal, unmarshal, deadline,
+                                &blk)
+              end
+            else  # is a bidi_stream
+              define_method(mth_name) do |reqs, deadline = nil, &blk|
+                logger.debug("calling #{@host}:#{route}")
+                bidi_streamer(route, reqs, marshal, unmarshal, deadline, &blk)
               end
             end
           end
         end
+      end
 
-        # Asserts that the appropriate methods are defined for each added rpc
-        # spec. Is intended to aid verifying that server classes are correctly
-        # implemented.
-        def assert_rpc_descs_have_methods
-          rpc_descs.each_pair do |m, spec|
-            mth_name = m.to_s.underscore.to_sym
-            unless instance_methods.include?(mth_name)
-              fail "#{self} does not provide instance method '#{mth_name}'"
-            end
-            spec.assert_arity_matches(instance_method(mth_name))
+      # Asserts that the appropriate methods are defined for each added rpc
+      # spec. Is intended to aid verifying that server classes are correctly
+      # implemented.
+      def assert_rpc_descs_have_methods
+        rpc_descs.each_pair do |m, spec|
+          mth_name = m.to_s.underscore.to_sym
+          unless instance_methods.include?(mth_name)
+            fail "#{self} does not provide instance method '#{mth_name}'"
           end
+          spec.assert_arity_matches(instance_method(mth_name))
         end
       end
+    end
 
-      def self.included(o)
-        o.extend(Dsl)
-        # Update to the use the service name including module. Proivde a default
-        # that can be nil e,g. when modules are declared dynamically.
-        return unless o.service_name.nil?
-        if o.name.nil?
-          o.service_name = 'GenericService'
+    def self.included(o)
+      o.extend(Dsl)
+      # Update to the use the service name including module. Proivde a default
+      # that can be nil e,g. when modules are declared dynamically.
+      return unless o.service_name.nil?
+      if o.name.nil?
+        o.service_name = 'GenericService'
+      else
+        modules = o.name.split('::')
+        if modules.length > 2
+          o.service_name = modules[modules.length - 2]
         else
-          modules = o.name.split('::')
-          if modules.length > 2
-            o.service_name = modules[modules.length - 2]
-          else
-            o.service_name = modules.first
-          end
+          o.service_name = modules.first
         end
       end
     end
diff --git a/src/ruby/lib/grpc/logconfig.rb b/src/ruby/lib/grpc/logconfig.rb
index 6442f23e895b5b793dad6a1202a7604b727660bf..f36906fc45f458acb9abebb5a19d8d590349bddc 100644
--- a/src/ruby/lib/grpc/logconfig.rb
+++ b/src/ruby/lib/grpc/logconfig.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,6 @@ Logging.logger.root.appenders = Logging.appenders.stdout
 Logging.logger.root.level = :info
 
 # TODO: provide command-line configuration for logging
-Logging.logger['Google::RPC'].level = :debug
-Logging.logger['Google::RPC::ActiveCall'].level = :info
-Logging.logger['Google::RPC::BidiCall'].level = :info
+Logging.logger['GRPC'].level = :debug
+Logging.logger['GRPC::ActiveCall'].level = :info
+Logging.logger['GRPC::BidiCall'].level = :info
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index dd526e583a6e3611c075dc6ee77051fb68583428..d4eb0ed24f65a3125bcd0adcbbca92f94907d9c6 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,9 +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.
 
-module Google
-  # Google::RPC contains the General RPC module.
-  module RPC
-    VERSION = '0.0.1'
-  end
+# GRPC contains the General RPC module.
+module GRPC
+  VERSION = '0.0.1'
 end
diff --git a/src/ruby/spec/alloc_spec.rb b/src/ruby/spec/alloc_spec.rb
index 6dd59ab9fcebf310822dc2e790428ad26ebad4c8..88e7e2b3e7ac10441f5cad7af6fe28c888449da1 100644
--- a/src/ruby/spec/alloc_spec.rb
+++ b/src/ruby/spec/alloc_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/auth/compute_engine_spec.rb b/src/ruby/spec/auth/compute_engine_spec.rb
index 9e0b4660fa5443b95197c4c7ad431e4e05a42642..c43214d08610305b0908ac725943f2bc38b241ee 100644
--- a/src/ruby/spec/auth/compute_engine_spec.rb
+++ b/src/ruby/spec/auth/compute_engine_spec.rb
@@ -36,9 +36,9 @@ require 'faraday'
 require 'grpc/auth/compute_engine'
 require 'spec_helper'
 
-describe Google::RPC::Auth::GCECredentials do
+describe GRPC::Auth::GCECredentials do
   MD_URI = '/computeMetadata/v1/instance/service-accounts/default/token'
-  GCECredentials = Google::RPC::Auth::GCECredentials
+  GCECredentials = GRPC::Auth::GCECredentials
 
   before(:example) do
     @client = GCECredentials.new
diff --git a/src/ruby/spec/auth/service_account_spec.rb b/src/ruby/spec/auth/service_account_spec.rb
index cbc6a73ac20c245ecb98d8096e94820487a55fcd..2f14a1ae053260d00b04c4293dbc057ac2f7e080 100644
--- a/src/ruby/spec/auth/service_account_spec.rb
+++ b/src/ruby/spec/auth/service_account_spec.rb
@@ -38,7 +38,7 @@ require 'multi_json'
 require 'openssl'
 require 'spec_helper'
 
-describe Google::RPC::Auth::ServiceAccountCredentials do
+describe GRPC::Auth::ServiceAccountCredentials do
   before(:example) do
     @key = OpenSSL::PKey::RSA.new(2048)
     cred_json = {
@@ -49,7 +49,7 @@ describe Google::RPC::Auth::ServiceAccountCredentials do
       type: 'service_account'
     }
     cred_json_text = MultiJson.dump(cred_json)
-    @client = Google::RPC::Auth::ServiceAccountCredentials.new(
+    @client = GRPC::Auth::ServiceAccountCredentials.new(
         'https://www.googleapis.com/auth/userinfo.profile',
         StringIO.new(cred_json_text))
   end
diff --git a/src/ruby/spec/byte_buffer_spec.rb b/src/ruby/spec/byte_buffer_spec.rb
index 3a65f45c7ed2c9ab76ab417d04ed315f856b9bbd..e1833ebb3a0b479da1bae75f4aa8378cc282fb1a 100644
--- a/src/ruby/spec/byte_buffer_spec.rb
+++ b/src/ruby/spec/byte_buffer_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/call_spec.rb b/src/ruby/spec/call_spec.rb
index 8bb5043186b2f4dc1f4049066d90982dfcdf7830..26175645719e31f5cf4e6c8bf509f9be0e47644f 100644
--- a/src/ruby/spec/call_spec.rb
+++ b/src/ruby/spec/call_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb
index 82c7915debb61c5dca9c67b9c2867e51cb2b75e6..af73294abe429ad80478f42d8591fbb4afc53e62 100644
--- a/src/ruby/spec/channel_spec.rb
+++ b/src/ruby/spec/channel_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 1321727f5cf9dd68c7a5047f420d77eb5e8bb9ac..52c985786a8b5c983d907599f60fad19b8ba7034 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/completion_queue_spec.rb b/src/ruby/spec/completion_queue_spec.rb
index 6117e062d64b1db9f9721c11ab02846fd80fb9f5..11d4e9959cbadd9c43b1fc2f38cb11f5472ab798 100644
--- a/src/ruby/spec/completion_queue_spec.rb
+++ b/src/ruby/spec/completion_queue_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/credentials_spec.rb b/src/ruby/spec/credentials_spec.rb
index 47b42aed29b7610efd2b2c05c78b634c6e3d30a4..001fecd12b6233ebe6cea5021b3f8f60a02b58d4 100644
--- a/src/ruby/spec/credentials_spec.rb
+++ b/src/ruby/spec/credentials_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/event_spec.rb b/src/ruby/spec/event_spec.rb
index 89acd4ba67668ea174c1e43987405bf1b726e66e..7d92fcd792870c07c937a6213f780f01d2b89cb2 100644
--- a/src/ruby/spec/event_spec.rb
+++ b/src/ruby/spec/event_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index 86495d7369446563272b163b3adf8deecfc9abcd..84bb7b4f9bd9353e7e32fe429cfb63c22ca29698 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index c7218da2cff22cf145ac2aa811ff1c3fb659bfdf..297a13383137a3cc6c3a5b4231ef2072943cf824 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/generic/rpc_desc_spec.rb b/src/ruby/spec/generic/rpc_desc_spec.rb
index 54ccf7ab8b0db9957331aaaf17a1174f890fb29d..8bff2a9a644719c9d22cb2e064b4c4995692dee9 100644
--- a/src/ruby/spec/generic/rpc_desc_spec.rb
+++ b/src/ruby/spec/generic/rpc_desc_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb
index 27fabd9c312280e1afbdbb02657e7647337cf4cb..8383dc1533ee20a3124bdc882e78a3a748eb0889 100644
--- a/src/ruby/spec/generic/rpc_server_pool_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 0ec79572e7df0402b2ff907bdd3bd3a085ff3656..e8c706044617a7775d84ce65f5bb448438dc4b92 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/generic/service_spec.rb b/src/ruby/spec/generic/service_spec.rb
index 29f2412631990483128b84c27a32c7660589c8e3..e7f5a65d3b384ed607e38eed2b9d54a067c08d76 100644
--- a/src/ruby/spec/generic/service_spec.rb
+++ b/src/ruby/spec/generic/service_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/metadata_spec.rb b/src/ruby/spec/metadata_spec.rb
index 9cdce6b40d59ed1e7409b01351d66061e469d417..247286669210b5f1c56b172574e04f5aa658bd76 100644
--- a/src/ruby/spec/metadata_spec.rb
+++ b/src/ruby/spec/metadata_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/server_credentials_spec.rb b/src/ruby/spec/server_credentials_spec.rb
index faa713d562c968bf27702d4dab9be6b354189968..55598bc8dfd38060020276e5efbac176e3758886 100644
--- a/src/ruby/spec/server_credentials_spec.rb
+++ b/src/ruby/spec/server_credentials_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/server_spec.rb b/src/ruby/spec/server_spec.rb
index 1550ba656608dcc095fc99c1e99cc6f62910c1d6..5b81f195371d9b8a3b2301cc335b8bf160d7f63b 100644
--- a/src/ruby/spec/server_spec.rb
+++ b/src/ruby/spec/server_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/spec_helper.rb b/src/ruby/spec/spec_helper.rb
index ea0a256713183944d7fe90b8d6dc50818bc759ca..837d2fc42a1baad733ccde8cd42e3f432565581a 100644
--- a/src/ruby/spec/spec_helper.rb
+++ b/src/ruby/spec/spec_helper.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/ruby/spec/time_consts_spec.rb b/src/ruby/spec/time_consts_spec.rb
index b01027ce2678d30104091dfcd5cb705302ffc207..871e0e241acacb7b27796c387c9b5976d3403547 100644
--- a/src/ruby/spec/time_consts_spec.rb
+++ b/src/ruby/spec/time_consts_spec.rb
@@ -1,4 +1,4 @@
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 3e0f77c01429c94ea37db2893ed56f5bd9a26b14..f1f1badc16b17a9b7ac1cc867c7eeac8dd6e7ea0 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -103,7 +103,6 @@ CXX_tsan = clang++
 LD_tsan = clang
 LDXX_tsan = clang++
 CPPFLAGS_tsan = -O1 -fsanitize=thread -fno-omit-frame-pointer
-OPENSSL_CONFIG_tsan = no-asm
 LDFLAGS_tsan = -fsanitize=thread
 DEFINES_tsan = NDEBUG
 
@@ -114,7 +113,6 @@ CXX_asan = clang++
 LD_asan = clang
 LDXX_asan = clang++
 CPPFLAGS_asan = -O1 -fsanitize=address -fno-omit-frame-pointer
-OPENSSL_CONFIG_asan = no-asm
 LDFLAGS_asan = -fsanitize=address
 DEFINES_asan = NDEBUG
 
@@ -126,7 +124,6 @@ LD_msan = clang
 LDXX_msan = clang++-libc++
 CPPFLAGS_msan = -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
 OPENSSL_CFLAGS_msan = -DPURIFY
-OPENSSL_CONFIG_msan = no-asm
 LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
 DEFINES_msan = NDEBUG
 
@@ -138,7 +135,6 @@ LD_ubsan = clang
 LDXX_ubsan = clang++
 CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer
 OPENSSL_CFLAGS_ubsan = -DPURIFY
-OPENSSL_CONFIG_ubsan = no-asm
 LDFLAGS_ubsan = -fsanitize=undefined
 DEFINES_ubsan = NDEBUG
 
@@ -194,7 +190,9 @@ LDFLAGS += -g -fPIC
 
 INCLUDES = . include $(GENDIR)
 ifeq ($(SYSTEM),Darwin)
+INCLUDES += /usr/local/ssl/include /opt/local/include
 LIBS = m z
+LDFLAGS += -L/usr/local/ssl/lib -L/opt/local/lib
 else
 LIBS = rt m z pthread
 LDFLAGS += -pthread
@@ -347,7 +345,7 @@ endif
 
 .SECONDARY = %.pb.h %.pb.cc
 
-PROTOC_PLUGINS=\
+PROTOC_PLUGINS =\
 % for tgt in targets:
 % if tgt.build == 'protoc':
  $(BINDIR)/$(CONFIG)/${tgt.name}\
@@ -355,7 +353,7 @@ PROTOC_PLUGINS=\
 % endfor
 
 ifeq ($(DEP_MISSING),)
-all: static shared\
+all: static shared plugins\
 % for tgt in targets:
 % if tgt.build == 'all':
  $(BINDIR)/$(CONFIG)/${tgt.name}\
@@ -467,9 +465,9 @@ $(LIBDIR)/$(CONFIG)/zlib/libz.a:
 $(LIBDIR)/$(CONFIG)/openssl/libssl.a:
 	$(E) "[MAKE]    Building openssl for $(SYSTEM)"
 ifeq ($(SYSTEM),Darwin)
-	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./Configure darwin64-x86_64-cc $(OPENSSL_CONFIG_$(CONFIG)))
+	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./Configure darwin64-x86_64-cc)
 else
-	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./config $(OPENSSL_CONFIG_$(CONFIG)))
+	$(Q)(cd third_party/openssl ; CC="$(CC) -fPIC -fvisibility=hidden $(CPPFLAGS_$(CONFIG)) $(OPENSSL_CFLAGS_$(CONFIG))" ./config no-asm $(OPENSSL_CONFIG_$(CONFIG)))
 endif
 	$(Q)$(MAKE) -C third_party/openssl clean
 	$(Q)$(MAKE) -C third_party/openssl build_crypto build_ssl
@@ -527,6 +525,17 @@ shared_cxx: \
 % endfor
 
 
+shared_csharp: shared_c \
+% for lib in libs:
+% if lib.build == 'all' and lib.language == 'csharp':
+ $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT)\
+% endif
+% endfor
+
+grpc_csharp_ext: shared_csharp
+
+plugins: $(PROTOC_PLUGINS)
+
 privatelibs: privatelibs_c privatelibs_cxx
 
 privatelibs_c: \
@@ -660,6 +669,18 @@ ifeq ($(CONFIG),opt)
 % endfor
 endif
 
+strip-shared_csharp: shared_csharp
+ifeq ($(CONFIG),opt)
+% for lib in libs:
+% if lib.language == "csharp":
+% if lib.build == "all":
+	$(E) "[STRIP]   Stripping lib${lib.name}.so"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT)
+% endif
+% endif
+% endfor
+endif
+
 % for p in protos:
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/${p}.pb.cc: protoc_dep_error
@@ -667,7 +688,7 @@ else
 $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 % endfor
@@ -693,12 +714,16 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc
 	$(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
 
-install: install_c install_cxx
+install: install_c install_cxx install-protobuf install-plugins
 
 install_c: install-headers_c install-static_c install-shared_c
 
 install_cxx: install-headers_cxx install-static_cxx install-shared_cxx
 
+install_csharp: install-shared_csharp install_c
+
+install_grpc_csharp_ext: install_csharp
+
 install-headers: install-headers_c install-headers_cxx
 
 install-headers_c:
@@ -731,9 +756,9 @@ install-static_cxx: static_cxx strip-static_cxx
 % endif
 % endfor
 
-install-shared_c: shared_c strip-shared_c
+<%def name="install_shared(lang_filter)">\
 % for lib in libs:
-% if lib.language == "c":
+% if lib.language == lang_filter:
 % if lib.build == "all":
 ifeq ($(SYSTEM),MINGW32)
 	$(E) "[INSTALL] Installing ${lib.name}.$(SHARED_EXT)"
@@ -751,35 +776,45 @@ endif
 % endfor
 ifneq ($(SYSTEM),MINGW32)
 ifneq ($(SYSTEM),Darwin)
-	$(Q) ldconfig
+	$(Q) ldconfig || true
 endif
 endif
+</%def>
 
-install-shared_cxx: shared_cxx strip-shared_cxx
-% for lib in libs:
-% if lib.language == "c++":
-% if lib.build == "all":
-ifeq ($(SYSTEM),MINGW32)
-	$(E) "[INSTALL] Installing ${lib.name}.$(SHARED_EXT)"
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/${lib.name}.$(SHARED_EXT) $(prefix)/lib/${lib.name}.$(SHARED_EXT)
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
-else
-	$(E) "[INSTALL] Installing lib${lib.name}.$(SHARED_EXT)"
-	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT)
+install-shared_c: shared_c strip-shared_c
+${install_shared("c")}
+
+install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c
+${install_shared("c++")}
+
+install-shared_csharp: shared_csharp strip-shared_csharp
+${install_shared("csharp")}
+
+install-protobuf: $(PROTOBUF_DEP)
+ifneq ($(PROTOBUF_DEP),)
+	$(E) "[INSTALL] Installing embedded protobufs"
+	$(Q) $(MAKE) -C third_party/protobuf install prefix=$(prefix)
+ifneq ($(SYSTEM),MINGW32)
 ifneq ($(SYSTEM),Darwin)
-	$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so
+	$(Q) ldconfig || true
 endif
 endif
-% endif
+endif
+
+install-plugins: $(PROTOC_PLUGINS)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) false
+else
+	$(E) "[INSTALL] Installing grpc protoc plugins"
+% for tgt in targets:
+% if tgt.build == 'protoc':
+	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/${tgt.name} $(prefix)/bin/${tgt.name}
 % endif
 % endfor
-ifneq ($(SYSTEM),MINGW32)
-ifneq ($(SYSTEM),Darwin)
-	$(Q) ldconfig
-endif
 endif
 
 clean:
+	$(E) "[CLEAN]   Cleaning build directories."
 	$(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR)
 
 
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index d53098b5e42b84bc30bcd41e598c17e613f631bd..59a4564220b1c3c49c8bc058afaad73751330606 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -128,7 +128,7 @@ static void test_create_channel_stack(void) {
   grpc_channel_stack_destroy(channel_stack);
   gpr_free(channel_stack);
 
-  grpc_mdctx_orphan(metadata_context);
+  grpc_mdctx_unref(metadata_context);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/channel/metadata_buffer_test.c b/test/core/channel/metadata_buffer_test.c
index 60813089868703bf44ad4ef84e4d93cb48be7f0e..ba8100b7d2fc0b8c048f3e44301a33738b986d61 100644
--- a/test/core/channel/metadata_buffer_test.c
+++ b/test/core/channel/metadata_buffer_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -182,7 +182,7 @@ static void test_case(size_t key_prefix_len, size_t value_prefix_len,
   gpr_free(stk);
 
   grpc_metadata_buffer_destroy(&buffer, GRPC_OP_OK);
-  grpc_mdctx_orphan(mdctx);
+  grpc_mdctx_unref(mdctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 5f55fa68d3232177583fc4f8be1a5c2ca74640cd..4033c181310a6687784f1fcd099d1d0fdb7f67b0 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/echo/client.c b/test/core/echo/client.c
index 5652fd9f38bafa55aefa34b33ed6170e4c68eb6b..fb1e366b15b1e8450dccfb214cb4f02540a6f0b1 100644
--- a/test/core/echo/client.c
+++ b/test/core/echo/client.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/echo/echo_test.c b/test/core/echo/echo_test.c
index 5450dfbef56e5a27cabb9f4b564a488443ecef97..e2c4d22ef51ef3d4382a360d96575a1706c1784a 100644
--- a/test/core/echo/echo_test.c
+++ b/test/core/echo/echo_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/echo/server.c b/test/core/echo/server.c
index 6e494d50fff5ecf93ce3140b51ddb27b3cb6b9f9..83da8b644d6ca9cd0b5c226891be78134fb0a2f7 100644
--- a/test/core/echo/server.c
+++ b/test/core/echo/server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index 15dc4270d6ff23f5781fa415b2ae085b6e7ac246..9ed98a43457763e058a62aeddf34b45819ede4fa 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h
index 8b76bc421dfc7b6ead48dd2f59c460e2ec884832..ad6481102e72629445ebc487f89d07603ed2aa76 100644
--- a/test/core/end2end/cq_verifier.h
+++ b/test/core/end2end/cq_verifier.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/data/prod_roots_certs.c b/test/core/end2end/data/prod_roots_certs.c
index 3b66d236c368e7a7df10f8008bfd28118bb8ed74..0b1275f723ad713aa777092b3098ad355ce0dd0a 100644
--- a/test/core/end2end/data/prod_roots_certs.c
+++ b/test/core/end2end/data/prod_roots_certs.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/data/server1_cert.c b/test/core/end2end/data/server1_cert.c
index 134b9cb98e4799e91f464383e999ffd137502bcd..d31f2e2d0ed5fd3f4ff84624a796ebf68863ad85 100644
--- a/test/core/end2end/data/server1_cert.c
+++ b/test/core/end2end/data/server1_cert.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/data/server1_key.c b/test/core/end2end/data/server1_key.c
index 992d3c032a9c3a4c71339b949bbeef8bf58ad8cf..d089660bfd26570f1d49fd7653082f1c433594ab 100644
--- a/test/core/end2end/data/server1_key.c
+++ b/test/core/end2end/data/server1_key.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/data/ssl_test_data.h b/test/core/end2end/data/ssl_test_data.h
index 3456ebebd4b4733e6145c51df3d8e14a227dee53..ff89e0d69f237a9579540163b056594f285c7938 100644
--- a/test/core/end2end/data/ssl_test_data.h
+++ b/test/core/end2end/data/ssl_test_data.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/data/test_root_cert.c b/test/core/end2end/data/test_root_cert.c
index f358b0b79ac70133abf7c89ff5c9043031f35e58..58d98050175888f74477afcbab135417f97047d8 100644
--- a/test/core/end2end/data/test_root_cert.c
+++ b/test/core/end2end/data/test_root_cert.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index a61644f583c218e81c955dddadf61e24fc5294ea..2c4c3b77462548b5d937423c8ce59404436f7ba0 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index e222ed62bd7b56e115fb2d2d076f2f7f48fc0a0d..8f2cd0f2e05296bff9dcd99b921208022bdacbbb 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index 38c3b228342a8dc6f39dac7b0613f6f98731de33..039909f76cb0bead088ceef2dcd3eb8d5a8e3185 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_fullstack.c b/test/core/end2end/fixtures/chttp2_fullstack.c
index 82bf267ce50722972812e7d5a23b77c349b0a798..ea367f4446bb22c993081079ffbb033c131bdba4 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_uds.c b/test/core/end2end/fixtures/chttp2_fullstack_uds.c
index 35a23698e4de2fb2348307e843273ff3c2418bd0..27e4baf3c013ed8423b515132ddf3616b0c93321 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_uds.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_uds.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 149ac8c07bbb0e5205bc764845801e401f1774ef..1db9e727b869e28b2d947ace10bc4213f4b86729 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index fb241cd460cfa82605be19ae8f6c6b3333f53f46..35e022c4947b16bdae7a81f52bf9c2f5ea77a6ae 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair.c b/test/core/end2end/fixtures/chttp2_socket_pair.c
index b5b7cee85f3ee7337972b46a19d15c7b2517fed7..759c6b4b9d7bb231e9e24f1b0302ab7099c22b21 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
index 2de67913d7c4b275f11aa2d38bce22bba9a5a0b6..c814527a8f009a2452becdffe343c7de7cc76a56 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 85d95338ddbd4cbfd70ce8728011bacfb5f6fdc5..92e8e5ad6bf25e2ccc3c8a670e1a8727c08a6dbb 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index 18d6bcec06e0308c4ff8d5e2d2d287cecb7ddb2a..faaa14727c96b265547ae3060dc972722e995521 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -166,7 +166,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(2)));
+                                                      f.server_cq,
+                                                      tag(2)));
   cq_expect_completion(v_server, tag(2), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
index 889db54162464529db66af4b9ab5d5c5d7ae789c..c6fb8b3ea2edde5843441966e3f9b55fb41c15ca 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
index 245966624220ad9c5c72d765df3a1fa4f86b954d..85b7599b1950a0ae371c6cdd3a6922a300761664 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_after_accept_legacy.c b/test/core/end2end/tests/cancel_after_accept_legacy.c
index e87f7d648c2f098f9e49b5c924d12ab5809b20a9..345c31d31f881c828a0d25f1fb265403302ac1e0 100644
--- a/test/core/end2end/tests/cancel_after_accept_legacy.c
+++ b/test/core/end2end/tests/cancel_after_accept_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 7f7c1e6597da00733a38f7fb575974b3b6b8c879..3c75024922b4e9dac76fd6f23f1b2fec5292802f 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_after_invoke_legacy.c b/test/core/end2end/tests/cancel_after_invoke_legacy.c
index 7a656f1cb0be75030e002215431ec7bb06c31d77..64af7cd3db28f6816f75e395dab42d6499eb039f 100644
--- a/test/core/end2end/tests/cancel_after_invoke_legacy.c
+++ b/test/core/end2end/tests/cancel_after_invoke_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 663db5290d1db1f28cc9e3654d65193b9de29313..bee6dd2e7b92fe5d6020034e05b7f1b57abe074b 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_before_invoke_legacy.c b/test/core/end2end/tests/cancel_before_invoke_legacy.c
index cdd4b43447af8da45525f1f17654fe3a1727952c..23e82cf2683f4e9f2e517f71b9a4c59a43b9ac43 100644
--- a/test/core/end2end/tests/cancel_before_invoke_legacy.c
+++ b/test/core/end2end/tests/cancel_before_invoke_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index e19d28a41ed118b8316fb1ed04d0782c5e77cd61..8228353b09bb6677a031f67e9e8623f5d2e5008a 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
index c9870896c00ad1eddba513d913dde53d56ac1d9c..869f091180c648432a2c08fecda72b0c6effd44c 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/cancel_test_helpers.h b/test/core/end2end/tests/cancel_test_helpers.h
index 52ebc9052fc1399e32b49a836f3fbe7c2c04660e..3dd743735311eb4e0269ae2e1b85b9f10c9a888f 100644
--- a/test/core/end2end/tests/cancel_test_helpers.h
+++ b/test/core/end2end/tests/cancel_test_helpers.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
index f144cd17aa17679b330e85d439c11b384e648d8d..003a8bef9b761fae79dfe1404ce2658698487c03 100644
--- a/test/core/end2end/tests/census_simple_request.c
+++ b/test/core/end2end/tests/census_simple_request.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/census_simple_request_legacy.c b/test/core/end2end/tests/census_simple_request_legacy.c
index f144cd17aa17679b330e85d439c11b384e648d8d..003a8bef9b761fae79dfe1404ce2658698487c03 100644
--- a/test/core/end2end/tests/census_simple_request_legacy.c
+++ b/test/core/end2end/tests/census_simple_request_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 07de01059cc12d46a3f91a74532f19ffaf9412f8..611589678f40dea2967ac91def99b087af2bec53 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/disappearing_server_legacy.c b/test/core/end2end/tests/disappearing_server_legacy.c
index b75b268647c02bf4f64278f88d598cb17b0cd5b0..ff8832a231eed8277772cb47a55b13da0cf92bed 100644
--- a/test/core/end2end/tests/disappearing_server_legacy.c
+++ b/test/core/end2end/tests/disappearing_server_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
index 65de02ac1f0c469e286a3f89e9f8c41fd08b069b..49ec4715cc4a06e26ab4ccc3cae6d780de132662 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
index 6b920bb4ade3a6bc6224da5b5450c2b7721a01b0..2e3a05e6692d14325630f3f72eadb2b1bcd0f0e0 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
index 51486cc169986a1c5b29c5a6237959b7635a6013..49dddc79759f98a20c104ec093f10701d1e6081e 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
index 123c8bc4153577332937a3b066c2a6658d5e7795..ed8f839a973b8278946079d1646e88d05aeb1e7e 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index 65972a756e892189d5758e37889fa055429c3487..ab9792e40ab56126a53f5c16e3e0d41c31588e5d 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/graceful_server_shutdown_legacy.c b/test/core/end2end/tests/graceful_server_shutdown_legacy.c
index 20394965d3048894a4316ceec186fe90d2f53acc..852a153accd3d4e372eb10308a43979cee2218a1 100644
--- a/test/core/end2end/tests/graceful_server_shutdown_legacy.c
+++ b/test/core/end2end/tests/graceful_server_shutdown_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 10c1e0befb527c8c52823fe169a7f9af603646c5..2a302e2b137fe4220d53f81758cbf7cc9b3cdc88 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/invoke_large_request_legacy.c b/test/core/end2end/tests/invoke_large_request_legacy.c
index 8982d027012ae1e85687bac656347d425e776290..875458e7f805885ee54edc906acc32a17257b0eb 100644
--- a/test/core/end2end/tests/invoke_large_request_legacy.c
+++ b/test/core/end2end/tests/invoke_large_request_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 2ea8645ea71eca1c6d164f8902c96557367e88cb..85369b5aac43716220e6d5e7cd278dace54383f6 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/max_concurrent_streams_legacy.c b/test/core/end2end/tests/max_concurrent_streams_legacy.c
index d15368182a0c19b23774014c8c9fa0a17d8f8633..0cb118d7950f4ff03c3f21fa79e221b95016888a 100644
--- a/test/core/end2end/tests/max_concurrent_streams_legacy.c
+++ b/test/core/end2end/tests/max_concurrent_streams_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c
index bd4ff06701e99301017ea74c0108c95bdc440663..00d940ddb54e4a0a5182f268def7b402ea23b9b0 100644
--- a/test/core/end2end/tests/no_op.c
+++ b/test/core/end2end/tests/no_op.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/no_op_legacy.c b/test/core/end2end/tests/no_op_legacy.c
index bd4ff06701e99301017ea74c0108c95bdc440663..00d940ddb54e4a0a5182f268def7b402ea23b9b0 100644
--- a/test/core/end2end/tests/no_op_legacy.c
+++ b/test/core/end2end/tests/no_op_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 4e27be16b4af06902e03ee0aa0af09b165029181..2930ba61430d461b1f949778f46a6cc3e0264b26 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/ping_pong_streaming_legacy.c b/test/core/end2end/tests/ping_pong_streaming_legacy.c
index cd1d03e4cd8c0465ee6a2b5708eb79bbd6096565..b2764e9f858312bb05053b0d936910d8795c026a 100644
--- a/test/core/end2end/tests/ping_pong_streaming_legacy.c
+++ b/test/core/end2end/tests/ping_pong_streaming_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
index 940e327d22d40cdf87f442628f885ec1d2770b28..843e9db9edd9b4a8410b5771dfd45f69335c8cdb 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -175,7 +175,8 @@ static void test_request_response_with_metadata_and_payload(
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
index b5e4eea6c8699d92ad20d421c2f60287e9c2184a..9c09e516fae6898c45141a0fbe3c9311bc04f442 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
index 80cb629542bbe0bb545b4447723517b9e87aea73..7f7b594d807d7954f4041005952abd52b8da48d2 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -168,7 +168,8 @@ static void test_request_response_with_metadata_and_payload(
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
index a86e1aa7f95726c1b815d32455c117d5c30e80b5..ba330d5f5f8997c4913f415667812e219866bed5 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c
index b07f51da85e6dad52a191e20c45081589f37dc50..a0dc0331f4e047e02449117f102375f980304c6e 100644
--- a/test/core/end2end/tests/request_response_with_payload.c
+++ b/test/core/end2end/tests/request_response_with_payload.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -162,7 +162,8 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) {
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_payload_legacy.c b/test/core/end2end/tests/request_response_with_payload_legacy.c
index eaa88eb91ad3615fdc9783dbbc08c8476280abf6..be5627489949fc68bdaa7196d80f14262bd13c23 100644
--- a/test/core/end2end/tests/request_response_with_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_payload_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
index e5476046198b921884be5f79d708a50ba07c3625..bf3b19b62d410b55cf82b4975c134e2db02ffd46 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -169,7 +169,8 @@ static void test_request_response_with_metadata_and_payload(
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
index d6554b2792320c1b16f088517914c39500aff0f6..0ed0f985ec84a8a7318d1a91b14b265d44ac9e2b 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c
index eb6180c399f377643926dbadbf4b69e149e7e2cc..753410401884cf55291f70679916f7a33a1e77d0 100644
--- a/test/core/end2end/tests/request_with_large_metadata.c
+++ b/test/core/end2end/tests/request_with_large_metadata.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -166,7 +166,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_with_large_metadata_legacy.c b/test/core/end2end/tests/request_with_large_metadata_legacy.c
index d768f148efe7d16b721b7dcafeaf9fbe2bea61aa..bc3b3800139e5049ecbdbb9d76014d9ae88b0adc 100644
--- a/test/core/end2end/tests/request_with_large_metadata_legacy.c
+++ b/test/core/end2end/tests/request_with_large_metadata_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index 2bf0fa3717fdaecd359baa42cb621a9464d7eff4..bb13512ad427e97c009e0ef9e172a35b912a9155 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -157,7 +157,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_with_payload_legacy.c b/test/core/end2end/tests/request_with_payload_legacy.c
index 8d932afb35c47fc9db30e7bd453d563fe55a3d4a..b56e08cf1fcd7569b99441fa0eefe70b0f3fa817 100644
--- a/test/core/end2end/tests/request_with_payload_legacy.c
+++ b/test/core/end2end/tests/request_with_payload_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index 80763fe6cd8d714b94f7ddd404e982a4391e576e..0a3eb7c7b79ec5f3b629d180a00beced77de5885 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -144,7 +144,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f->server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f->server_cq, tag(101)));
+                                                      f->server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/simple_delayed_request_legacy.c b/test/core/end2end/tests/simple_delayed_request_legacy.c
index 6b211ecccf87b40aeee20842b4467018197d1868..3c94de548ea63d945111bc11f06d1e241b704ad3 100644
--- a/test/core/end2end/tests/simple_delayed_request_legacy.c
+++ b/test/core/end2end/tests/simple_delayed_request_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 968be74cfb93e9f23e33ecb7effbf47be83317d1..591bc52dc5b0fc7d13d2d6e6a91cecbceca97130 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -150,7 +150,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq, tag(101)));
+                                                      f.server_cq,
+                                                      tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/simple_request_legacy.c b/test/core/end2end/tests/simple_request_legacy.c
index eb984cee978e88a2f7b41b6b81a89a1dae78aa62..2e30d101e18d26b991bacc5ae12873665f8a379f 100644
--- a/test/core/end2end/tests/simple_request_legacy.c
+++ b/test/core/end2end/tests/simple_request_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/thread_stress.c b/test/core/end2end/tests/thread_stress.c
index 8a5cdc7e92bd172fa2510e5e177385864e8216c1..c10b3737441dc346f223e867140de00458bb72ba 100644
--- a/test/core/end2end/tests/thread_stress.c
+++ b/test/core/end2end/tests/thread_stress.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/thread_stress_legacy.c b/test/core/end2end/tests/thread_stress_legacy.c
index 8a5cdc7e92bd172fa2510e5e177385864e8216c1..c10b3737441dc346f223e867140de00458bb72ba 100644
--- a/test/core/end2end/tests/thread_stress_legacy.c
+++ b/test/core/end2end/tests/thread_stress_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
index e7b7da17569bfc9b18a872434e7da0f732c2b6d3..5f8b9974d68279986d13be659699c4ef0f08b448 100644
--- a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
+++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
index e7b7da17569bfc9b18a872434e7da0f732c2b6d3..5f8b9974d68279986d13be659699c4ef0f08b448 100644
--- a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
+++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index 0a113f033f75cfa5d4e4052601b2d7c983c62267..68164b1c5a51fa16f4327ee89f3cf09eb24521ff 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c
index 1db2f1a7916f817d973403f62429215429c7ae1a..41ba995544b3e0512c61b3f898dabf3473fad113 100644
--- a/test/core/fling/fling_stream_test.c
+++ b/test/core/fling/fling_stream_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c
index 4f41a21aaafa3ae182eb7379de2bd182387b3b5b..c0066cf1013953c4085655c826807cccc088ad0a 100644
--- a/test/core/fling/fling_test.c
+++ b/test/core/fling/fling_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index ca0683fa6797f9b795a0ffe15c257ffea50ad2ac..59c303015a3935413407afc0460bd7dc51c8aede 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/httpcli/format_request_test.c b/test/core/httpcli/format_request_test.c
index ec66f9600421457598e31c7c501171146f1745fb..da850049e20dafed7e32a7b11f26b5463b1b760a 100644
--- a/test/core/httpcli/format_request_test.c
+++ b/test/core/httpcli/format_request_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index c901e595f635486d395ba3b1eeab5ffb9d26170f..599b3ad4eaaf0536ceb94235d022be76aa3243fc 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/httpcli/parser_test.c b/test/core/httpcli/parser_test.c
index 455f6a6393902dce139173f3a9310007839d190c..dacec0f72f700b737ea73d0c9fb10493454cd5a2 100644
--- a/test/core/httpcli/parser_test.c
+++ b/test/core/httpcli/parser_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/alarm_heap_test.c b/test/core/iomgr/alarm_heap_test.c
index abb1086a22d7e36c953b135df12730e1c2f9e4f0..b3e1e64d0feb1b42fc33e77b4de46c5d5af8287e 100644
--- a/test/core/iomgr/alarm_heap_test.c
+++ b/test/core/iomgr/alarm_heap_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/alarm_list_test.c b/test/core/iomgr/alarm_list_test.c
index a25095123188909a0b6db9655f50075681b2d589..f2ccd1fb357f9405f3c9c0fdab20b54770d155f8 100644
--- a/test/core/iomgr/alarm_list_test.c
+++ b/test/core/iomgr/alarm_list_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/alarm_test.c b/test/core/iomgr/alarm_test.c
index aec3a50efc63818484282b2d900b342f09f8d5e4..18f57725a26e42beb0a6c936000ff56391f191a0 100644
--- a/test/core/iomgr/alarm_test.c
+++ b/test/core/iomgr/alarm_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 125cde467853f4adac1b1e41fb8855a231bbc31e..c08ee7d48f22c28665ba854085b9b1e80a371ec7 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/endpoint_tests.h b/test/core/iomgr/endpoint_tests.h
index c76c9483c6a9304987c0ef55eb544e4305ed5baa..3be377c4e3dc121587cacdfced292f4223c64c4a 100644
--- a/test/core/iomgr/endpoint_tests.h
+++ b/test/core/iomgr/endpoint_tests.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 05c91ffdd4d8071085cf5bfa7cfa4280ba06c38e..22090ead0ac275bf02137755efdf3ca7b2e2494a 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 1f97724e607a4b748e6b9da28b5f108c99fdcbec..0961a3659f66d01f294ac6921deaf8c59bf9d569 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c
index 6cbdc4e21c17d39d6de7dbe2eb44eee920767c31..9f5e954b9dedae0fde068d47da2e80ab6be30bb1 100644
--- a/test/core/iomgr/sockaddr_utils_test.c
+++ b/test/core/iomgr/sockaddr_utils_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index 78709f47fbcb113975b8ff02aae0cab27c6f8874..ad5a31704483720b3ed3d6d666ed8bce4a62822a 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index f52ae229812b8d114dca2f91f40c429c53954b34..0f81ba77344a9b4064e727eab9952fcd93585adc 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -250,7 +250,7 @@ struct write_socket_state {
 
 static gpr_slice *allocate_blocks(ssize_t num_bytes, ssize_t slice_size,
                                   size_t *num_blocks, int *current_data) {
-  ssize_t nslices = num_bytes / slice_size + (num_bytes % slice_size ? 1 : 0);
+  size_t nslices = num_bytes / slice_size + (num_bytes % slice_size ? 1 : 0);
   gpr_slice *slices = gpr_malloc(sizeof(gpr_slice) * nslices);
   ssize_t num_bytes_left = num_bytes;
   unsigned i, j;
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index e906f302cf63f0e7d6b20c8c319dc1c50e3d2f79..b26115bcd00ceafda28b3b18f4fedde566b38794 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@ static void test_no_op(void) {
 static void test_no_op_with_start(void) {
   grpc_tcp_server *s = grpc_tcp_server_create();
   LOG_TEST();
-  grpc_tcp_server_start(s, NULL, on_connect, NULL);
+  grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
   grpc_tcp_server_destroy(s);
 }
 
@@ -93,7 +93,7 @@ static void test_no_op_with_port_and_start(void) {
   GPR_ASSERT(
       grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
 
-  grpc_tcp_server_start(s, NULL, on_connect, NULL);
+  grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
 
   grpc_tcp_server_destroy(s);
 }
@@ -120,7 +120,7 @@ static void test_connect(int n) {
   GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0);
   GPR_ASSERT(addr_len <= sizeof(addr));
 
-  grpc_tcp_server_start(s, NULL, on_connect, NULL);
+  grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
 
   for (i = 0; i < n; i++) {
     deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(10000000));
diff --git a/test/core/iomgr/time_averaged_stats_test.c b/test/core/iomgr/time_averaged_stats_test.c
index bbfeab5633010977c416baf8ac127f82fac0a081..4206a1c58f316b7d8b7b4bec62a75e63f8d822cb 100644
--- a/test/core/iomgr/time_averaged_stats_test.c
+++ b/test/core/iomgr/time_averaged_stats_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/json/json_rewrite.c b/test/core/json/json_rewrite.c
index a761a670f0e9652523041a03887d40327788f306..203e75c7d5776e589742fd5e378bafbfeee0a409 100644
--- a/test/core/json/json_rewrite.c
+++ b/test/core/json/json_rewrite.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/json/json_rewrite_test.c b/test/core/json/json_rewrite_test.c
index 4ce406c9909ae86f5f2f9751fe1f69d283cfc915..78dff92a777c96dd2ca124c4f8392b42b68a4fd8 100644
--- a/test/core/json/json_rewrite_test.c
+++ b/test/core/json/json_rewrite_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c
index 6d0227ad39b009ef86a3e3f070a9b82dce448517..0e315e51eeef0ef6858a15031bebe8847a6eadb6 100644
--- a/test/core/json/json_test.c
+++ b/test/core/json/json_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c
index 9a6f518399c4633dc765a61fe6c07e521f191f43..f0a3e26c4eeb82bf6aa794de3ee9d4e3f0b779d0 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.c
+++ b/test/core/network_benchmarks/low_level_ping_pong.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/security/base64_test.c b/test/core/security/base64_test.c
index b3ba491a341d47944c587ae7d57e349f76a006ce..bfd5c4877728f5c363aef374d1976dea9ae50315 100644
--- a/test/core/security/base64_test.c
+++ b/test/core/security/base64_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index dd90a7edc857a81b307df9d3eb22eab8665c60fb..f911db6de1f33174029451b8103d78782e660692 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -138,7 +138,7 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
   GPR_ASSERT(!strcmp(grpc_mdstr_as_c_string(token_elem->value),
                      "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"));
   grpc_mdelem_unref(token_elem);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
@@ -150,7 +150,7 @@ static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
@@ -161,7 +161,7 @@ static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
@@ -176,7 +176,7 @@ static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
@@ -190,7 +190,7 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
@@ -205,7 +205,7 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
@@ -220,7 +220,7 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
   GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
                  &response, ctx, &token_elem, &token_lifetime) ==
              GRPC_CREDENTIALS_ERROR);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void check_metadata(expected_md *expected, grpc_mdelem **md_elems,
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
index c5cc3adfd699a27a1df3310b29bb92df3eadbbf1..6315087448947b0644e7b31e4a99044e14e41941 100644
--- a/test/core/security/fetch_oauth2.c
+++ b/test/core/security/fetch_oauth2.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -95,7 +95,7 @@ static grpc_credentials *create_service_account_creds(
       break;
     }
     current += bytes_read;
-  } while (sizeof(json_key) > (current - json_key));
+  } while (sizeof(json_key) > (size_t)(current - json_key));
 
   if ((current - json_key) == sizeof(json_key)) {
     gpr_log(GPR_ERROR, "Json key file %s exceeds size limit (%d bytes).",
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 2a9c8f88b24e3f7f3188cdcf266ef3d48696bc45..8615fca5fbb4346e2dee1eef096b985215e3d55c 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index 456515bfd5030781a29a9682dbe88fec8a3ed15f..03a4d3a1e691f1735a38ac22c6d3f8609d8982d3 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/census_log_tests.c b/test/core/statistics/census_log_tests.c
index c7b2b2e46dcfe82bd54c90787fdbdec7bd3c8a3b..fbc96bbde610f188a9773b01b99a921e251d2843 100644
--- a/test/core/statistics/census_log_tests.c
+++ b/test/core/statistics/census_log_tests.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "src/core/support/cpu.h"
+#include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/sync.h>
diff --git a/test/core/statistics/census_log_tests.h b/test/core/statistics/census_log_tests.h
index 764b9fde1957b961fa72b1dfcfe8465082444783..f829ab36833ae9f57d4ece1d1c30daf6ae110a21 100644
--- a/test/core/statistics/census_log_tests.h
+++ b/test/core/statistics/census_log_tests.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/census_stub_test.c b/test/core/statistics/census_stub_test.c
index c651eaf21ff293094b0bdae432fa27cbe4440258..26a45ae58a954880c7226b79395a59bddd71254b 100644
--- a/test/core/statistics/census_stub_test.c
+++ b/test/core/statistics/census_stub_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c
index e8e4d8b6f1d985eb03a9af540b684611c9e78757..2752d6d89d549c5fc1f14fd1c201c0d532996f07 100644
--- a/test/core/statistics/hash_table_test.c
+++ b/test/core/statistics/hash_table_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -97,7 +97,7 @@ static void test_table_with_int_key(void) {
   for (i = 0; i < 20; ++i) {
     census_ht_key key;
     key.val = i;
-    census_ht_insert(ht, key, (void*)i);
+    census_ht_insert(ht, key, (void*)(gpr_intptr)i);
     GPR_ASSERT(census_ht_get_size(ht) == i + 1);
   }
   for (i = 0; i < 20; i++) {
@@ -105,7 +105,7 @@ static void test_table_with_int_key(void) {
     census_ht_key key;
     key.val = i;
     val = census_ht_find(ht, key);
-    GPR_ASSERT(val == (void*)i);
+    GPR_ASSERT(val == (void*)(gpr_intptr)i);
   }
   elements = census_ht_get_all_elements(ht, &num_elements);
   GPR_ASSERT(elements != NULL);
diff --git a/test/core/statistics/multiple_writers_circular_buffer_test.c b/test/core/statistics/multiple_writers_circular_buffer_test.c
index 298900a6612b0041c9f7c0eccedf505cd85bcfee..a645e15918a93276d6034b816f95d3bc092e6346 100644
--- a/test/core/statistics/multiple_writers_circular_buffer_test.c
+++ b/test/core/statistics/multiple_writers_circular_buffer_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/multiple_writers_test.c b/test/core/statistics/multiple_writers_test.c
index ae6fd956514881c16d08143feeba4c486fa4d017..84aef15c1a9c4d0e09482b9b4fdbe79e332a8d25 100644
--- a/test/core/statistics/multiple_writers_test.c
+++ b/test/core/statistics/multiple_writers_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/performance_test.c b/test/core/statistics/performance_test.c
index 40fe4c59114590fe7efde3b568d72b53c376efdd..3c1e28241ec7867699a5f96862907a78d1992a5a 100644
--- a/test/core/statistics/performance_test.c
+++ b/test/core/statistics/performance_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/quick_test.c b/test/core/statistics/quick_test.c
index 8df32cf111768b631b111efa49051b9991613179..0e432314bbad5a2644adb3c43c83f90fda0df446 100644
--- a/test/core/statistics/quick_test.c
+++ b/test/core/statistics/quick_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/rpc_stats_test.c b/test/core/statistics/rpc_stats_test.c
index 1e929d18ef05cdf53131cfb5352bd2f2e7c08dda..df076b9c1e48752006f2a92326c7185578d0e52b 100644
--- a/test/core/statistics/rpc_stats_test.c
+++ b/test/core/statistics/rpc_stats_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/small_log_test.c b/test/core/statistics/small_log_test.c
index ff3aee9eae3f903abcc74100ad828888b052b0d4..c151b77f6391585b4c433913d569cda7147bda2f 100644
--- a/test/core/statistics/small_log_test.c
+++ b/test/core/statistics/small_log_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c
index 97e1463ae134edbc7a2c8bdb5f64af6564a1e404..65b70e1006a266d74b3b6ae5cb1f53a20dc148b2 100644
--- a/test/core/statistics/trace_test.c
+++ b/test/core/statistics/trace_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/statistics/window_stats_test.c b/test/core/statistics/window_stats_test.c
index 1fe7747740801df98d27b28c50d2fc02716e8b96..d893f7f792b7fe005b56e717ebd5dacdeabf5db9 100644
--- a/test/core/statistics/window_stats_test.c
+++ b/test/core/statistics/window_stats_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/cancellable_test.c b/test/core/support/cancellable_test.c
index e90c999921d7a7fd2f039744529fd91aae575bd6..b2db1afc7619ef87dc27d4b00b6d0e41ca3cb9c9 100644
--- a/test/core/support/cancellable_test.c
+++ b/test/core/support/cancellable_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/cmdline_test.c b/test/core/support/cmdline_test.c
index 1d15c662898c8e8904681ecb8eae4a7e00bad04b..52c311f75c287ad8f6e99164dac4609359a3332f 100644
--- a/test/core/support/cmdline_test.c
+++ b/test/core/support/cmdline_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/env_test.c b/test/core/support/env_test.c
index 36d7adf80b592deba83ddd673610d1354434b7b0..1f16af87a5a6973ec01e58965404d5e9973b0596 100644
--- a/test/core/support/env_test.c
+++ b/test/core/support/env_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/file_test.c b/test/core/support/file_test.c
index b089954186c17829b1613354c38b01ea1047d4b9..c0c14ffa0e5e079d722041e2bfbe8c7d13888c9b 100644
--- a/test/core/support/file_test.c
+++ b/test/core/support/file_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/histogram_test.c b/test/core/support/histogram_test.c
index 4769ce0599894bbcdbdf89d5fafd4a429b20e900..39944308743ec0b0af02bd6b0cd5de574af46175 100644
--- a/test/core/support/histogram_test.c
+++ b/test/core/support/histogram_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/host_port_test.c b/test/core/support/host_port_test.c
index 6d14fab8636919c973db9655c7d18afaa8c01e15..eccc39a2db113bf638edf4684751d1ba8039306f 100644
--- a/test/core/support/host_port_test.c
+++ b/test/core/support/host_port_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/log_test.c b/test/core/support/log_test.c
index 3ee40b6d76d467c8e0bb416b19fec6fd295af7b7..b39b0699134199ba6d68c61426ca8244c5d910be 100644
--- a/test/core/support/log_test.c
+++ b/test/core/support/log_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/murmur_hash_test.c b/test/core/support/murmur_hash_test.c
index 366bcb20bf601c0a8a85405d036b0a20ce6343aa..e3890a79dad38386ab8e9fd2f24fc6a9a84adcd1 100644
--- a/test/core/support/murmur_hash_test.c
+++ b/test/core/support/murmur_hash_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/slice_buffer_test.c b/test/core/support/slice_buffer_test.c
index 030d1d4249a3d2c893241c33dffe194b1e858a0a..8301795dbfda7b275785c8a71e8f9f4c728b73d5 100644
--- a/test/core/support/slice_buffer_test.c
+++ b/test/core/support/slice_buffer_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c
index 469d7dedc3b237238eb3dda7af3e4f224ef4989c..4ab3d6f45b9a99f52e36dc9e26ca2b21dd60278b 100644
--- a/test/core/support/slice_test.c
+++ b/test/core/support/slice_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c
index a01ec6f87f37989a9147ff96b12b1760b7bb3ad9..a78e4782a29f0dbd64a0cdd4d721cee18d69f9cc 100644
--- a/test/core/support/string_test.c
+++ b/test/core/support/string_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c
index 540d9d1c643c7f38a986a85c1f92dc00551b0a62..43d05c6302b7fbcb921d615820a8b3ebcf7527aa 100644
--- a/test/core/support/sync_test.c
+++ b/test/core/support/sync_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/thd_test.c b/test/core/support/thd_test.c
index c70e025326f9f87ff212c6e9864e319d623a2434..c03a905d2af2540dc0593c85a98bbe39f71e9ff8 100644
--- a/test/core/support/thd_test.c
+++ b/test/core/support/thd_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c
index 56f927787bc39ce8da33b52ca4bf46dafb5cc229..2741e17f95f10f0014316435f4be6000c845dd84 100644
--- a/test/core/support/time_test.c
+++ b/test/core/support/time_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/support/useful_test.c b/test/core/support/useful_test.c
index 716861665b5a55b8cc6da5d5da011cd7e7b8c186..feaf4363795ea26683f37490fc358e869892fd72 100644
--- a/test/core/support/useful_test.c
+++ b/test/core/support/useful_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index d78dd641ad6cd4e9e6a6bfacaadc0fe9dd4788f0..b121abf75728ae90cc91063d76b97cc835144e1e 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/surface/completion_queue_benchmark.c b/test/core/surface/completion_queue_benchmark.c
index e1b9d0d035aa0d2ab90967f5a9df2a7a2d638f46..9116fd0fe4c8fb1653d9c234a9bca10a8dd68fdc 100644
--- a/test/core/surface/completion_queue_benchmark.c
+++ b/test/core/surface/completion_queue_benchmark.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index 875cf3e52aa6df818658f066ea46b8bda9a1c261..35f150c78158b6380022aaf3c9f9371979bbd7e1 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 0a6edc1630d94ee1439c31b34539dbea5c254640..0142768261d9a89523a8bc9a71ee6feeb59f665a 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/surface/multi_init_test.c b/test/core/surface/multi_init_test.c
index dced88257467b16716882d80af8a143963f66e64..99b7a52ff98bbef20b01752de404367991d9382d 100644
--- a/test/core/surface/multi_init_test.c
+++ b/test/core/surface/multi_init_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/chttp2/alpn_test.c b/test/core/transport/chttp2/alpn_test.c
index 7a70b0ca7f06936eb42ac45ab4d6afc78a924a8b..c2497d3b1a2bbce2ede48cdb1f3ff2e25dfd1996 100644
--- a/test/core/transport/chttp2/alpn_test.c
+++ b/test/core/transport/chttp2/alpn_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/chttp2/bin_encoder_test.c b/test/core/transport/chttp2/bin_encoder_test.c
index 048ed7edd3cb4f8a17a86c8211a015f76acbed30..983eaf5a0d7d43d4ed2657fa00f94561098bba38 100644
--- a/test/core/transport/chttp2/bin_encoder_test.c
+++ b/test/core/transport/chttp2/bin_encoder_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index 3be6c366f5c2387f656c36cf6175e3055565f405..86c6bb1f56aac43c3b1b8392138804f0e308dc8c 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -214,7 +214,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
               "set-cookie",
               "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
   grpc_chttp2_hpack_parser_destroy(&parser);
-  grpc_mdctx_orphan(mdctx);
+  grpc_mdctx_unref(mdctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index d155dee9dc2f4def53809a5e6161692a13bdac6c..d1e5f0829a87bf0372f4356a6090355ba513e841 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -126,7 +126,7 @@ static void test_static_lookup(void) {
   assert_index(&tbl, 61, "www-authenticate", "");
 
   grpc_chttp2_hptbl_destroy(&tbl);
-  grpc_mdctx_orphan(mdctx);
+  grpc_mdctx_unref(mdctx);
 }
 
 static void test_many_additions(void) {
@@ -158,7 +158,7 @@ static void test_many_additions(void) {
   }
 
   grpc_chttp2_hptbl_destroy(&tbl);
-  grpc_mdctx_orphan(mdctx);
+  grpc_mdctx_unref(mdctx);
 }
 
 static grpc_chttp2_hptbl_find_result find_simple(grpc_chttp2_hptbl *tbl,
@@ -262,7 +262,7 @@ static void test_find(void) {
   GPR_ASSERT(r.has_value == 0);
 
   grpc_chttp2_hptbl_destroy(&tbl);
-  grpc_mdctx_orphan(mdctx);
+  grpc_mdctx_unref(mdctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/chttp2/status_conversion_test.c b/test/core/transport/chttp2/status_conversion_test.c
index bb5d7b8860888a68db4e0c86f3e04176a96ce362..e2729a0a198ab8cdf7a6986118ec692cfb2fd966 100644
--- a/test/core/transport/chttp2/status_conversion_test.c
+++ b/test/core/transport/chttp2/status_conversion_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/chttp2/stream_encoder_test.c b/test/core/transport/chttp2/stream_encoder_test.c
index 5e8ec0a1af85135dbb3d34541a31167b97c6a913..5c7801079fe83cda66fed83c3aa166d0233b1f43 100644
--- a/test/core/transport/chttp2/stream_encoder_test.c
+++ b/test/core/transport/chttp2/stream_encoder_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -309,7 +309,7 @@ static void run_test(void (*test)(), const char *name) {
   grpc_sopb_init(&g_sopb);
   test();
   grpc_chttp2_hpack_compressor_destroy(&g_compressor);
-  grpc_mdctx_orphan(g_mdctx);
+  grpc_mdctx_unref(g_mdctx);
   grpc_sopb_destroy(&g_sopb);
 }
 
diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c
index 9b4446f7f8072b84986e71ed70f2ebe9dcd9df50..49d58114f87990e3bc3171fc29346649ee0fa3bd 100644
--- a/test/core/transport/chttp2/stream_map_test.c
+++ b/test/core/transport/chttp2/stream_map_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/chttp2/timeout_encoding_test.c b/test/core/transport/chttp2/timeout_encoding_test.c
index 56a1e6ee63864da27d4d46e2374660118ecec48f..fdb27a22ced42e5cdc26797e8fd5383fac1ed1cb 100644
--- a/test/core/transport/chttp2/timeout_encoding_test.c
+++ b/test/core/transport/chttp2/timeout_encoding_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/chttp2_transport_end2end_test.c b/test/core/transport/chttp2_transport_end2end_test.c
index 34e3aeba383724d1ddffe63f3f8bce4748b1602c..a3c9f97ce4c6ece3bef730125dbef2ee07676a42 100644
--- a/test/core/transport/chttp2_transport_end2end_test.c
+++ b/test/core/transport/chttp2_transport_end2end_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index a2d190e1c4e1cada3bc3e62efe10093d446547d7..f345cebdb6afdd818e78c2cc4f2bd0e8210b2681 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,7 @@
 #define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__)
 
 /* a large number */
-#define MANY 100000
+#define MANY 10000
 
 static void test_no_op(void) {
   grpc_mdctx *ctx;
@@ -52,7 +52,7 @@ static void test_no_op(void) {
   LOG_TEST();
 
   ctx = grpc_mdctx_create();
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_create_string(void) {
@@ -71,7 +71,7 @@ static void test_create_string(void) {
   GPR_ASSERT(gpr_slice_str_cmp(s3->slice, "very much not hello") == 0);
   grpc_mdstr_unref(s1);
   grpc_mdstr_unref(s2);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
   grpc_mdstr_unref(s3);
 }
 
@@ -95,7 +95,7 @@ static void test_create_metadata(void) {
   grpc_mdelem_unref(m1);
   grpc_mdelem_unref(m2);
   grpc_mdelem_unref(m3);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_create_many_ephemeral_metadata(void) {
@@ -116,7 +116,7 @@ static void test_create_many_ephemeral_metadata(void) {
   /* capacity should not grow */
   GPR_ASSERT(mdtab_capacity_before ==
              grpc_mdctx_get_mdtab_capacity_test_only(ctx));
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_create_many_persistant_metadata(void) {
@@ -145,7 +145,7 @@ static void test_create_many_persistant_metadata(void) {
   for (i = 0; i < MANY; i++) {
     grpc_mdelem_unref(created[i]);
   }
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 
   gpr_free(created);
 }
@@ -171,7 +171,7 @@ static void test_spin_creating_the_same_thing(void) {
   GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
   GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
 
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_things_stick_around(void) {
@@ -218,7 +218,7 @@ static void test_things_stick_around(void) {
     }
   }
 
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
   gpr_free(strs);
   gpr_free(shuf);
 }
@@ -245,7 +245,7 @@ static void test_slices_work(void) {
   gpr_slice_unref(slice);
   grpc_mdstr_unref(str);
 
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 static void test_base64_and_huffman_works(void) {
@@ -264,7 +264,7 @@ static void test_base64_and_huffman_works(void) {
 
   gpr_slice_unref(slice2);
   grpc_mdstr_unref(str);
-  grpc_mdctx_orphan(ctx);
+  grpc_mdctx_unref(ctx);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/transport/stream_op_test.c b/test/core/transport/stream_op_test.c
index e6649ec97c251e60e0600e1660ffa902d262aaba..588522389483ed5e31b082db5f3b60dccd1b58ff 100644
--- a/test/core/transport/stream_op_test.c
+++ b/test/core/transport/stream_op_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/transport/transport_end2end_tests.c b/test/core/transport/transport_end2end_tests.c
index 2cd033bf3ac4070dc2bf6d4b16f425f326224652..6d13bf1f8c9935ca295f4eba3738e7bc88f5629f 100644
--- a/test/core/transport/transport_end2end_tests.c
+++ b/test/core/transport/transport_end2end_tests.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -927,7 +927,7 @@ void grpc_transport_end2end_tests(grpc_transport_test_config *config) {
     test_request_with_flow_ctl_cb(config, interesting_message_lengths[i]);
   }
 
-  grpc_mdctx_orphan(g_metadata_context);
+  grpc_mdctx_unref(g_metadata_context);
 
   gpr_log(GPR_INFO, "tests completed ok");
 }
diff --git a/test/core/transport/transport_end2end_tests.h b/test/core/transport/transport_end2end_tests.h
index f1447e2e98306714a127155194f46717684b2463..3dc2b9b0678b2245a05f11a28a151c86471eeb01 100644
--- a/test/core/transport/transport_end2end_tests.h
+++ b/test/core/transport/transport_end2end_tests.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/grpc_profiler.c b/test/core/util/grpc_profiler.c
index 46bfc1f533c8959edc7c6e6d231b40d528f17d40..35b9361c70c981bba4b03a107c079e76310ed78c 100644
--- a/test/core/util/grpc_profiler.c
+++ b/test/core/util/grpc_profiler.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/grpc_profiler.h b/test/core/util/grpc_profiler.h
index a35472db7351a0c2edf96e4cd790cac79a299eac..a31fcc1db5f8274d287b2ad93a1582fe5fac0e72 100644
--- a/test/core/util/grpc_profiler.h
+++ b/test/core/util/grpc_profiler.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/parse_hexstring.c b/test/core/util/parse_hexstring.c
index 888d03bc68bbe01b9b803916c67879d16b422038..bf5bc84b4836582a4e065d27c1e3eb98787554af 100644
--- a/test/core/util/parse_hexstring.c
+++ b/test/core/util/parse_hexstring.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/parse_hexstring.h b/test/core/util/parse_hexstring.h
index 7477986d609718c321b0ddae657bd7b47c6d144f..3fce0c9f7ac6695871d0552db7b40b1562fc8f28 100644
--- a/test/core/util/parse_hexstring.h
+++ b/test/core/util/parse_hexstring.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/port.h b/test/core/util/port.h
index 94cc1d5bd3696f4c7919e731259fcc9de04a672f..2a12ab985e01bfd506becd5634df3c7c0eb4b4d9 100644
--- a/test/core/util/port.h
+++ b/test/core/util/port.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 067ca0fafa58617be87f6c04e94d8f471200e656..f0fe1a0e7c38a4b63de3385eb6d0d60526ba03e5 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/slice_splitter.c b/test/core/util/slice_splitter.c
index 1682ef4fcde4f6565422d233ff857cf4f05c3ef4..0f05072e50593726eccd83870dfe410d6f91d237 100644
--- a/test/core/util/slice_splitter.c
+++ b/test/core/util/slice_splitter.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/slice_splitter.h b/test/core/util/slice_splitter.h
index 7aed9ea9224fdd1418c4fcc1b1408a41efeaddc3..b67fe737cbd7863b22c5cf50d638c357ae04702d 100644
--- a/test/core/util/slice_splitter.h
+++ b/test/core/util/slice_splitter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 5f3b55da75bc18720065011d4fefc78b3b5b5e38..1c46407311472c9e8908e28b6cbc1a75747fa2b7 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index e24501508f6001a516c58112962fc6a8cb239c27..b97fbfa6138214d3e0bb75c0eaa14cfac5ff1cf2 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/client/channel_arguments_test.cc b/test/cpp/client/channel_arguments_test.cc
index 3cd6add167b49c978f202b99e8028700b69c52cb..01c56cb795f579c1c2b5589f155bd5fed9a67dea 100644
--- a/test/cpp/client/channel_arguments_test.cc
+++ b/test/cpp/client/channel_arguments_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,14 +52,14 @@ TEST_F(ChannelArgumentsTest, SetInt) {
   ChannelArguments channel_args;
   // Empty arguments.
   SetChannelArgs(channel_args, &args);
-  EXPECT_EQ(0, args.num_args);
+  EXPECT_EQ(static_cast<size_t>(0), args.num_args);
 
   grpc::string key("key0");
   channel_args.SetInt(key, 0);
   // Clear key early to make sure channel_args takes a copy
   key = "";
   SetChannelArgs(channel_args, &args);
-  EXPECT_EQ(1, args.num_args);
+  EXPECT_EQ(static_cast<size_t>(1), args.num_args);
   EXPECT_EQ(GRPC_ARG_INTEGER, args.args[0].type);
   EXPECT_STREQ("key0", args.args[0].key);
   EXPECT_EQ(0, args.args[0].value.integer);
@@ -68,7 +68,7 @@ TEST_F(ChannelArgumentsTest, SetInt) {
   channel_args.SetInt(key, 1);
   key = "";
   SetChannelArgs(channel_args, &args);
-  EXPECT_EQ(2, args.num_args);
+  EXPECT_EQ(static_cast<size_t>(2), args.num_args);
   // We do not enforce order on the arguments.
   for (size_t i = 0; i < args.num_args; i++) {
     EXPECT_EQ(GRPC_ARG_INTEGER, args.args[i].type);
@@ -85,7 +85,7 @@ TEST_F(ChannelArgumentsTest, SetString) {
   ChannelArguments channel_args;
   // Empty arguments.
   SetChannelArgs(channel_args, &args);
-  EXPECT_EQ(0, args.num_args);
+  EXPECT_EQ(static_cast<size_t>(0), args.num_args);
 
   grpc::string key("key0");
   grpc::string val("val0");
@@ -94,7 +94,7 @@ TEST_F(ChannelArgumentsTest, SetString) {
   key = "";
   val = "";
   SetChannelArgs(channel_args, &args);
-  EXPECT_EQ(1, args.num_args);
+  EXPECT_EQ(static_cast<size_t>(1), args.num_args);
   EXPECT_EQ(GRPC_ARG_STRING, args.args[0].type);
   EXPECT_STREQ("key0", args.args[0].key);
   EXPECT_STREQ("val0", args.args[0].value.string);
@@ -103,7 +103,7 @@ TEST_F(ChannelArgumentsTest, SetString) {
   val = "val1";
   channel_args.SetString(key, val);
   SetChannelArgs(channel_args, &args);
-  EXPECT_EQ(2, args.num_args);
+  EXPECT_EQ(static_cast<size_t>(2), args.num_args);
   // We do not enforce order on the arguments.
   for (size_t i = 0; i < args.num_args; i++) {
     EXPECT_EQ(GRPC_ARG_STRING, args.args[i].type);
diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc
index 174d2187b0b16f2df2ef3318d161960073843ad8..dc8d76d7eff5a920e4564120b982d79e9dafe21b 100644
--- a/test/cpp/client/credentials_test.cc
+++ b/test/cpp/client/credentials_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..248e054e49a5e1356c0f6fa954cead756b6f70a1
--- /dev/null
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -0,0 +1,556 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <chrono>
+#include <memory>
+
+#include "test/core/util/test_config.h"
+#include "test/cpp/util/echo_duplicate.pb.h"
+#include "test/cpp/util/echo.pb.h"
+#include "src/cpp/util/time.h"
+#include <grpc++/async_unary_call.h>
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+#include "test/core/util/port.h"
+#include <gtest/gtest.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+using grpc::cpp::test::util::EchoRequest;
+using grpc::cpp::test::util::EchoResponse;
+using std::chrono::system_clock;
+
+namespace grpc {
+namespace testing {
+
+namespace {
+
+void* tag(int i) {
+  return (void*)(gpr_intptr)i;
+}
+
+void verify_ok(CompletionQueue* cq, int i, bool expect_ok) {
+  bool ok;
+  void* got_tag;
+  EXPECT_TRUE(cq->Next(&got_tag, &ok));
+  EXPECT_EQ(expect_ok, ok);
+  EXPECT_EQ(tag(i), got_tag);
+}
+
+class AsyncEnd2endTest : public ::testing::Test {
+ protected:
+  AsyncEnd2endTest() : service_(&srv_cq_) {}
+
+  void SetUp() override {
+    int port = grpc_pick_unused_port_or_die();
+    server_address_ << "localhost:" << port;
+    // Setup server
+    ServerBuilder builder;
+    builder.AddPort(server_address_.str());
+    builder.RegisterAsyncService(&service_);
+    server_ = builder.BuildAndStart();
+  }
+
+  void TearDown() override {
+    server_->Shutdown();
+    void* ignored_tag;
+    bool ignored_ok;
+    cli_cq_.Shutdown();
+    srv_cq_.Shutdown();
+    while (cli_cq_.Next(&ignored_tag, &ignored_ok))
+      ;
+    while (srv_cq_.Next(&ignored_tag, &ignored_ok))
+      ;
+  }
+
+  void ResetStub() {
+    std::shared_ptr<ChannelInterface> channel =
+        CreateChannel(server_address_.str(), ChannelArguments());
+    stub_.reset(grpc::cpp::test::util::TestService::NewStub(channel));
+  }
+
+  void server_ok(int i) {
+    verify_ok(&srv_cq_, i, true);
+  }
+  void client_ok(int i) {
+    verify_ok(&cli_cq_, i , true);
+  }
+  void server_fail(int i) {
+    verify_ok(&srv_cq_, i, false);
+  }
+  void client_fail(int i) {
+    verify_ok(&cli_cq_, i, false);
+  }
+
+  void SendRpc(int num_rpcs) {
+    for (int i = 0; i < num_rpcs; i++) {
+      EchoRequest send_request;
+      EchoRequest recv_request;
+      EchoResponse send_response;
+      EchoResponse recv_response;
+      Status recv_status;
+
+      ClientContext cli_ctx;
+      ServerContext srv_ctx;
+      grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+      send_request.set_message("Hello");
+      std::unique_ptr<ClientAsyncResponseReader<EchoResponse> >
+          response_reader(stub_->Echo(
+              &cli_ctx, send_request, &cli_cq_, tag(1)));
+
+      service_.RequestEcho(
+          &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+
+      server_ok(2);
+      EXPECT_EQ(send_request.message(), recv_request.message());
+      client_ok(1);
+
+      send_response.set_message(recv_request.message());
+      response_writer.Finish(send_response, Status::OK, tag(3));
+      server_ok(3);
+
+      response_reader->Finish(&recv_response, &recv_status, tag(4));
+      client_ok(4);
+
+      EXPECT_EQ(send_response.message(), recv_response.message());
+      EXPECT_TRUE(recv_status.IsOk());
+    }
+  }
+
+  CompletionQueue cli_cq_;
+  CompletionQueue srv_cq_;
+  std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
+  std::unique_ptr<Server> server_;
+  grpc::cpp::test::util::TestService::AsyncService service_;
+  std::ostringstream server_address_;
+};
+
+TEST_F(AsyncEnd2endTest, SimpleRpc) {
+  ResetStub();
+  SendRpc(1);
+}
+
+TEST_F(AsyncEnd2endTest, SequentialRpcs) {
+  ResetStub();
+  SendRpc(10);
+}
+
+// Two pings and a final pong.
+TEST_F(AsyncEnd2endTest, SimpleClientStreaming) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::unique_ptr<ClientAsyncWriter<EchoRequest> > cli_stream(
+      stub_->RequestStream(&cli_ctx, &recv_response, &cli_cq_, tag(1)));
+
+  service_.RequestRequestStream(
+      &srv_ctx, &srv_stream, &srv_cq_, tag(2));
+
+  server_ok(2);
+  client_ok(1);
+
+  cli_stream->Write(send_request, tag(3));
+  client_ok(3);
+
+  srv_stream.Read(&recv_request, tag(4));
+  server_ok(4);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  cli_stream->Write(send_request, tag(5));
+  client_ok(5);
+
+  srv_stream.Read(&recv_request, tag(6));
+  server_ok(6);
+
+  EXPECT_EQ(send_request.message(), recv_request.message());
+  cli_stream->WritesDone(tag(7));
+  client_ok(7);
+
+  srv_stream.Read(&recv_request, tag(8));
+  server_fail(8);
+
+  send_response.set_message(recv_request.message());
+  srv_stream.Finish(send_response, Status::OK, tag(9));
+  server_ok(9);
+
+  cli_stream->Finish(&recv_status, tag(10));
+  client_ok(10);
+
+  EXPECT_EQ(send_response.message(), recv_response.message());
+  EXPECT_TRUE(recv_status.IsOk());
+}
+
+// One ping, two pongs.
+TEST_F(AsyncEnd2endTest, SimpleServerStreaming) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::unique_ptr<ClientAsyncReader<EchoResponse> > cli_stream(
+      stub_->ResponseStream(&cli_ctx, send_request, &cli_cq_, tag(1)));
+
+  service_.RequestResponseStream(
+      &srv_ctx, &recv_request, &srv_stream, &srv_cq_, tag(2));
+
+  server_ok(2);
+  client_ok(1);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.Write(send_response, tag(3));
+  server_ok(3);
+
+  cli_stream->Read(&recv_response, tag(4));
+  client_ok(4);
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  srv_stream.Write(send_response, tag(5));
+  server_ok(5);
+
+  cli_stream->Read(&recv_response, tag(6));
+  client_ok(6);
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  srv_stream.Finish(Status::OK, tag(7));
+  server_ok(7);
+
+  cli_stream->Read(&recv_response, tag(8));
+  client_fail(8);
+
+  cli_stream->Finish(&recv_status, tag(9));
+  client_ok(9);
+
+  EXPECT_TRUE(recv_status.IsOk());
+}
+
+// One ping, one pong.
+TEST_F(AsyncEnd2endTest, SimpleBidiStreaming) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse> >
+      cli_stream(stub_->BidiStream(&cli_ctx, &cli_cq_, tag(1)));
+
+  service_.RequestBidiStream(
+      &srv_ctx, &srv_stream, &srv_cq_, tag(2));
+
+  server_ok(2);
+  client_ok(1);
+
+  cli_stream->Write(send_request, tag(3));
+  client_ok(3);
+
+  srv_stream.Read(&recv_request, tag(4));
+  server_ok(4);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+
+  send_response.set_message(recv_request.message());
+  srv_stream.Write(send_response, tag(5));
+  server_ok(5);
+
+  cli_stream->Read(&recv_response, tag(6));
+  client_ok(6);
+  EXPECT_EQ(send_response.message(), recv_response.message());
+
+  cli_stream->WritesDone(tag(7));
+  client_ok(7);
+
+  srv_stream.Read(&recv_request, tag(8));
+  server_fail(8);
+
+  srv_stream.Finish(Status::OK, tag(9));
+  server_ok(9);
+
+  cli_stream->Finish(&recv_status, tag(10));
+  client_ok(10);
+
+  EXPECT_TRUE(recv_status.IsOk());
+}
+
+// Metadata tests
+TEST_F(AsyncEnd2endTest, ClientInitialMetadataRpc) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::pair<grpc::string, grpc::string> meta1("key1", "val1");
+  std::pair<grpc::string, grpc::string> meta2("key2", "val2");
+  cli_ctx.AddMetadata(meta1.first, meta1.second);
+  cli_ctx.AddMetadata(meta2.first, meta2.second);
+
+  std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+
+  service_.RequestEcho(
+      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  server_ok(2);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+  auto client_initial_metadata = srv_ctx.client_metadata();
+  EXPECT_EQ(meta1.second, client_initial_metadata.find(meta1.first)->second);
+  EXPECT_EQ(meta2.second, client_initial_metadata.find(meta2.first)->second);
+  EXPECT_EQ(static_cast<size_t>(2), client_initial_metadata.size());
+  client_ok(1);
+
+  send_response.set_message(recv_request.message());
+  response_writer.Finish(send_response, Status::OK, tag(3));
+
+  server_ok(3);
+
+  response_reader->Finish(&recv_response, &recv_status, tag(4));
+  client_ok(4);
+
+  EXPECT_EQ(send_response.message(), recv_response.message());
+  EXPECT_TRUE(recv_status.IsOk());
+}
+
+TEST_F(AsyncEnd2endTest, ServerInitialMetadataRpc) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::pair<grpc::string, grpc::string> meta1("key1", "val1");
+  std::pair<grpc::string, grpc::string> meta2("key2", "val2");
+
+  std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+
+  service_.RequestEcho(
+      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  server_ok(2);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+  srv_ctx.AddInitialMetadata(meta1.first, meta1.second);
+  srv_ctx.AddInitialMetadata(meta2.first, meta2.second);
+  client_ok(1);
+  response_writer.SendInitialMetadata(tag(3));
+  server_ok(3);
+
+  response_reader->ReadInitialMetadata(tag(4));
+  client_ok(4);
+  auto server_initial_metadata = cli_ctx.GetServerInitialMetadata();
+  EXPECT_EQ(meta1.second, server_initial_metadata.find(meta1.first)->second);
+  EXPECT_EQ(meta2.second, server_initial_metadata.find(meta2.first)->second);
+  EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size());
+
+  send_response.set_message(recv_request.message());
+  response_writer.Finish(send_response, Status::OK, tag(5));
+  server_ok(5);
+
+  response_reader->Finish(&recv_response, &recv_status, tag(6));
+  client_ok(6);
+
+  EXPECT_EQ(send_response.message(), recv_response.message());
+  EXPECT_TRUE(recv_status.IsOk());
+}
+
+TEST_F(AsyncEnd2endTest, ServerTrailingMetadataRpc) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::pair<grpc::string, grpc::string> meta1("key1", "val1");
+  std::pair<grpc::string, grpc::string> meta2("key2", "val2");
+
+  std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+
+  service_.RequestEcho(
+      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  server_ok(2);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+  response_writer.SendInitialMetadata(tag(3));
+  server_ok(3);
+  client_ok(1);
+
+  send_response.set_message(recv_request.message());
+  srv_ctx.AddTrailingMetadata(meta1.first, meta1.second);
+  srv_ctx.AddTrailingMetadata(meta2.first, meta2.second);
+  response_writer.Finish(send_response, Status::OK, tag(4));
+
+  server_ok(4);
+
+
+  response_reader->Finish(&recv_response, &recv_status, tag(5));
+  client_ok(5);
+  EXPECT_EQ(send_response.message(), recv_response.message());
+  EXPECT_TRUE(recv_status.IsOk());
+  auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata();
+  EXPECT_EQ(meta1.second, server_trailing_metadata.find(meta1.first)->second);
+  EXPECT_EQ(meta2.second, server_trailing_metadata.find(meta2.first)->second);
+  EXPECT_EQ(static_cast<size_t>(2), server_trailing_metadata.size());
+}
+
+TEST_F(AsyncEnd2endTest, MetadataRpc) {
+  ResetStub();
+
+  EchoRequest send_request;
+  EchoRequest recv_request;
+  EchoResponse send_response;
+  EchoResponse recv_response;
+  Status recv_status;
+
+  ClientContext cli_ctx;
+  ServerContext srv_ctx;
+  grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+  send_request.set_message("Hello");
+  std::pair<grpc::string, grpc::string> meta1("key1", "val1");
+  std::pair<grpc::string, grpc::string> meta2(
+      "key2-bin", {"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13});
+  std::pair<grpc::string, grpc::string> meta3("key3", "val3");
+  std::pair<grpc::string, grpc::string> meta6("key4-bin",
+      {"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", 14});
+  std::pair<grpc::string, grpc::string> meta5("key5", "val5");
+  std::pair<grpc::string, grpc::string> meta4("key6-bin",
+      {"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15});
+
+  cli_ctx.AddMetadata(meta1.first, meta1.second);
+  cli_ctx.AddMetadata(meta2.first, meta2.second);
+
+  std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+
+  service_.RequestEcho(
+      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  server_ok(2);
+  EXPECT_EQ(send_request.message(), recv_request.message());
+  auto client_initial_metadata = srv_ctx.client_metadata();
+  EXPECT_EQ(meta1.second, client_initial_metadata.find(meta1.first)->second);
+  EXPECT_EQ(meta2.second, client_initial_metadata.find(meta2.first)->second);
+  EXPECT_EQ(static_cast<size_t>(2), client_initial_metadata.size());
+  client_ok(1);
+
+  srv_ctx.AddInitialMetadata(meta3.first, meta3.second);
+  srv_ctx.AddInitialMetadata(meta4.first, meta4.second);
+  response_writer.SendInitialMetadata(tag(3));
+  server_ok(3);
+  response_reader->ReadInitialMetadata(tag(4));
+  client_ok(4);
+  auto server_initial_metadata = cli_ctx.GetServerInitialMetadata();
+  EXPECT_EQ(meta3.second, server_initial_metadata.find(meta3.first)->second);
+  EXPECT_EQ(meta4.second, server_initial_metadata.find(meta4.first)->second);
+  EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size());
+
+  send_response.set_message(recv_request.message());
+  srv_ctx.AddTrailingMetadata(meta5.first, meta5.second);
+  srv_ctx.AddTrailingMetadata(meta6.first, meta6.second);
+  response_writer.Finish(send_response, Status::OK, tag(5));
+
+  server_ok(5);
+
+
+  response_reader->Finish(&recv_response, &recv_status, tag(6));
+  client_ok(6);
+  EXPECT_EQ(send_response.message(), recv_response.message());
+  EXPECT_TRUE(recv_status.IsOk());
+  auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata();
+  EXPECT_EQ(meta5.second, server_trailing_metadata.find(meta5.first)->second);
+  EXPECT_EQ(meta6.second, server_trailing_metadata.find(meta6.first)->second);
+  EXPECT_EQ(static_cast<size_t>(2), server_trailing_metadata.size());
+}
+}  // namespace
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  grpc_init();
+  ::testing::InitGoogleTest(&argc, argv);
+  int result = RUN_ALL_TESTS();
+  grpc_shutdown();
+  google::protobuf::ShutdownProtobufLibrary();
+  return result;
+}
diff --git a/test/cpp/end2end/async_test_server.cc b/test/cpp/end2end/async_test_server.cc
deleted file mode 100644
index f18b6c00bceff36795aba82693d2fa01c69a6c13..0000000000000000000000000000000000000000
--- a/test/cpp/end2end/async_test_server.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *
- * Copyright 2014, 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/end2end/async_test_server.h"
-
-#include <chrono>
-
-#include <grpc/support/log.h>
-#include "src/cpp/proto/proto_utils.h"
-#include "test/cpp/util/echo.pb.h"
-#include <grpc++/async_server.h>
-#include <grpc++/async_server_context.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/status.h>
-#include <gtest/gtest.h>
-
-using grpc::cpp::test::util::EchoRequest;
-using grpc::cpp::test::util::EchoResponse;
-
-using std::chrono::duration_cast;
-using std::chrono::microseconds;
-using std::chrono::seconds;
-using std::chrono::system_clock;
-
-namespace grpc {
-namespace testing {
-
-AsyncTestServer::AsyncTestServer() : server_(&cq_), cq_drained_(false) {}
-
-AsyncTestServer::~AsyncTestServer() {}
-
-void AsyncTestServer::AddPort(const grpc::string& addr) {
-  server_.AddPort(addr);
-}
-
-void AsyncTestServer::Start() { server_.Start(); }
-
-// Return true if deadline actual is within 0.5s from expected.
-bool DeadlineMatched(const system_clock::time_point& actual,
-                     const system_clock::time_point& expected) {
-  microseconds diff_usecs = duration_cast<microseconds>(expected - actual);
-  gpr_log(GPR_INFO, "diff_usecs= %d", diff_usecs.count());
-  return diff_usecs.count() < 500000 && diff_usecs.count() > -500000;
-}
-
-void AsyncTestServer::RequestOneRpc() { server_.RequestOneRpc(); }
-
-void AsyncTestServer::MainLoop() {
-  EchoRequest request;
-  EchoResponse response;
-  void* tag = nullptr;
-
-  RequestOneRpc();
-
-  while (true) {
-    CompletionQueue::CompletionType t = cq_.Next(&tag);
-    AsyncServerContext* server_context = static_cast<AsyncServerContext*>(tag);
-    switch (t) {
-      case CompletionQueue::SERVER_RPC_NEW:
-        gpr_log(GPR_INFO, "SERVER_RPC_NEW %p", server_context);
-        if (server_context) {
-          EXPECT_EQ(server_context->method(), "/foo");
-          // TODO(ctiller): verify deadline
-          server_context->Accept(cq_.cq());
-          // Handle only one rpc at a time.
-          RequestOneRpc();
-          server_context->StartRead(&request);
-        }
-        break;
-      case CompletionQueue::RPC_END:
-        gpr_log(GPR_INFO, "RPC_END %p", server_context);
-        delete server_context;
-        break;
-      case CompletionQueue::SERVER_READ_OK:
-        gpr_log(GPR_INFO, "SERVER_READ_OK %p", server_context);
-        response.set_message(request.message());
-        server_context->StartWrite(response, 0);
-        break;
-      case CompletionQueue::SERVER_READ_ERROR:
-        gpr_log(GPR_INFO, "SERVER_READ_ERROR %p", server_context);
-        server_context->StartWriteStatus(Status::OK);
-        break;
-      case CompletionQueue::HALFCLOSE_OK:
-        gpr_log(GPR_INFO, "HALFCLOSE_OK %p", server_context);
-        // Do nothing, just wait for RPC_END.
-        break;
-      case CompletionQueue::SERVER_WRITE_OK:
-        gpr_log(GPR_INFO, "SERVER_WRITE_OK %p", server_context);
-        server_context->StartRead(&request);
-        break;
-      case CompletionQueue::SERVER_WRITE_ERROR:
-        EXPECT_TRUE(0);
-        break;
-      case CompletionQueue::QUEUE_CLOSED: {
-        gpr_log(GPR_INFO, "QUEUE_CLOSED");
-        HandleQueueClosed();
-        return;
-      }
-      default:
-        EXPECT_TRUE(0);
-        break;
-    }
-  }
-}
-
-void AsyncTestServer::HandleQueueClosed() {
-  std::unique_lock<std::mutex> lock(cq_drained_mu_);
-  cq_drained_ = true;
-  cq_drained_cv_.notify_all();
-}
-
-void AsyncTestServer::Shutdown() {
-  // The server need to be shut down before cq_ as grpc_server flushes all
-  // pending requested calls to the completion queue at shutdown.
-  server_.Shutdown();
-  cq_.Shutdown();
-  std::unique_lock<std::mutex> lock(cq_drained_mu_);
-  while (!cq_drained_) {
-    cq_drained_cv_.wait(lock);
-  }
-}
-
-}  // namespace testing
-}  // namespace grpc
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 4dea77ea8118d94a224e0106d822fdef54b59c20..d4ca3ef49e40208939936d8d6632b4d723ffc937 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
 #include "test/cpp/util/echo_duplicate.pb.h"
 #include "test/cpp/util/echo.pb.h"
 #include "src/cpp/util/time.h"
+#include "src/cpp/server/thread_pool.h"
 #include <grpc++/channel_arguments.h>
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
@@ -76,6 +77,7 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
     response->mutable_param()->set_request_deadline(deadline.tv_sec);
   }
 }
+
 }  // namespace
 
 class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
@@ -141,14 +143,17 @@ class TestServiceImplDupPkg
 
 class End2endTest : public ::testing::Test {
  protected:
+  End2endTest() : thread_pool_(2) {}
+
   void SetUp() override {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     // Setup server
     ServerBuilder builder;
     builder.AddPort(server_address_.str());
-    builder.RegisterService(service_.service());
-    builder.RegisterService(dup_pkg_service_.service());
+    builder.RegisterService(&service_);
+    builder.RegisterService(&dup_pkg_service_);
+    builder.SetThreadPool(&thread_pool_);
     server_ = builder.BuildAndStart();
   }
 
@@ -165,6 +170,7 @@ class End2endTest : public ::testing::Test {
   std::ostringstream server_address_;
   TestServiceImpl service_;
   TestServiceImplDupPkg dup_pkg_service_;
+  ThreadPool thread_pool_;
 };
 
 static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
@@ -290,7 +296,7 @@ TEST_F(End2endTest, RequestStreamOneRequest) {
   request.set_message("hello");
   EXPECT_TRUE(stream->Write(request));
   stream->WritesDone();
-  Status s = stream->Wait();
+  Status s = stream->Finish();
   EXPECT_EQ(response.message(), request.message());
   EXPECT_TRUE(s.IsOk());
 
@@ -308,7 +314,7 @@ TEST_F(End2endTest, RequestStreamTwoRequests) {
   EXPECT_TRUE(stream->Write(request));
   EXPECT_TRUE(stream->Write(request));
   stream->WritesDone();
-  Status s = stream->Wait();
+  Status s = stream->Finish();
   EXPECT_EQ(response.message(), "hellohello");
   EXPECT_TRUE(s.IsOk());
 
@@ -323,7 +329,7 @@ TEST_F(End2endTest, ResponseStream) {
   request.set_message("hello");
 
   ClientReader<EchoResponse>* stream =
-      stub_->ResponseStream(&context, &request);
+      stub_->ResponseStream(&context, request);
   EXPECT_TRUE(stream->Read(&response));
   EXPECT_EQ(response.message(), request.message() + "0");
   EXPECT_TRUE(stream->Read(&response));
@@ -332,7 +338,7 @@ TEST_F(End2endTest, ResponseStream) {
   EXPECT_EQ(response.message(), request.message() + "2");
   EXPECT_FALSE(stream->Read(&response));
 
-  Status s = stream->Wait();
+  Status s = stream->Finish();
   EXPECT_TRUE(s.IsOk());
 
   delete stream;
@@ -366,7 +372,7 @@ TEST_F(End2endTest, BidiStream) {
   stream->WritesDone();
   EXPECT_FALSE(stream->Read(&response));
 
-  Status s = stream->Wait();
+  Status s = stream->Finish();
   EXPECT_TRUE(s.IsOk());
 
   delete stream;
@@ -422,7 +428,7 @@ TEST_F(End2endTest, BadCredentials) {
   ClientContext context2;
   ClientReaderWriter<EchoRequest, EchoResponse>* stream =
       stub->BidiStream(&context2);
-  s = stream->Wait();
+  s = stream->Finish();
   EXPECT_FALSE(s.IsOk());
   EXPECT_EQ(StatusCode::UNKNOWN, s.code());
   EXPECT_EQ("Rpc sent on a lame channel.", s.details());
@@ -439,5 +445,6 @@ int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
   int result = RUN_ALL_TESTS();
   grpc_shutdown();
+  google::protobuf::ShutdownProtobufLibrary();
   return result;
 }
diff --git a/test/cpp/end2end/sync_client_async_server_test.cc b/test/cpp/end2end/sync_client_async_server_test.cc
deleted file mode 100644
index 9955eb306f051c58b42f2f6c42297701f7f48852..0000000000000000000000000000000000000000
--- a/test/cpp/end2end/sync_client_async_server_test.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- *
- * Copyright 2014, 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 <chrono>
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include <grpc/grpc.h>
-#include <grpc/support/thd.h>
-#include "test/cpp/util/echo.pb.h"
-#include <grpc++/channel_arguments.h>
-#include <grpc++/channel_interface.h>
-#include <grpc++/client_context.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/impl/internal_stub.h>
-#include <grpc++/impl/rpc_method.h>
-#include <grpc++/status.h>
-#include <grpc++/stream.h>
-#include "test/cpp/end2end/async_test_server.h"
-#include "test/core/util/port.h"
-#include <gtest/gtest.h>
-
-using grpc::cpp::test::util::EchoRequest;
-using grpc::cpp::test::util::EchoResponse;
-
-using std::chrono::duration_cast;
-using std::chrono::microseconds;
-using std::chrono::seconds;
-using std::chrono::system_clock;
-
-using grpc::testing::AsyncTestServer;
-
-namespace grpc {
-namespace {
-
-void ServerLoop(void* s) {
-  AsyncTestServer* server = static_cast<AsyncTestServer*>(s);
-  server->MainLoop();
-}
-
-class End2endTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    int port = grpc_pick_unused_port_or_die();
-    // TODO(yangg) protobuf has a StringPrintf, maybe use that
-    std::ostringstream oss;
-    oss << "[::]:" << port;
-    // Setup server
-    server_.reset(new AsyncTestServer());
-    server_->AddPort(oss.str());
-    server_->Start();
-
-    RunServerThread();
-
-    // Setup client
-    oss.str("");
-    oss << "127.0.0.1:" << port;
-    std::shared_ptr<ChannelInterface> channel =
-        CreateChannel(oss.str(), ChannelArguments());
-    stub_.set_channel(channel);
-  }
-
-  void RunServerThread() {
-    gpr_thd_id id;
-    EXPECT_TRUE(gpr_thd_new(&id, ServerLoop, server_.get(), NULL));
-  }
-
-  void TearDown() override { server_->Shutdown(); }
-
-  std::unique_ptr<AsyncTestServer> server_;
-  InternalStub stub_;
-};
-
-TEST_F(End2endTest, NoOpTest) { EXPECT_TRUE(stub_.channel() != nullptr); }
-
-TEST_F(End2endTest, SimpleRpc) {
-  EchoRequest request;
-  request.set_message("hello");
-  EchoResponse result;
-  ClientContext context;
-  RpcMethod method("/foo");
-  std::chrono::system_clock::time_point deadline =
-      std::chrono::system_clock::now() + std::chrono::seconds(10);
-  context.set_absolute_deadline(deadline);
-  Status s =
-      stub_.channel()->StartBlockingRpc(method, &context, request, &result);
-  EXPECT_EQ(result.message(), request.message());
-  EXPECT_TRUE(s.IsOk());
-}
-
-TEST_F(End2endTest, KSequentialSimpleRpcs) {
-  int k = 3;
-  for (int i = 0; i < k; i++) {
-    EchoRequest request;
-    request.set_message("hello");
-    EchoResponse result;
-    ClientContext context;
-    RpcMethod method("/foo");
-    std::chrono::system_clock::time_point deadline =
-        std::chrono::system_clock::now() + std::chrono::seconds(10);
-    context.set_absolute_deadline(deadline);
-    Status s =
-        stub_.channel()->StartBlockingRpc(method, &context, request, &result);
-    EXPECT_EQ(result.message(), request.message());
-    EXPECT_TRUE(s.IsOk());
-  }
-}
-
-TEST_F(End2endTest, OnePingpongBidiStream) {
-  EchoRequest request;
-  request.set_message("hello");
-  EchoResponse result;
-  ClientContext context;
-  RpcMethod method("/foo", RpcMethod::RpcType::BIDI_STREAMING);
-  std::chrono::system_clock::time_point deadline =
-      std::chrono::system_clock::now() + std::chrono::seconds(10);
-  context.set_absolute_deadline(deadline);
-  StreamContextInterface* stream_interface =
-      stub_.channel()->CreateStream(method, &context, nullptr, nullptr);
-  std::unique_ptr<ClientReaderWriter<EchoRequest, EchoResponse>> stream(
-      new ClientReaderWriter<EchoRequest, EchoResponse>(stream_interface));
-  EXPECT_TRUE(stream->Write(request));
-  EXPECT_TRUE(stream->Read(&result));
-  stream->WritesDone();
-  EXPECT_FALSE(stream->Read(&result));
-  Status s = stream->Wait();
-  EXPECT_EQ(result.message(), request.message());
-  EXPECT_TRUE(s.IsOk());
-}
-
-TEST_F(End2endTest, TwoPingpongBidiStream) {
-  EchoRequest request;
-  request.set_message("hello");
-  EchoResponse result;
-  ClientContext context;
-  RpcMethod method("/foo", RpcMethod::RpcType::BIDI_STREAMING);
-  std::chrono::system_clock::time_point deadline =
-      std::chrono::system_clock::now() + std::chrono::seconds(10);
-  context.set_absolute_deadline(deadline);
-  StreamContextInterface* stream_interface =
-      stub_.channel()->CreateStream(method, &context, nullptr, nullptr);
-  std::unique_ptr<ClientReaderWriter<EchoRequest, EchoResponse>> stream(
-      new ClientReaderWriter<EchoRequest, EchoResponse>(stream_interface));
-  EXPECT_TRUE(stream->Write(request));
-  EXPECT_TRUE(stream->Read(&result));
-  EXPECT_EQ(result.message(), request.message());
-  EXPECT_TRUE(stream->Write(request));
-  EXPECT_TRUE(stream->Read(&result));
-  EXPECT_EQ(result.message(), request.message());
-  stream->WritesDone();
-  EXPECT_FALSE(stream->Read(&result));
-  Status s = stream->Wait();
-  EXPECT_TRUE(s.IsOk());
-}
-
-TEST_F(End2endTest, OnePingpongClientStream) {
-  EchoRequest request;
-  request.set_message("hello");
-  EchoResponse result;
-  ClientContext context;
-  RpcMethod method("/foo", RpcMethod::RpcType::CLIENT_STREAMING);
-  std::chrono::system_clock::time_point deadline =
-      std::chrono::system_clock::now() + std::chrono::seconds(10);
-  context.set_absolute_deadline(deadline);
-  StreamContextInterface* stream_interface =
-      stub_.channel()->CreateStream(method, &context, nullptr, &result);
-  std::unique_ptr<ClientWriter<EchoRequest>> stream(
-      new ClientWriter<EchoRequest>(stream_interface));
-  EXPECT_TRUE(stream->Write(request));
-  stream->WritesDone();
-  Status s = stream->Wait();
-  EXPECT_EQ(result.message(), request.message());
-  EXPECT_TRUE(s.IsOk());
-}
-
-TEST_F(End2endTest, OnePingpongServerStream) {
-  EchoRequest request;
-  request.set_message("hello");
-  EchoResponse result;
-  ClientContext context;
-  RpcMethod method("/foo", RpcMethod::RpcType::SERVER_STREAMING);
-  std::chrono::system_clock::time_point deadline =
-      std::chrono::system_clock::now() + std::chrono::seconds(10);
-  context.set_absolute_deadline(deadline);
-  StreamContextInterface* stream_interface =
-      stub_.channel()->CreateStream(method, &context, &request, nullptr);
-  std::unique_ptr<ClientReader<EchoResponse>> stream(
-      new ClientReader<EchoResponse>(stream_interface));
-  EXPECT_TRUE(stream->Read(&result));
-  EXPECT_FALSE(stream->Read(nullptr));
-  Status s = stream->Wait();
-  EXPECT_EQ(result.message(), request.message());
-  EXPECT_TRUE(s.IsOk());
-}
-
-}  // namespace
-}  // namespace grpc
-
-int main(int argc, char** argv) {
-  grpc_init();
-  ::testing::InitGoogleTest(&argc, argv);
-  int result = RUN_ALL_TESTS();
-  grpc_shutdown();
-  return result;
-}
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 0fa76f0e023261ce859c3b96428ddeda1175946a..78f2063c45baa647b3cde2fdbd8b5b6af68b19e8 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@
 
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
-#include <google/gflags.h>
+#include <gflags/gflags.h>
 #include <grpc++/channel_arguments.h>
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
@@ -92,6 +92,13 @@ using grpc::testing::StreamingOutputCallRequest;
 using grpc::testing::StreamingOutputCallResponse;
 using grpc::testing::TestService;
 
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google { }
+namespace gflags { }
+using namespace google;
+using namespace gflags;
+
 namespace {
 // The same value is defined by the Java client.
 const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
@@ -248,7 +255,7 @@ void DoRequestStreaming() {
     aggregated_payload_size += request_stream_sizes[i];
   }
   stream->WritesDone();
-  grpc::Status s = stream->Wait();
+  grpc::Status s = stream->Finish();
 
   GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
   GPR_ASSERT(s.IsOk());
@@ -269,7 +276,7 @@ void DoResponseStreaming() {
   }
   StreamingOutputCallResponse response;
   std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
-      stub->StreamingOutputCall(&context, &request));
+      stub->StreamingOutputCall(&context, request));
 
   unsigned int i = 0;
   while (stream->Read(&response)) {
@@ -278,7 +285,7 @@ void DoResponseStreaming() {
     ++i;
   }
   GPR_ASSERT(response_stream_sizes.size() == i);
-  grpc::Status s = stream->Wait();
+  grpc::Status s = stream->Finish();
 
   GPR_ASSERT(s.IsOk());
   gpr_log(GPR_INFO, "Response streaming done.");
@@ -299,7 +306,7 @@ void DoResponseStreamingWithSlowConsumer() {
   }
   StreamingOutputCallResponse response;
   std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
-      stub->StreamingOutputCall(&context, &request));
+      stub->StreamingOutputCall(&context, request));
 
   int i = 0;
   while (stream->Read(&response)) {
@@ -311,7 +318,7 @@ void DoResponseStreamingWithSlowConsumer() {
     ++i;
   }
   GPR_ASSERT(kNumResponseMessages == i);
-  grpc::Status s = stream->Wait();
+  grpc::Status s = stream->Finish();
 
   GPR_ASSERT(s.IsOk());
   gpr_log(GPR_INFO, "Response streaming done.");
@@ -345,7 +352,7 @@ void DoHalfDuplex() {
     ++i;
   }
   GPR_ASSERT(response_stream_sizes.size() == i);
-  grpc::Status s = stream->Wait();
+  grpc::Status s = stream->Finish();
   GPR_ASSERT(s.IsOk());
   gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
 }
@@ -378,7 +385,7 @@ void DoPingPong() {
 
   stream->WritesDone();
   GPR_ASSERT(!stream->Read(&response));
-  grpc::Status s = stream->Wait();
+  grpc::Status s = stream->Finish();
   GPR_ASSERT(s.IsOk());
   gpr_log(GPR_INFO, "Ping pong streaming done.");
 }
@@ -386,7 +393,7 @@ void DoPingPong() {
 int main(int argc, char** argv) {
   grpc_init();
 
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  ParseCommandLineFlags(&argc, &argv, true);
 
   if (FLAGS_test_case == "empty_unary") {
     DoEmpty();
diff --git a/test/cpp/interop/empty.proto b/test/cpp/interop/empty.proto
index 98fc3a39070507d4c7d430afec0d382e63e90345..f66a108c19b7b46f4afe2b55d09bfc4f03a359a9 100644
--- a/test/cpp/interop/empty.proto
+++ b/test/cpp/interop/empty.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/interop/messages.proto b/test/cpp/interop/messages.proto
index e3814da406e705b30a0a855ab49b6a382971c817..65a81404652520a211940cd4af81968620ea8dc2 100644
--- a/test/cpp/interop/messages.proto
+++ b/test/cpp/interop/messages.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index 8a6be57929458e97c4421cb0325f259f6707e50d..4869d4df529891aa48c23115025ae79c1d92e22f 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
 #include <sstream>
 #include <thread>
 
-#include <google/gflags.h>
+#include <gflags/gflags.h>
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include "test/core/end2end/data/ssl_test_data.h"
@@ -73,6 +73,13 @@ using grpc::testing::StreamingOutputCallResponse;
 using grpc::testing::TestService;
 using grpc::Status;
 
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google { }
+namespace gflags { }
+using namespace google;
+using namespace gflags;
+
 bool SetPayload(PayloadType type, int size, Payload* payload) {
   PayloadType response_type = type;
   // TODO(yangg): Support UNCOMPRESSABLE payload.
@@ -200,7 +207,7 @@ void RunServer() {
 
   ServerBuilder builder;
   builder.AddPort(server_address.str());
-  builder.RegisterService(service.service());
+  builder.RegisterService(&service);
   if (FLAGS_enable_ssl) {
     SslServerCredentialsOptions ssl_opts = {
         "", {{test_server1_key, test_server1_cert}}};
@@ -217,7 +224,7 @@ void RunServer() {
 
 int main(int argc, char** argv) {
   grpc_init();
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  ParseCommandLineFlags(&argc, &argv, true);
 
   GPR_ASSERT(FLAGS_port != 0);
   RunServer();
diff --git a/test/cpp/interop/test.proto b/test/cpp/interop/test.proto
index 32b8c63195ff7343fd4ff674db9945b45a0a16cb..b55780e5cdef6e272e3adaf50f23a1e8450f6ca8 100644
--- a/test/cpp/interop/test.proto
+++ b/test/cpp/interop/test.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/qps/client.cc b/test/cpp/qps/client.cc
index d2c83aad3df75d3c30a441c16e3f50c5e30c9e23..666f25054ab608ec521f7b6a99c074e7fa757641 100644
--- a/test/cpp/qps/client.cc
+++ b/test/cpp/qps/client.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/histogram.h>
 #include <grpc/support/log.h>
-#include <google/gflags.h>
+#include <gflags/gflags.h>
 #include <grpc++/client_context.h>
 #include <grpc++/status.h>
 #include "test/core/util/grpc_profiler.h"
@@ -80,6 +80,13 @@ using grpc::testing::SimpleResponse;
 using grpc::testing::StatsRequest;
 using grpc::testing::TestService;
 
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google { }
+namespace gflags { }
+using namespace google;
+using namespace gflags;
+
 static double now() {
   gpr_timespec tv = gpr_now();
   return 1e9 * tv.tv_sec + tv.tv_nsec;
@@ -221,7 +228,7 @@ void RunTest(const int client_threads, const int client_channels,
 
 int main(int argc, char **argv) {
   grpc_init();
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  ParseCommandLineFlags(&argc, &argv, true);
 
   GPR_ASSERT(FLAGS_server_port);
 
diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto
index ffe7ecae56aa5e48cbd167461b63ea90e97a6ae3..68ec6149f59669954b03bbe6425c6de271604a1c 100644
--- a/test/cpp/qps/qpstest.proto
+++ b/test/cpp/qps/qpstest.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc
index 3a432b6fbbbb24add9ecd3518b05b9a6c5486292..8e136349a15e490ede14dc1a913258d403140372 100644
--- a/test/cpp/qps/server.cc
+++ b/test/cpp/qps/server.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
 #include <sys/signal.h>
 #include <thread>
 
-#include <google/gflags.h>
+#include <gflags/gflags.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc++/config.h>
@@ -68,6 +68,13 @@ using grpc::testing::StatsRequest;
 using grpc::testing::TestService;
 using grpc::Status;
 
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google { }
+namespace gflags { }
+using namespace google;
+using namespace gflags;
+
 static bool got_sigint = false;
 
 static void sigint_handler(int x) { got_sigint = 1; }
@@ -128,7 +135,7 @@ static void RunServer() {
 
   ServerBuilder builder;
   builder.AddPort(server_address);
-  builder.RegisterService(service.service());
+  builder.RegisterService(&service);
 
   std::unique_ptr<ThreadPool> pool(new ThreadPool(FLAGS_server_threads));
   builder.SetThreadPool(pool.get());
@@ -149,10 +156,10 @@ static void RunServer() {
 
 int main(int argc, char** argv) {
   grpc_init();
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  ParseCommandLineFlags(&argc, &argv, true);
 
   signal(SIGINT, sigint_handler);
-  
+
   GPR_ASSERT(FLAGS_port != 0);
   GPR_ASSERT(!FLAGS_enable_ssl);
   RunServer();
@@ -160,4 +167,3 @@ int main(int argc, char** argv) {
   grpc_shutdown();
   return 0;
 }
-
diff --git a/test/cpp/server/thread_pool_test.cc b/test/cpp/server/thread_pool_test.cc
index cae1a105c96d7d50001e7825126273d4d0d87a8e..824d78531607bf8b422b094e129955a329a704f3 100644
--- a/test/cpp/server/thread_pool_test.cc
+++ b/test/cpp/server/thread_pool_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index 301e9a3c3a36884598eb58d72f5527d9c973f292..b0472d32a99e9b452b24ef7b38fd3f2488bfcffe 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h
index 4e326559bfd37a26bee5d83894eff94bb7f98bde..3476b8354b1a798f302bf6749ab1e874c69fb311 100644
--- a/test/cpp/util/create_test_channel.h
+++ b/test/cpp/util/create_test_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/util/echo.proto b/test/cpp/util/echo.proto
index 01369c540f9cd541af586f85d8a1594d50dee1ea..58ec680ecd00df32254a4afe63a392a5d8d5d6e6 100644
--- a/test/cpp/util/echo.proto
+++ b/test/cpp/util/echo.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/util/echo_duplicate.proto b/test/cpp/util/echo_duplicate.proto
index b0b07269cf6ddb4eb679790be41c967969087b2c..e54c016d2f3c3d0a69c8a1bde1f56dfc4a957e53 100644
--- a/test/cpp/util/echo_duplicate.proto
+++ b/test/cpp/util/echo_duplicate.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto
index 3e4b38b839f5c51aa67c07ac69955d818b0b1645..9c27f6869ecb91da247730e42d07c828c02d7a9a 100644
--- a/test/cpp/util/messages.proto
+++ b/test/cpp/util/messages.proto
@@ -1,11 +1,11 @@
 
 // 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
@@ -15,7 +15,7 @@
 //     * 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
diff --git a/test/cpp/util/status_test.cc b/test/cpp/util/status_test.cc
index 0c32311badb6a8de67725731395f2354691d8897..8c6a3354fe46dc068bd3047d2c0f4a7b0ad6a276 100644
--- a/test/cpp/util/status_test.cc
+++ b/test/cpp/util/status_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/util/time_test.cc b/test/cpp/util/time_test.cc
index f5942aa85a1335c7391afee8359259ed67f7f9df..2e17add67faabca80cafc6293f08b5483511fed7 100644
--- a/test/cpp/util/time_test.cc
+++ b/test/cpp/util/time_test.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/tools/buildgen/build-cleaner.py b/tools/buildgen/build-cleaner.py
index 478ff4c58dc27f43df1ca49933c39ec0e46e0c04..880f3e26a48c95e6da10383761d5fc2670c3a9d0 100755
--- a/tools/buildgen/build-cleaner.py
+++ b/tools/buildgen/build-cleaner.py
@@ -40,13 +40,13 @@ TEST = (os.environ.get('TEST', 'false') == 'true')
 _TOP_LEVEL_KEYS = ['settings', 'filegroups', 'libs', 'targets']
 _VERSION_KEYS = ['major', 'minor', 'micro', 'build']
 _ELEM_KEYS = [
-    'name', 
-    'build', 
+    'name',
+    'build',
     'run',
-    'language', 
-    'public_headers', 
-    'headers', 
-    'src', 
+    'language',
+    'public_headers',
+    'headers',
+    'src',
     'deps']
 
 def rebuild_as_ordered_dict(indict, special_keys):
diff --git a/tools/buildgen/generate_projects.sh b/tools/buildgen/generate_projects.sh
index 9903f0e7835a104e086dcd8f89271389b3d16546..d37288a078c555c830e20fbedf77207bc0ed1a04 100755
--- a/tools/buildgen/generate_projects.sh
+++ b/tools/buildgen/generate_projects.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -72,4 +72,3 @@ for dir in . ; do
 done
 
 rm $end2end_test_build
-
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index fbe01841d987494a0b59bffe5e0310cba3c8d0a1..c81a1ea55bf6eac055fded9d74f9d7be74dcc593 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -41,15 +41,19 @@ os.chdir(ROOT)
 
 # parse command line
 argp = argparse.ArgumentParser(description='copyright checker')
-argp.add_argument('-o', '--output', 
-                  default='details', 
+argp.add_argument('-o', '--output',
+                  default='details',
                   choices=['list', 'details'])
-argp.add_argument('-s', '--skips', 
+argp.add_argument('-s', '--skips',
                   default=0,
                   action='store_const',
                   const=1)
-argp.add_argument('-a', '--ancient', 
-                  default=0, 
+argp.add_argument('-a', '--ancient',
+                  default=0,
+                  action='store_const',
+                  const=1)
+argp.add_argument('-f', '--fix',
+                  default=0,
                   action='store_const',
                   const=1)
 args = argp.parse_args()
@@ -94,7 +98,7 @@ def log(cond, why, filename):
 for filename in subprocess.check_output('git ls-tree -r --name-only -r HEAD',
                                         shell=True).splitlines():
   ext = os.path.splitext(filename)[1]
-  if ext not in LICENSE_TEXT: 
+  if ext not in LICENSE_TEXT:
     log(args.skips, 'skip', filename)
     continue
   license = LICENSE_TEXT[ext]
@@ -105,6 +109,9 @@ for filename in subprocess.check_output('git ls-tree -r --name-only -r HEAD',
     pass
   elif old_license in text:
     log(args.ancient, 'old', filename)
+    if args.fix:
+      with open(filename, 'w') as f:
+        f.write(text.replace('Copyright 2014, Google Inc.', 'Copyright 2015, Google Inc.') + '\n')
   elif 'DO NOT EDIT' not in text and 'AssemblyInfo.cs' not in filename:
     log(1, 'missing', filename)
 
diff --git a/tools/dockerfile/grpc_base/README.md b/tools/dockerfile/grpc_base/README.md
index e3b5f2ef373d85adb060d5d43c2f2abdc75ce843..5c81b02425d65b82b3a3cc32ccf5faf90c77eaf8 100644
--- a/tools/dockerfile/grpc_base/README.md
+++ b/tools/dockerfile/grpc_base/README.md
@@ -2,7 +2,8 @@ Base GRPC Dockerfile
 ====================
 
 Dockerfile for creating the base gRPC development Docker instance.
-For now, this assumes that the development will be done on GCE instances, with source code on Git-on-Borg.
+For now, this assumes that the development will be done on GCE instances,
+with source code on GitHub.
 
 As of 2015/02/02, it includes
 - git
diff --git a/tools/dockerfile/grpc_node/Dockerfile b/tools/dockerfile/grpc_node/Dockerfile
index ce582d2ef12a75d0db47116260997cdcd12c200b..59aa8cfd1c6a8fe2ba37b0677f144b4c48b224fb 100644
--- a/tools/dockerfile/grpc_node/Dockerfile
+++ b/tools/dockerfile/grpc_node/Dockerfile
@@ -11,4 +11,11 @@ RUN make install_c -C /var/local/git/grpc
 
 RUN cd /var/local/git/grpc/src/node && npm install && node-gyp rebuild
 
+# Add a cacerts directory containing the Google root pem file, allowing the
+# ruby client to access the production test instance
+ADD cacerts cacerts
+
+# Add a service_account directory containing the auth creds file
+ADD service_account service_account
+
 CMD ["/usr/bin/nodejs", "/var/local/git/grpc/src/node/interop/interop_server.js", "--use_tls=true", "--port=8040"]
\ No newline at end of file
diff --git a/tools/gce_setup/builder.sh b/tools/gce_setup/builder.sh
index 9fd1e1c61e6db4af8acee489e8b5684fd356ae51..d4dbd75426cf22e13610477b54ef51f1827e0a67 100755
--- a/tools/gce_setup/builder.sh
+++ b/tools/gce_setup/builder.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@ main() {
 
   # launch images for all languages on  server
   grpc_launch_servers grpc-docker-server
-  
+
 }
 
 set -x
diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh
index ffb5b85822972062bbb6e473e13f6e1644eb7142..52e9b5e2a320f5c04ed8c142482dc24e8502c812 100755
--- a/tools/gce_setup/cloud_prod_runner.sh
+++ b/tools/gce_setup/cloud_prod_runner.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
 
 main() {
   source grpc_docker.sh
-  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming)
+  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming service_account_creds compute_engine_creds)
   clients=(cxx java go ruby node)
   for test_case in "${test_cases[@]}"
   do
diff --git a/tools/gce_setup/compute_extras.sh b/tools/gce_setup/compute_extras.sh
index 4dab4c093e9766602b33627373a33912d4bde9ad..a0835a12ed448cd8e66d44370ab20434f9d0e874 100755
--- a/tools/gce_setup/compute_extras.sh
+++ b/tools/gce_setup/compute_extras.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index 37e24949f671faea1e5dbe85923264bb4b5df6a6..41a1d200e60d19dfe77b624fa83760d3be25d48a 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -350,7 +350,7 @@ grpc_interop_test_flags() {
     echo "$FUNCNAME: missing arg: test_case" 1>&2
     return 1
   }
-  echo "--server_host_override=foo.test.google.fr --server_host=$server_ip --server_port=$port --test_case=$test_case"
+  echo "--server_host=$server_ip --server_port=$port --test_case=$test_case"
 }
 
 # checks the positional args and assigns them to variables visible in the caller
@@ -795,7 +795,7 @@ grpc_interop_test() {
   echo "  $ssh_cmd"
   echo "on $host"
   [[ $dry_run == 1 ]] && return 0  # don't run the command on a dry run
-  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" & 
+  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
   PID=$!
   sleep 10
   echo "pid is $PID"
@@ -850,7 +850,7 @@ grpc_cloud_prod_test() {
   echo "  $ssh_cmd"
   echo "on $host"
   [[ $dry_run == 1 ]] && return 0  # don't run the command on a dry run
-  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" & 
+  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
   PID=$!
   sleep 10
   echo "pid is $PID"
@@ -974,7 +974,7 @@ grpc_cloud_prod_auth_compute_engine_creds_gen_ruby_cmd() {
 #   cmd=$($grpc_gen_test_cmd $flags)
 grpc_interop_gen_go_cmd() {
   local cmd_prefix="sudo docker run grpc/go /bin/bash -c"
-  local test_script="cd /go/src/github.com/google/grpc-go/rpc/interop/client"
+  local test_script="cd src/google.golang.org/grpc/interop/client"
   local test_script+=" && go run client.go --use_tls=true"
   local the_cmd="$cmd_prefix '$test_script $@'"
   echo $the_cmd
@@ -987,7 +987,7 @@ grpc_interop_gen_go_cmd() {
 #   cmd=$($grpc_gen_test_cmd $flags)
 grpc_cloud_prod_gen_go_cmd() {
   local cmd_prefix="sudo docker run grpc/go /bin/bash -c"
-  local test_script="cd /go/src/github.com/google/grpc-go/rpc/interop/client"
+  local test_script="cd src/google.golang.org/grpc/interop/client"
   local test_script+=" && go run client.go --use_tls=true"
   local gfe_flags="  --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com"
   local the_cmd="$cmd_prefix '$test_script $gfe_flags $@'"
@@ -1044,11 +1044,39 @@ grpc_interop_gen_php_cmd() {
 #   cmd=$($grpc_gen_test_cmd $flags)
 grpc_interop_gen_node_cmd() {
   local cmd_prefix="sudo docker run grpc/node";
-  local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true";
+  local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true --use_test_ca=true";
   local the_cmd="$cmd_prefix $test_script $@";
   echo $the_cmd
 }
 
+# constructs the full dockerized node gce=>prod interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_gen_node_cmd() {
+  local cmd_prefix="sudo docker run grpc/node";
+  local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true";
+  local gfe_flags=$(_grpc_prod_gfe_flags);
+  local the_cmd="$cmd_prefix $test_script $gfe_flags $@";
+  echo $the_cmd
+}
+
+# constructs the full dockerized node service_account auth interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_auth_service_account_creds_gen_node_cmd() {
+  local cmd_prefix="sudo docker run grpc/node";
+  local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true";
+  local gfe_flags=$(_grpc_prod_gfe_flags);
+  local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
+  env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
+  local the_cmd="$env_prefix $cmd_prefix $test_script $gfe_flags $@";
+  echo $the_cmd
+}
+
 # constructs the full dockerized cpp interop test cmd.
 #
 # call-seq:
diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh
index a1d7813b201539128dd4eb5bbd8e4183f7416509..465c2ab6a789b5f1adf57f7f8a5b5e5b20a6151e 100755
--- a/tools/gce_setup/interop_test_runner.sh
+++ b/tools/gce_setup/interop_test_runner.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@ echo $result_file_name
 
 main() {
   source grpc_docker.sh
-  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming)
+  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_being cancel_after_first_response)
   clients=(cxx java go ruby node)
   servers=(cxx java go ruby node python)
   for test_case in "${test_cases[@]}"
diff --git a/tools/gce_setup/new_grpc_docker_builder.sh b/tools/gce_setup/new_grpc_docker_builder.sh
index 70a2f1254025cd8da82fe5528a8187504c274426..8a9ece33170d33b89c9f8341d75388faf6607049 100755
--- a/tools/gce_setup/new_grpc_docker_builder.sh
+++ b/tools/gce_setup/new_grpc_docker_builder.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/gce_setup/new_grpc_docker_builder_on_startup.sh b/tools/gce_setup/new_grpc_docker_builder_on_startup.sh
index a084fe08d6a08c97d2a4a195100e957d1185927d..30eb0377c295d0f53622586d571eefca7c00f3e7 100755
--- a/tools/gce_setup/new_grpc_docker_builder_on_startup.sh
+++ b/tools/gce_setup/new_grpc_docker_builder_on_startup.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/gce_setup/shared_startup_funcs.sh b/tools/gce_setup/shared_startup_funcs.sh
index 13bf3124fa3b63bab87a9eeddb3323ac1683b2b2..143e039c93dadde64471ea6bfacc205bdc25b041 100755
--- a/tools/gce_setup/shared_startup_funcs.sh
+++ b/tools/gce_setup/shared_startup_funcs.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -416,6 +416,10 @@ grpc_dockerfile_install() {
     grpc_docker_sync_roots_pem $dockerfile_dir/cacerts || return 1;
     grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1;
   }
+  [[ $image_label == "grpc/node" ]] && {
+    grpc_docker_sync_roots_pem $dockerfile_dir/cacerts || return 1;
+    grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1;
+  }
   [[ $image_label == "grpc/cxx" ]] && {
     grpc_docker_sync_roots_pem $dockerfile_dir/cacerts || return 1;
     grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1;
diff --git a/tools/run_tests/build_node.sh b/tools/run_tests/build_node.sh
index 85feacfb86c9d2e71af00672bf0b19cc29c47285..c3e88c565d276cac7f804d545f215a417541e443 100755
--- a/tools/run_tests/build_node.sh
+++ b/tools/run_tests/build_node.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/run_tests/build_php.sh b/tools/run_tests/build_php.sh
index d32969f39ca27f74e29443e8f7a1373d9913af73..2d52a6e33b458ce521d911ab76d692ee00609a1e 100755
--- a/tools/run_tests/build_php.sh
+++ b/tools/run_tests/build_php.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index 084b3893ab09f20b27adde64252eac33909e1b0c..9303a67a1e669ed24e8bb05c0225d5b0c3c8c1be 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/run_tests/run_lcov.sh b/tools/run_tests/run_lcov.sh
index 7696536141d6c70818ab395ec95ceea6c57d2f2c..292aec454825d24ceb63eea355d9eff21bbc4ebd 100755
--- a/tools/run_tests/run_lcov.sh
+++ b/tools/run_tests/run_lcov.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -43,4 +43,3 @@ if which xdg-open > /dev/null
 then
   xdg-open file://$out/index.html
 fi
-
diff --git a/tools/run_tests/run_node.sh b/tools/run_tests/run_node.sh
index 525b34a7095ed2b0cf64f49b528ba411e468355a..ccf1b9d6f54918d9dd713f95ee1c516a5884a9d8 100755
--- a/tools/run_tests/run_node.sh
+++ b/tools/run_tests/run_node.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index fc7e4871182abe73575d8c6465b5cebb3dc5db3a..f21f854b09a3b15906eff24f524abfb5d4fc8fb6 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2014, Google Inc.
+# Copyright 2015, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 72a4b0cd122b8ef3387ae116a5710b2bf20e60fc..64478b37532775a19a2fc5a1b1d8eba37fa94467 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -62,15 +62,18 @@ class SimpleConfig(object):
 # ValgrindConfig: compile with some CONFIG=config, but use valgrind to run
 class ValgrindConfig(object):
 
-  def __init__(self, config, tool):
+  def __init__(self, config, tool, args=[]):
     self.build_config = config
     self.tool = tool
+    self.args = args
     self.maxjobs = 2 * multiprocessing.cpu_count()
     self.allow_hashing = False
 
   def job_spec(self, binary, hash_targets):
-    return jobset.JobSpec(cmdline=['valgrind', '--tool=%s' % self.tool, binary],
-                   hash_targets=None)
+    return jobset.JobSpec(cmdline=['valgrind', '--tool=%s' % self.tool] +
+                          self.args + [binary],
+                          shortname='valgrind %s' % binary,
+                          hash_targets=None)
 
 
 class CLanguage(object):
@@ -144,7 +147,7 @@ _CONFIGS = {
     'asan': SimpleConfig('asan', environ={
         'ASAN_OPTIONS': 'detect_leaks=1:color=always:suppressions=tools/tsan_suppressions.txt'}),
     'gcov': SimpleConfig('gcov'),
-    'memcheck': ValgrindConfig('valgrind', 'memcheck'),
+    'memcheck': ValgrindConfig('valgrind', 'memcheck', ['--leak-check=full']),
     'helgrind': ValgrindConfig('dbg', 'helgrind')
     }
 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 2b3e6702c5df070cde405f8dfeb251f6ae0dcb29..b5d61595c2ea5594b15a975ada45cf79c60c92f0 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -269,6 +269,10 @@
     "language": "c", 
     "name": "transport_metadata_test"
   }, 
+  {
+    "language": "c++", 
+    "name": "async_end2end_test"
+  }, 
   {
     "language": "c++", 
     "name": "channel_arguments_test"
@@ -293,10 +297,6 @@
     "language": "c++", 
     "name": "status_test"
   }, 
-  {
-    "language": "c++", 
-    "name": "sync_client_async_server_test"
-  }, 
   {
     "language": "c++", 
     "name": "thread_pool_test"
diff --git a/vsprojects/third_party/openssl/buildinf.h b/vsprojects/third_party/openssl/buildinf.h
index 8249d5e7ff08a0d38fbd2792e5555d6eac491684..0901f8d9ae13b86887db7c95607d9466f0f9bcc5 100644
--- a/vsprojects/third_party/openssl/buildinf.h
+++ b/vsprojects/third_party/openssl/buildinf.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/vsprojects/third_party/openssl/opensslconf.h b/vsprojects/third_party/openssl/opensslconf.h
index f04044538431cc5da752c20fc2c97d8006a1e2d9..0f5ae4059f05f2c0b17687e7ccda373a6fcfe0c7 100644
--- a/vsprojects/third_party/openssl/opensslconf.h
+++ b/vsprojects/third_party/openssl/opensslconf.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2014, Google Inc.
+ * Copyright 2015, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/vsprojects/vs2013/gpr.vcxproj b/vsprojects/vs2013/gpr.vcxproj
index f6516b8953751adb02e76386fc4685451c45b8db..3d970079a423fa41147e4822ae2263221e4fe9c8 100644
--- a/vsprojects/vs2013/gpr.vcxproj
+++ b/vsprojects/vs2013/gpr.vcxproj
@@ -101,7 +101,6 @@
     <ClInclude Include="..\..\include\grpc\support\useful.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\core\support\cpu.h" />
     <ClInclude Include="..\..\src\core\support\env.h" />
     <ClInclude Include="..\..\src\core\support\file.h" />
     <ClInclude Include="..\..\src\core\support\murmur_hash.h" />
diff --git a/vsprojects/vs2013/gpr.vcxproj.filters b/vsprojects/vs2013/gpr.vcxproj.filters
index 1e908a5ba51fbdb384f45bfcdb2832c2f37d7e30..9b78c3a390a2c4d8447baeb6a83fa4332d970279 100644
--- a/vsprojects/vs2013/gpr.vcxproj.filters
+++ b/vsprojects/vs2013/gpr.vcxproj.filters
@@ -167,9 +167,6 @@
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\core\support\cpu.h">
-      <Filter>src\core\support</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\support\env.h">
       <Filter>src\core\support</Filter>
     </ClInclude>
diff --git a/vsprojects/vs2013/gpr_shared.vcxproj b/vsprojects/vs2013/gpr_shared.vcxproj
index b9131e381c12ae7407e840b2eca7b2606d41f23f..892490e3248197edeb1b10f55b41facdd99c84f5 100644
--- a/vsprojects/vs2013/gpr_shared.vcxproj
+++ b/vsprojects/vs2013/gpr_shared.vcxproj
@@ -101,7 +101,6 @@
     <ClInclude Include="..\..\include\grpc\support\useful.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\core\support\cpu.h" />
     <ClInclude Include="..\..\src\core\support\env.h" />
     <ClInclude Include="..\..\src\core\support\file.h" />
     <ClInclude Include="..\..\src\core\support\murmur_hash.h" />
diff --git a/vsprojects/vs2013/gpr_shared.vcxproj.filters b/vsprojects/vs2013/gpr_shared.vcxproj.filters
index 1e908a5ba51fbdb384f45bfcdb2832c2f37d7e30..9b78c3a390a2c4d8447baeb6a83fa4332d970279 100644
--- a/vsprojects/vs2013/gpr_shared.vcxproj.filters
+++ b/vsprojects/vs2013/gpr_shared.vcxproj.filters
@@ -167,9 +167,6 @@
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\core\support\cpu.h">
-      <Filter>src\core\support</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\support\env.h">
       <Filter>src\core\support</Filter>
     </ClInclude>