Merge pull request #7093 from murgatroid99/run_interop_override_server_fix

Fix bug with override_server flag in run_interop_tests.py
diff --git a/.travis.yml b/.travis.yml
index 16c6390..fcdfd8b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,34 @@
     - CONFIG=opt
     - TEST=objc
     - JOBS=1
+  matrix:
+    - SCHEME="RxLibraryUnitTests" WORKSPACE="Tests.xcworkspace"
+      TEST_PATH="src/objective-c/tests" BUILD_ONLY="false"
+      INTEROP_SERVER="false"
+    - SCHEME="InteropTestsLocalSSL" WORKSPACE="Tests.xcworkspace"
+      TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="true"
+    - SCHEME="InteropTestsLocalCleartext" WORKSPACE="Tests.xcworkspace"
+      TEST_PATH="src/objective-c/tests"  BUILD_ONLY="false"
+      INTEROP_SERVER="true"
+    # TODO(jcanizales): Investigate why they time out:
+    # - SCHEME="InteropTestsRemote" WORKSPACE="Tests.xcworkspace"
+    #   TEST_PATH="src/objective-c/tests" BUILD_ONLY="false"
+    #   INTEROP_SERVER="true"
+    - SCHEME="HelloWorld" WORKSPACE="HelloWorld.xcworkspace"
+      TEST_PATH="examples/objective-c/helloworld" BUILD_ONLY="true"
+      INTEROP_SERVER="false"
+    - SCHEME="RouteGuideClient" WORKSPACE="RouteGuideClient.xcworkspace"
+      TEST_PATH="examples/objective-c/route_guide" BUILD_ONLY="true"
+      INTEROP_SERVER="false"
+    - SCHEME="AuthSample" WORKSPACE="AuthSample.xcworkspace"
+      TEST_PATH="examples/objective-c/auth_sample" BUILD_ONLY="true"
+      INTEROP_SERVER="false"
+    - SCHEME="Sample" WORKSPACE="Sample.xcworkspace"
+      TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true"
+      INTEROP_SERVER="false"
+    - SCHEME="SwiftSample" WORKSPACE="SwiftSample.xcworkspace"
+      TEST_PATH="src/objective-c/examples/SwiftSample" BUILD_ONLY="true"
+      INTEROP_SERVER="false"
 before_install:
   - pod --version
   - gem uninstall cocoapods -a
@@ -16,20 +44,24 @@
   - popd
 install:
   - make grpc_objective_c_plugin
-  - pushd src/objective-c/tests
+  - install bins/opt/grpc_objective_c_plugin /usr/local/bin/protoc-gen-objcgrpc
+  - install bins/opt/protobuf/protoc /usr/local/bin/protoc
+  - pushd $TEST_PATH
   - pod install
   - popd
 before_script:
-  - make interop_server
-  - bins/$CONFIG/interop_server --port=5050 &
-  - bins/$CONFIG/interop_server --port=5051 --use_tls &
-xcode_workspace: src/objective-c/tests/Tests.xcworkspace
-xcode_scheme:
-  - RxLibraryUnitTests
-  - InteropTestsLocalSSL
-  - InteropTestsLocalCleartext
-  # TODO(jcanizales): Investigate why they time out:
-  # - InteropTestsRemote
-xcode_sdk: iphonesimulator9.3
+  - if [ "${INTEROP_SERVER}" = "true" ]; then
+      make interop_server;
+      (bins/$CONFIG/interop_server --port=5050 &);
+      (bins/$CONFIG/interop_server --port=5051 --use_tls &);
+    fi
+script:
+  - if [ "${BUILD_ONLY}" = "true" ]; then
+      xctool -workspace "$TEST_PATH/$WORKSPACE" -scheme "$SCHEME"
+      -sdk iphonesimulator9.3 build;
+    else
+      xctool -workspace "$TEST_PATH/$WORKSPACE" -scheme "$SCHEME"
+      -sdk iphonesimulator9.3 test;
+    fi
 notifications:
   email: false
diff --git a/BUILD b/BUILD
index 8f3e16a..33323be 100644
--- a/BUILD
+++ b/BUILD
@@ -230,7 +230,6 @@
     "src/core/lib/surface/init.h",
     "src/core/lib/surface/lame_client.h",
     "src/core/lib/surface/server.h",
-    "src/core/lib/surface/surface_trace.h",
     "src/core/lib/transport/byte_stream.h",
     "src/core/lib/transport/connectivity_state.h",
     "src/core/lib/transport/metadata.h",
@@ -618,7 +617,6 @@
     "src/core/lib/surface/init.h",
     "src/core/lib/surface/lame_client.h",
     "src/core/lib/surface/server.h",
-    "src/core/lib/surface/surface_trace.h",
     "src/core/lib/transport/byte_stream.h",
     "src/core/lib/transport/connectivity_state.h",
     "src/core/lib/transport/metadata.h",
@@ -971,7 +969,6 @@
     "src/core/lib/surface/init.h",
     "src/core/lib/surface/lame_client.h",
     "src/core/lib/surface/server.h",
-    "src/core/lib/surface/surface_trace.h",
     "src/core/lib/transport/byte_stream.h",
     "src/core/lib/transport/connectivity_state.h",
     "src/core/lib/transport/metadata.h",
@@ -2074,7 +2071,6 @@
     "src/core/lib/surface/init.h",
     "src/core/lib/surface/lame_client.h",
     "src/core/lib/surface/server.h",
-    "src/core/lib/surface/surface_trace.h",
     "src/core/lib/transport/byte_stream.h",
     "src/core/lib/transport/connectivity_state.h",
     "src/core/lib/transport/metadata.h",
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 35eb5e6..56bb4b6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -53,6 +53,13 @@
 
 `./tools/run_tests/run_tests.py -h`
 
+If you are running tests for ObjC on osx, follow these steps before running tests:
+* install Xcode command-line tools by running
+`sudo xcode-select --install`
+* install macports from https://www.macports.org/install.php
+* install autoconf, automake, libtool, gflags, cmake using macports
+* restart your terminal window or run source ~/.bash_profile to pick up the new PATH changes.
+
 ## Adding or removing source code
 
 Each language uses its own build system to work. Currently, the root's Makefile
diff --git a/INSTALL.md b/INSTALL.md
index 66e6c33..6718aad 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -49,7 +49,7 @@
 gRPC C Core library.
 
 ```sh
- $ git clone https://github.com/grpc/grpc.git
+ $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
  $ cd grpc
  $ git submodule update --init
  $ make
diff --git a/Makefile b/Makefile
index 358252f..8fd86e7 100644
--- a/Makefile
+++ b/Makefile
@@ -995,7 +995,6 @@
 timeout_encoding_test: $(BINDIR)/$(CONFIG)/timeout_encoding_test
 timer_heap_test: $(BINDIR)/$(CONFIG)/timer_heap_test
 timer_list_test: $(BINDIR)/$(CONFIG)/timer_list_test
-timers_test: $(BINDIR)/$(CONFIG)/timers_test
 transport_connectivity_state_test: $(BINDIR)/$(CONFIG)/transport_connectivity_state_test
 transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test
 transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test
@@ -1326,7 +1325,6 @@
   $(BINDIR)/$(CONFIG)/timeout_encoding_test \
   $(BINDIR)/$(CONFIG)/timer_heap_test \
   $(BINDIR)/$(CONFIG)/timer_list_test \
-  $(BINDIR)/$(CONFIG)/timers_test \
   $(BINDIR)/$(CONFIG)/transport_connectivity_state_test \
   $(BINDIR)/$(CONFIG)/transport_metadata_test \
   $(BINDIR)/$(CONFIG)/transport_security_test \
@@ -1707,8 +1705,6 @@
 	$(Q) $(BINDIR)/$(CONFIG)/timer_heap_test || ( echo test timer_heap_test failed ; exit 1 )
 	$(E) "[RUN]     Testing timer_list_test"
 	$(Q) $(BINDIR)/$(CONFIG)/timer_list_test || ( echo test timer_list_test failed ; exit 1 )
-	$(E) "[RUN]     Testing timers_test"
-	$(Q) $(BINDIR)/$(CONFIG)/timers_test || ( echo test timers_test failed ; exit 1 )
 	$(E) "[RUN]     Testing transport_connectivity_state_test"
 	$(Q) $(BINDIR)/$(CONFIG)/transport_connectivity_state_test || ( echo test transport_connectivity_state_test failed ; exit 1 )
 	$(E) "[RUN]     Testing transport_metadata_test"
@@ -10028,38 +10024,6 @@
 endif
 
 
-TIMERS_TEST_SRC = \
-    test/core/profiling/timers_test.c \
-
-TIMERS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMERS_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/timers_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/timers_test: $(TIMERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(TIMERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timers_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/profiling/timers_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_timers_test: $(TIMERS_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(TIMERS_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 TRANSPORT_CONNECTIVITY_STATE_TEST_SRC = \
     test/core/transport/connectivity_state_test.c \
 
diff --git a/build.yaml b/build.yaml
index 8ebcccb..2446b9f 100644
--- a/build.yaml
+++ b/build.yaml
@@ -141,11 +141,6 @@
   - include/grpc/impl/codegen/sync_posix.h
   - include/grpc/impl/codegen/sync_windows.h
   - include/grpc/impl/codegen/time.h
-- name: grpc++_codegen_base_src
-  src:
-  - src/cpp/codegen/codegen_init.cc
-  uses:
-  - grpc++_codegen_base
 - name: grpc_base
   public_headers:
   - include/grpc/byte_buffer.h
@@ -226,7 +221,6 @@
   - src/core/lib/surface/init.h
   - src/core/lib/surface/lame_client.h
   - src/core/lib/surface/server.h
-  - src/core/lib/surface/surface_trace.h
   - src/core/lib/transport/byte_stream.h
   - src/core/lib/transport/connectivity_state.h
   - src/core/lib/transport/metadata.h
@@ -757,6 +751,12 @@
   - include/grpc++/impl/codegen/time.h
   uses:
   - grpc_codegen
+- name: grpc++_codegen_base_src
+  language: c++
+  src:
+  - src/cpp/codegen/codegen_init.cc
+  uses:
+  - grpc++_codegen_base
 - name: grpc++_codegen_proto
   language: c++
   public_headers:
@@ -2352,16 +2352,6 @@
   - grpc
   - gpr_test_util
   - gpr
-- name: timers_test
-  build: test
-  language: c
-  src:
-  - test/core/profiling/timers_test.c
-  deps:
-  - grpc_test_util
-  - grpc
-  - gpr_test_util
-  - gpr
 - name: transport_connectivity_state_test
   build: test
   language: c
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index a4f9abe..e7b6f8c 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -968,8 +968,8 @@
 [StreamingOutputCall]: #streamingoutputcall
 
 Server implements StreamingOutputCall by replying, in order, with one
-StreamingOutputCallResponses for each ResponseParameters in
-StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a
+StreamingOutputCallResponse for each ResponseParameters in
+StreamingOutputCallRequest. Each StreamingOutputCallResponse should have a
 payload body of size ResponseParameters.size bytes, as specified by its
 respective ResponseParameters. After sending all responses, it closes with OK.
 
@@ -977,8 +977,8 @@
 [FullDuplexCall]: #fullduplexcall
 
 Server implements FullDuplexCall by replying, in order, with one
-StreamingOutputCallResponses for each ResponseParameters in each
-StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a
+StreamingOutputCallResponse for each ResponseParameters in each
+StreamingOutputCallRequest. Each StreamingOutputCallResponse should have a
 payload body of size ResponseParameters.size bytes, as specified by its
 respective ResponseParameters. After receiving half close and sending all
 responses, it closes with OK.
diff --git a/examples/cpp/README.md b/examples/cpp/README.md
index d93cbac..3fa7ad4 100644
--- a/examples/cpp/README.md
+++ b/examples/cpp/README.md
@@ -14,7 +14,7 @@
 
 
 ```sh
-$ git clone https://github.com/grpc/grpc.git
+$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
 ```
 
 Change your current directory to examples/cpp/helloworld
diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md
index ef9ca99..80fef07 100644
--- a/examples/cpp/cpptutorial.md
+++ b/examples/cpp/cpptutorial.md
@@ -20,7 +20,7 @@
 
 The example code for our tutorial is in [examples/cpp/route_guide](route_guide). To download the example, clone this repository by running the following command:
 ```shell
-$ git clone https://github.com/grpc/grpc.git
+$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
 ```
 
 Then change your current directory to `examples/cpp/route_guide`:
diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md
index 04283ea..db953f5 100644
--- a/examples/cpp/helloworld/README.md
+++ b/examples/cpp/helloworld/README.md
@@ -12,7 +12,7 @@
 
 
 ```sh
-$ git clone https://github.com/grpc/grpc.git
+$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
 ```
 
 Change your current directory to examples/cpp/helloworld
diff --git a/examples/node/README.md b/examples/node/README.md
index 59fb4a1..b92ca38 100644
--- a/examples/node/README.md
+++ b/examples/node/README.md
@@ -12,7 +12,7 @@
    ```sh
    $ # Get the gRPC repository
    $ export REPO_ROOT=grpc # REPO root can be any directory of your choice
-   $ git clone https://github.com/grpc/grpc.git $REPO_ROOT
+   $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc $REPO_ROOT
    $ cd $REPO_ROOT
 
    $ cd examples/node
diff --git a/examples/objective-c/auth_sample/AuthSample.xcodeproj/xcshareddata/xcschemes/AuthSample.xcscheme b/examples/objective-c/auth_sample/AuthSample.xcodeproj/xcshareddata/xcschemes/AuthSample.xcscheme
new file mode 100644
index 0000000..0a21071
--- /dev/null
+++ b/examples/objective-c/auth_sample/AuthSample.xcodeproj/xcshareddata/xcschemes/AuthSample.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0730"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "63E1E97B1B28CB2000EF0978"
+               BuildableName = "AuthSample.app"
+               BlueprintName = "AuthSample"
+               ReferencedContainer = "container:AuthSample.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "63E1E97B1B28CB2000EF0978"
+            BuildableName = "AuthSample.app"
+            BlueprintName = "AuthSample"
+            ReferencedContainer = "container:AuthSample.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "63E1E97B1B28CB2000EF0978"
+            BuildableName = "AuthSample.app"
+            BlueprintName = "AuthSample"
+            ReferencedContainer = "container:AuthSample.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "63E1E97B1B28CB2000EF0978"
+            BuildableName = "AuthSample.app"
+            BlueprintName = "AuthSample"
+            ReferencedContainer = "container:AuthSample.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme b/examples/objective-c/helloworld/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme
new file mode 100644
index 0000000..be7b990
--- /dev/null
+++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/xcshareddata/xcschemes/HelloWorld.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0730"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "5E36905F1B2A23800040F884"
+               BuildableName = "HelloWorld.app"
+               BlueprintName = "HelloWorld"
+               ReferencedContainer = "container:HelloWorld.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "5E36905F1B2A23800040F884"
+            BuildableName = "HelloWorld.app"
+            BlueprintName = "HelloWorld"
+            ReferencedContainer = "container:HelloWorld.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "5E36905F1B2A23800040F884"
+            BuildableName = "HelloWorld.app"
+            BlueprintName = "HelloWorld"
+            ReferencedContainer = "container:HelloWorld.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "5E36905F1B2A23800040F884"
+            BuildableName = "HelloWorld.app"
+            BlueprintName = "HelloWorld"
+            ReferencedContainer = "container:HelloWorld.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/examples/objective-c/helloworld/README.md b/examples/objective-c/helloworld/README.md
index 81c5aaa..fdff938 100644
--- a/examples/objective-c/helloworld/README.md
+++ b/examples/objective-c/helloworld/README.md
@@ -16,7 +16,7 @@
 
 
 ```sh
-$ git clone https://github.com/grpc/grpc.git
+$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
 $ cd grpc
 $ git submodule update --init
 ```
diff --git a/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/xcshareddata/xcschemes/RouteGuideClient.xcscheme b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/xcshareddata/xcschemes/RouteGuideClient.xcscheme
new file mode 100644
index 0000000..42806a7
--- /dev/null
+++ b/examples/objective-c/route_guide/RouteGuideClient.xcodeproj/xcshareddata/xcschemes/RouteGuideClient.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0730"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "6325277C1B1D0395003073D9"
+               BuildableName = "RouteGuideClient.app"
+               BlueprintName = "RouteGuideClient"
+               ReferencedContainer = "container:RouteGuideClient.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "6325277C1B1D0395003073D9"
+            BuildableName = "RouteGuideClient.app"
+            BlueprintName = "RouteGuideClient"
+            ReferencedContainer = "container:RouteGuideClient.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "6325277C1B1D0395003073D9"
+            BuildableName = "RouteGuideClient.app"
+            BlueprintName = "RouteGuideClient"
+            ReferencedContainer = "container:RouteGuideClient.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "6325277C1B1D0395003073D9"
+            BuildableName = "RouteGuideClient.app"
+            BlueprintName = "RouteGuideClient"
+            ReferencedContainer = "container:RouteGuideClient.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/examples/php/README.md b/examples/php/README.md
index ea9ccb6..e56b017 100644
--- a/examples/php/README.md
+++ b/examples/php/README.md
@@ -17,7 +17,7 @@
  - Clone this repository
 
    ```sh
-   $ git clone https://github.com/grpc/grpc.git
+   $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
    ```
 
  - Install composer
diff --git a/gRPC.podspec b/gRPC.podspec
index d4eb293..fd58bd6 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -233,7 +233,6 @@
                       'src/core/lib/surface/init.h',
                       'src/core/lib/surface/lame_client.h',
                       'src/core/lib/surface/server.h',
-                      'src/core/lib/surface/surface_trace.h',
                       'src/core/lib/transport/byte_stream.h',
                       'src/core/lib/transport/connectivity_state.h',
                       'src/core/lib/transport/metadata.h',
@@ -617,7 +616,6 @@
                               'src/core/lib/surface/init.h',
                               'src/core/lib/surface/lame_client.h',
                               'src/core/lib/surface/server.h',
-                              'src/core/lib/surface/surface_trace.h',
                               'src/core/lib/transport/byte_stream.h',
                               'src/core/lib/transport/connectivity_state.h',
                               'src/core/lib/transport/metadata.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 370f009..369851b 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -242,7 +242,6 @@
   s.files += %w( src/core/lib/surface/init.h )
   s.files += %w( src/core/lib/surface/lame_client.h )
   s.files += %w( src/core/lib/surface/server.h )
-  s.files += %w( src/core/lib/surface/surface_trace.h )
   s.files += %w( src/core/lib/transport/byte_stream.h )
   s.files += %w( src/core/lib/transport/connectivity_state.h )
   s.files += %w( src/core/lib/transport/metadata.h )
diff --git a/package.xml b/package.xml
index 253928f..49a6d90 100644
--- a/package.xml
+++ b/package.xml
@@ -10,7 +10,7 @@
   <email>grpc-packages@google.com</email>
   <active>yes</active>
  </lead>
- <date>2016-05-19</date>
+ <date>2016-06-30</date>
  <time>16:06:07</time>
  <version>
   <release>0.16.0</release>
@@ -22,7 +22,7 @@
  </stability>
  <license>BSD</license>
  <notes>
-- TBD
+- Fix shutdown hang problem #4017
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
@@ -249,7 +249,6 @@
     <file baseinstalldir="/" name="src/core/lib/surface/init.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/lame_client.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/server.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/surface/surface_trace.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/transport/byte_stream.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/transport/metadata.h" role="src" />
@@ -1035,6 +1034,7 @@
    <license>BSD</license>
    <notes>
 - Simplify gRPC PHP installation #4517
+- Wrap gRPC core library version 0.13
    </notes>
   </release>
   <release>
@@ -1064,13 +1064,14 @@
    <date>2016-04-19</date>
    <license>BSD</license>
    <notes>
+- wrap grpc C core version 0.14.0
 - destroy grpc_byte_buffer after startBatch #6096
    </notes>
   </release>
   <release>
    <version>
-    <release>0.14.2</release>
-    <api>0.14.2</api>
+    <release>0.15.0</release>
+    <api>0.15.0</api>
    </version>
    <stability>
     <release>beta</release>
@@ -1080,6 +1081,22 @@
    <license>BSD</license>
    <notes>
 - Updated functions with TSRM macros for ZTS support #6607
+- Load default roots.pem via grpc_set_ssl_roots_override_callback #6848
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.15.1</release>
+    <api>0.15.1</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2016-06-30</date>
+   <license>BSD</license>
+   <notes>
+- Fix shutdown hang problem #4017
    </notes>
   </release>
  </changelog>
diff --git a/setup.py b/setup.py
index 7e625b9..c134118 100644
--- a/setup.py
+++ b/setup.py
@@ -167,7 +167,7 @@
 }
 
 INSTALL_REQUIRES = (
-    'six>=1.10',
+    'six>=1.5.2',
     'enum34>=1.0.4',
     'futures>=2.2.0',
     # TODO(atash): eventually split the grpcio package into a metapackage
@@ -175,10 +175,11 @@
     'protobuf>=3.0.0a3',
 )
 
-SETUP_REQUIRES = (
+SETUP_REQUIRES = INSTALL_REQUIRES + (
     'sphinx>=1.3',
-    'sphinx_rtd_theme>=0.1.8'
-) + INSTALL_REQUIRES
+    'sphinx_rtd_theme>=0.1.8',
+    'six>=1.10',
+)
 
 COMMAND_CLASS = {
     'doc': commands.SphinxDocumentation,
diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 72e4e54..f51d850 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -45,6 +45,7 @@
 #include "src/core/ext/census/census_interface.h"
 #include "src/core/ext/census/census_rpc_stats.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 typedef struct call_data {
@@ -92,6 +93,7 @@
 
 static void server_on_done_recv(grpc_exec_ctx *exec_ctx, void *ptr,
                                 grpc_error *error) {
+  GPR_TIMER_BEGIN("census-server:server_on_done_recv", 0);
   grpc_call_element *elem = ptr;
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
@@ -99,6 +101,7 @@
     extract_and_annotate_method_tag(calld->recv_initial_metadata, calld, chand);
   }
   calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
+  GPR_TIMER_END("census-server:server_on_done_recv", 0);
 }
 
 static void server_mutate_op(grpc_call_element *elem,
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index 1d5a7d5..a096435 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -367,6 +367,8 @@
                               uint32_t initial_metadata_flags,
                               grpc_connected_subchannel **connected_subchannel,
                               grpc_closure *on_ready) {
+  GPR_TIMER_BEGIN("cc_pick_subchannel", 0);
+
   grpc_call_element *elem = elemp;
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
@@ -391,6 +393,7 @@
       }
     }
     gpr_mu_unlock(&chand->mu_config);
+    GPR_TIMER_END("cc_pick_subchannel", 0);
     return 1;
   }
   if (chand->lb_policy != NULL) {
@@ -402,6 +405,7 @@
                             initial_metadata, initial_metadata_flags,
                             connected_subchannel, on_ready);
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel");
+    GPR_TIMER_END("cc_pick_subchannel", 0);
     return r;
   }
   if (chand->resolver != NULL && !chand->started_resolving) {
@@ -426,6 +430,8 @@
                         NULL);
   }
   gpr_mu_unlock(&chand->mu_config);
+
+  GPR_TIMER_END("cc_pick_subchannel", 0);
   return 0;
 }
 
diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c
index 468067e..d089cd4 100644
--- a/src/core/ext/client_config/subchannel.c
+++ b/src/core/ext/client_config/subchannel.c
@@ -690,9 +690,11 @@
 void grpc_subchannel_call_process_op(grpc_exec_ctx *exec_ctx,
                                      grpc_subchannel_call *call,
                                      grpc_transport_stream_op *op) {
+  GPR_TIMER_BEGIN("grpc_subchannel_call_process_op", 0);
   grpc_call_stack *call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
   grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0);
   top_elem->filter->start_transport_stream_op(exec_ctx, top_elem, op);
+  GPR_TIMER_END("grpc_subchannel_call_process_op", 0);
 }
 
 grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
diff --git a/src/core/ext/client_config/subchannel_call_holder.c b/src/core/ext/client_config/subchannel_call_holder.c
index e31800e..b96a0ad 100644
--- a/src/core/ext/client_config/subchannel_call_holder.c
+++ b/src/core/ext/client_config/subchannel_call_holder.c
@@ -120,16 +120,13 @@
     return;
   }
   /* if this is a cancellation, then we can raise our cancelled flag */
-  if (op->cancel_with_status != GRPC_STATUS_OK) {
+  if (op->cancel_error != GRPC_ERROR_NONE) {
     if (!gpr_atm_rel_cas(&holder->subchannel_call, 0, 1)) {
       goto retry;
     } else {
       switch (holder->creation_phase) {
         case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
-          fail_locked(exec_ctx, holder,
-                      grpc_error_set_int(GRPC_ERROR_CREATE("Cancelled"),
-                                         GRPC_ERROR_INT_GRPC_STATUS,
-                                         op->cancel_with_status));
+          fail_locked(exec_ctx, holder, GRPC_ERROR_REF(op->cancel_error));
           break;
         case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
           holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL,
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 9c12556..38e782b 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -106,14 +106,12 @@
 static void cancel_from_api(grpc_exec_ctx *exec_ctx,
                             grpc_chttp2_transport_global *transport_global,
                             grpc_chttp2_stream_global *stream_global,
-                            grpc_status_code status,
-                            gpr_slice *optional_message);
+                            grpc_error *error);
 
 static void close_from_api(grpc_exec_ctx *exec_ctx,
                            grpc_chttp2_transport_global *transport_global,
                            grpc_chttp2_stream_global *stream_global,
-                           grpc_status_code status,
-                           gpr_slice *optional_message);
+                           grpc_error *error);
 
 /** Add endpoint from this transport to pollset */
 static void add_to_pollset_locked(grpc_exec_ctx *exec_ctx,
@@ -163,8 +161,6 @@
 
   GPR_ASSERT(t->ep == NULL);
 
-  gpr_slice_unref(t->optional_drop_message);
-
   gpr_slice_buffer_destroy(&t->global.qbuf);
 
   gpr_slice_buffer_destroy(&t->writing.outbuf);
@@ -266,7 +262,6 @@
       is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
   t->parsing.is_first_frame = true;
   t->writing.is_client = is_client;
-  t->optional_drop_message = gpr_empty_slice();
   grpc_connectivity_state_init(
       &t->channel_callback.state_tracker, GRPC_CHANNEL_READY,
       is_client ? "client_transport" : "server_transport");
@@ -594,6 +589,7 @@
   grpc_chttp2_incoming_metadata_buffer_destroy(
       &s->global.received_trailing_metadata);
   gpr_slice_buffer_destroy(&s->writing.flow_controlled_buffer);
+  GRPC_ERROR_UNREF(s->global.removal_error);
 
   UNREF_TRANSPORT(exec_ctx, t, "stream");
 
@@ -642,6 +638,8 @@
   grpc_chttp2_executor_action_header *hdr;
   grpc_chttp2_executor_action_header *next;
 
+  GPR_TIMER_BEGIN("finish_global_actions", 0);
+
   for (;;) {
     if (!t->executor.writing_active && !t->closed &&
         grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing)) {
@@ -659,7 +657,9 @@
           NULL;
       gpr_mu_unlock(&t->executor.mu);
       while (hdr != NULL) {
+        GPR_TIMER_BEGIN("chttp2:locked_action", 0);
         hdr->action(exec_ctx, t, hdr->stream, hdr->arg);
+        GPR_TIMER_END("chttp2:locked_action", 0);
         next = hdr->next;
         gpr_free(hdr);
         UNREF_TRANSPORT(exec_ctx, t, "pending_action");
@@ -672,6 +672,8 @@
     gpr_mu_unlock(&t->executor.mu);
     break;
   }
+
+  GPR_TIMER_END("finish_global_actions", 0);
 }
 
 void grpc_chttp2_run_with_global_lock(grpc_exec_ctx *exec_ctx,
@@ -681,6 +683,8 @@
                                       void *arg, size_t sizeof_arg) {
   grpc_chttp2_executor_action_header *hdr;
 
+  GPR_TIMER_BEGIN("grpc_chttp2_run_with_global_lock", 0);
+
   REF_TRANSPORT(t, "run_global");
   gpr_mu_lock(&t->executor.mu);
 
@@ -689,7 +693,9 @@
       t->executor.global_active = 1;
       gpr_mu_unlock(&t->executor.mu);
 
+      GPR_TIMER_BEGIN("chttp2:locked_action", 0);
       action(exec_ctx, t, optional_stream, arg);
+      GPR_TIMER_END("chttp2:locked_action", 0);
 
       finish_global_actions(exec_ctx, t);
     } else {
@@ -726,6 +732,8 @@
   }
 
   UNREF_TRANSPORT(exec_ctx, t, "run_global");
+
+  GPR_TIMER_END("grpc_chttp2_run_with_global_lock", 0);
 }
 
 /*******************************************************************************
@@ -876,7 +884,9 @@
          grpc_chttp2_list_pop_waiting_for_concurrency(transport_global,
                                                       &stream_global)) {
     cancel_from_api(exec_ctx, transport_global, stream_global,
-                    GRPC_STATUS_UNAVAILABLE, NULL);
+                    grpc_error_set_int(
+                        GRPC_ERROR_CREATE("Stream IDs exhausted"),
+                        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
   }
 }
 
@@ -958,14 +968,14 @@
     on_complete->next_data.scratch |= CLOSURE_BARRIER_STATS_BIT;
   }
 
-  if (op->cancel_with_status != GRPC_STATUS_OK) {
+  if (op->cancel_error != GRPC_ERROR_NONE) {
     cancel_from_api(exec_ctx, transport_global, stream_global,
-                    op->cancel_with_status, op->optional_close_message);
+                    GRPC_ERROR_REF(op->cancel_error));
   }
 
-  if (op->close_with_status != GRPC_STATUS_OK) {
+  if (op->close_error != GRPC_ERROR_NONE) {
     close_from_api(exec_ctx, transport_global, stream_global,
-                   op->close_with_status, op->optional_close_message);
+                   GRPC_ERROR_REF(op->close_error));
   }
 
   if (op->send_initial_metadata != NULL) {
@@ -979,12 +989,16 @@
         transport_global->settings[GRPC_PEER_SETTINGS]
                                   [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
     if (metadata_size > metadata_peer_limit) {
-      gpr_log(GPR_DEBUG,
-              "to-be-sent initial metadata size exceeds peer limit "
-              "(%" PRIuPTR " vs. %" PRIuPTR ")",
-              metadata_size, metadata_peer_limit);
-      cancel_from_api(exec_ctx, transport_global, stream_global,
-                      GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
+      cancel_from_api(
+          exec_ctx, transport_global, stream_global,
+          grpc_error_set_int(
+              grpc_error_set_int(
+                  grpc_error_set_int(
+                      GRPC_ERROR_CREATE("to-be-sent initial metadata size "
+                                        "exceeds peer limit"),
+                      GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size),
+                  GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
+              GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     } else {
       if (contains_non_ok_status(transport_global, op->send_initial_metadata)) {
         stream_global->seen_error = true;
@@ -1038,12 +1052,16 @@
         transport_global->settings[GRPC_PEER_SETTINGS]
                                   [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
     if (metadata_size > metadata_peer_limit) {
-      gpr_log(GPR_DEBUG,
-              "to-be-sent trailing metadata size exceeds peer limit "
-              "(%" PRIuPTR " vs. %" PRIuPTR ")",
-              metadata_size, metadata_peer_limit);
-      cancel_from_api(exec_ctx, transport_global, stream_global,
-                      GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
+      cancel_from_api(
+          exec_ctx, transport_global, stream_global,
+          grpc_error_set_int(
+              grpc_error_set_int(
+                  grpc_error_set_int(
+                      GRPC_ERROR_CREATE("to-be-sent trailing metadata size "
+                                        "exceeds peer limit"),
+                      GRPC_ERROR_INT_SIZE, (intptr_t)metadata_size),
+                  GRPC_ERROR_INT_LIMIT, (intptr_t)metadata_peer_limit),
+              GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
     } else {
       if (contains_non_ok_status(transport_global,
                                  op->send_trailing_metadata)) {
@@ -1235,8 +1253,12 @@
           incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
         }
         if (stream_global->exceeded_metadata_size) {
-          cancel_from_api(exec_ctx, transport_global, stream_global,
-                          GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
+          cancel_from_api(
+              exec_ctx, transport_global, stream_global,
+              grpc_error_set_int(
+                  GRPC_ERROR_CREATE(
+                      "received initial metadata size exceeds limit"),
+                  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
         }
       }
       grpc_chttp2_incoming_metadata_buffer_publish(
@@ -1275,8 +1297,12 @@
           incoming_byte_stream_destroy_locked(exec_ctx, NULL, NULL, bs);
         }
         if (stream_global->exceeded_metadata_size) {
-          cancel_from_api(exec_ctx, transport_global, stream_global,
-                          GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
+          cancel_from_api(
+              exec_ctx, transport_global, stream_global,
+              grpc_error_set_int(
+                  GRPC_ERROR_CREATE(
+                      "received trailing metadata size exceeds limit"),
+                  GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
         }
       }
       if (stream_global->all_incoming_byte_streams_finished) {
@@ -1316,15 +1342,15 @@
   }
   if (s->parsing.data_parser.parsing_frame != NULL) {
     grpc_chttp2_incoming_byte_stream_finished(
-        exec_ctx, s->parsing.data_parser.parsing_frame,
-        GRPC_ERROR_CREATE_REFERENCING("Stream removed", &error, 1), 0);
+        exec_ctx, s->parsing.data_parser.parsing_frame, GRPC_ERROR_REF(error),
+        0);
     s->parsing.data_parser.parsing_frame = NULL;
   }
 
   if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
     close_transport_locked(
-        exec_ctx, t,
-        GRPC_ERROR_CREATE("Last stream closed after sending GOAWAY"));
+        exec_ctx, t, GRPC_ERROR_CREATE_REFERENCING(
+                         "Last stream closed after sending GOAWAY", &error, 1));
   }
   if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) {
     GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing");
@@ -1340,35 +1366,67 @@
   GRPC_ERROR_UNREF(error);
 }
 
+static void status_codes_from_error(grpc_error *error,
+                                    grpc_chttp2_error_code *http2_error,
+                                    grpc_status_code *grpc_status) {
+  intptr_t ip_http;
+  intptr_t ip_grpc;
+  bool have_http =
+      grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &ip_http);
+  bool have_grpc =
+      grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &ip_grpc);
+  if (have_http) {
+    *http2_error = (grpc_chttp2_error_code)ip_http;
+  } else if (have_grpc) {
+    *http2_error =
+        grpc_chttp2_grpc_status_to_http2_error((grpc_status_code)ip_grpc);
+  } else {
+    *http2_error = GRPC_CHTTP2_INTERNAL_ERROR;
+  }
+  if (have_grpc) {
+    *grpc_status = (grpc_status_code)ip_grpc;
+  } else if (have_http) {
+    *grpc_status =
+        grpc_chttp2_http2_error_to_grpc_status((grpc_chttp2_error_code)ip_http);
+  } else {
+    *grpc_status = GRPC_STATUS_INTERNAL;
+  }
+}
+
 static void cancel_from_api(grpc_exec_ctx *exec_ctx,
                             grpc_chttp2_transport_global *transport_global,
                             grpc_chttp2_stream_global *stream_global,
-                            grpc_status_code status,
-                            gpr_slice *optional_message) {
+                            grpc_error *due_to_error) {
   if (!stream_global->read_closed || !stream_global->write_closed) {
+    grpc_status_code grpc_status;
+    grpc_chttp2_error_code http_error;
+    status_codes_from_error(due_to_error, &http_error, &grpc_status);
+
     if (stream_global->id != 0) {
       gpr_slice_buffer_add(
           &transport_global->qbuf,
-          grpc_chttp2_rst_stream_create(
-              stream_global->id,
-              (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status),
-              &stream_global->stats.outgoing));
+          grpc_chttp2_rst_stream_create(stream_global->id, (uint32_t)http_error,
+                                        &stream_global->stats.outgoing));
     }
 
-    if (optional_message) {
-      gpr_slice_ref(*optional_message);
+    const char *msg =
+        grpc_error_get_str(due_to_error, GRPC_ERROR_STR_GRPC_MESSAGE);
+    bool free_msg = false;
+    if (msg == NULL) {
+      free_msg = true;
+      msg = grpc_error_string(due_to_error);
     }
-    grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
-                            optional_message);
+    gpr_slice msg_slice = gpr_slice_from_copied_string(msg);
+    grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global,
+                            grpc_status, &msg_slice);
+    if (free_msg) grpc_error_free_string(msg);
   }
-  if (status != GRPC_STATUS_OK && !stream_global->seen_error) {
+  if (due_to_error != GRPC_ERROR_NONE && !stream_global->seen_error) {
     stream_global->seen_error = true;
     grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
   }
-  grpc_chttp2_mark_stream_closed(
-      exec_ctx, transport_global, stream_global, 1, 1,
-      grpc_error_set_int(GRPC_ERROR_CREATE("Cancelled"),
-                         GRPC_ERROR_INT_GRPC_STATUS, status));
+  grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1,
+                                 1, due_to_error);
 }
 
 void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
@@ -1451,6 +1509,7 @@
     }
   }
   if (stream_global->read_closed && stream_global->write_closed) {
+    stream_global->removal_error = GRPC_ERROR_REF(error);
     if (stream_global->id != 0 &&
         TRANSPORT_FROM_GLOBAL(transport_global)->executor.parsing_active) {
       grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global,
@@ -1469,15 +1528,17 @@
 static void close_from_api(grpc_exec_ctx *exec_ctx,
                            grpc_chttp2_transport_global *transport_global,
                            grpc_chttp2_stream_global *stream_global,
-                           grpc_status_code status,
-                           gpr_slice *optional_message) {
+                           grpc_error *error) {
   gpr_slice hdr;
   gpr_slice status_hdr;
   gpr_slice message_pfx;
   uint8_t *p;
   uint32_t len = 0;
+  grpc_status_code grpc_status;
+  grpc_chttp2_error_code http_error;
+  status_codes_from_error(error, &http_error, &grpc_status);
 
-  GPR_ASSERT(status >= 0 && (int)status < 100);
+  GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);
 
   if (stream_global->id != 0 && !transport_global->is_client) {
     /* Hand roll a header block.
@@ -1487,7 +1548,7 @@
        time we got around to sending this, so instead we ignore HPACK
        compression
        and just write the uncompressed bytes onto the wire. */
-    status_hdr = gpr_slice_malloc(15 + (status >= 10));
+    status_hdr = gpr_slice_malloc(15 + (grpc_status >= 10));
     p = GPR_SLICE_START_PTR(status_hdr);
     *p++ = 0x40; /* literal header */
     *p++ = 11;   /* len(grpc-status) */
@@ -1502,19 +1563,23 @@
     *p++ = 't';
     *p++ = 'u';
     *p++ = 's';
-    if (status < 10) {
+    if (grpc_status < 10) {
       *p++ = 1;
-      *p++ = (uint8_t)('0' + status);
+      *p++ = (uint8_t)('0' + grpc_status);
     } else {
       *p++ = 2;
-      *p++ = (uint8_t)('0' + (status / 10));
-      *p++ = (uint8_t)('0' + (status % 10));
+      *p++ = (uint8_t)('0' + (grpc_status / 10));
+      *p++ = (uint8_t)('0' + (grpc_status % 10));
     }
     GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr));
     len += (uint32_t)GPR_SLICE_LENGTH(status_hdr);
 
-    if (optional_message) {
-      GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127);
+    const char *optional_message =
+        grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
+
+    if (optional_message != NULL) {
+      size_t msg_len = strlen(optional_message);
+      GPR_ASSERT(msg_len < 127);
       message_pfx = gpr_slice_malloc(15);
       p = GPR_SLICE_START_PTR(message_pfx);
       *p++ = 0x40;
@@ -1531,10 +1596,10 @@
       *p++ = 'a';
       *p++ = 'g';
       *p++ = 'e';
-      *p++ = (uint8_t)GPR_SLICE_LENGTH(*optional_message);
+      *p++ = (uint8_t)msg_len;
       GPR_ASSERT(p == GPR_SLICE_END_PTR(message_pfx));
       len += (uint32_t)GPR_SLICE_LENGTH(message_pfx);
-      len += (uint32_t)GPR_SLICE_LENGTH(*optional_message);
+      len += (uint32_t)msg_len;
     }
 
     hdr = gpr_slice_malloc(9);
@@ -1555,7 +1620,7 @@
     if (optional_message) {
       gpr_slice_buffer_add(&transport_global->qbuf, message_pfx);
       gpr_slice_buffer_add(&transport_global->qbuf,
-                           gpr_slice_ref(*optional_message));
+                           gpr_slice_from_copied_string(optional_message));
     }
     gpr_slice_buffer_add(
         &transport_global->qbuf,
@@ -1563,43 +1628,45 @@
                                       &stream_global->stats.outgoing));
   }
 
-  if (optional_message) {
-    gpr_slice_ref(*optional_message);
+  const char *msg = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
+  bool free_msg = false;
+  if (msg == NULL) {
+    free_msg = true;
+    msg = grpc_error_string(error);
   }
-  grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
-                          optional_message);
-  grpc_error *err = GRPC_ERROR_CREATE("Stream closed");
-  err = grpc_error_set_int(err, GRPC_ERROR_INT_GRPC_STATUS, status);
-  if (optional_message) {
-    char *str =
-        gpr_dump_slice(*optional_message, GPR_DUMP_HEX | GPR_DUMP_ASCII);
-    err = grpc_error_set_str(err, GRPC_ERROR_STR_GRPC_MESSAGE, str);
-    gpr_free(str);
-  }
+  gpr_slice msg_slice = gpr_slice_from_copied_string(msg);
+  grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global,
+                          grpc_status, &msg_slice);
+  if (free_msg) grpc_error_free_string(msg);
+
   grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1,
-                                 1, err);
+                                 1, error);
 }
 
+typedef struct {
+  grpc_exec_ctx *exec_ctx;
+  grpc_error *error;
+} cancel_stream_cb_args;
+
 static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global,
                              void *user_data,
                              grpc_chttp2_stream_global *stream_global) {
-  grpc_chttp2_transport *transport = TRANSPORT_FROM_GLOBAL(transport_global);
-  cancel_from_api(user_data, transport_global, stream_global,
-                  GRPC_STATUS_UNAVAILABLE,
-                  GPR_SLICE_IS_EMPTY(transport->optional_drop_message)
-                      ? NULL
-                      : &transport->optional_drop_message);
+  cancel_stream_cb_args *args = user_data;
+  cancel_from_api(args->exec_ctx, transport_global, stream_global,
+                  GRPC_ERROR_REF(args->error));
 }
 
-static void end_all_the_calls(grpc_exec_ctx *exec_ctx,
-                              grpc_chttp2_transport *t) {
-  grpc_chttp2_for_all_streams(&t->global, exec_ctx, cancel_stream_cb);
+static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
+                              grpc_error *error) {
+  cancel_stream_cb_args args = {exec_ctx, error};
+  grpc_chttp2_for_all_streams(&t->global, &args, cancel_stream_cb);
+  GRPC_ERROR_UNREF(error);
 }
 
 static void drop_connection(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
                             grpc_error *error) {
-  close_transport_locked(exec_ctx, t, error);
-  end_all_the_calls(exec_ctx, t);
+  close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error));
+  end_all_the_calls(exec_ctx, t, error);
 }
 
 /** update window from a settings change */
@@ -1706,15 +1773,7 @@
                                          t->read_buffer.slices[i]);
   };
   if (i != t->read_buffer.count) {
-    gpr_slice_unref(t->optional_drop_message);
     errors[2] = try_http_parsing(exec_ctx, t);
-    if (errors[2] != GRPC_ERROR_NONE) {
-      t->optional_drop_message = gpr_slice_from_copied_string(
-          "Connection dropped: received http1.x response");
-    } else {
-      t->optional_drop_message = gpr_slice_from_copied_string(
-          "Connection dropped: received unparseable response");
-    }
   }
   grpc_error *err =
       errors[0] == GRPC_ERROR_NONE && errors[1] == GRPC_ERROR_NONE &&
@@ -1765,7 +1824,7 @@
     GPR_ASSERT(stream_global->write_closed);
     GPR_ASSERT(stream_global->read_closed);
     remove_stream(exec_ctx, t, stream_global->id,
-                  GRPC_ERROR_CREATE("Stream removed"));
+                  GRPC_ERROR_REF(stream_global->removal_error));
     GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2");
   }
 
@@ -1782,6 +1841,10 @@
     error = GRPC_ERROR_CREATE("Transport closed");
   }
   if (error != GRPC_ERROR_NONE) {
+    if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) {
+      error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
+                                 GRPC_STATUS_UNAVAILABLE);
+    }
     drop_connection(exec_ctx, t, GRPC_ERROR_REF(error));
     t->endpoint_reading = 0;
     if (!t->executor.writing_active && t->ep) {
@@ -1796,6 +1859,7 @@
     prevent_endpoint_shutdown(t);
   }
   gpr_slice_buffer_reset_and_unref(&t->read_buffer);
+  GRPC_ERROR_UNREF(error);
 
   if (keep_reading) {
     grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->reading_action);
@@ -1804,8 +1868,6 @@
   } else {
     UNREF_TRANSPORT(exec_ctx, t, "reading_action");
   }
-
-  GRPC_LOG_IF_ERROR("close_transport", error);
 }
 
 /*******************************************************************************
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index d63170e..b5180c6 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -384,9 +384,6 @@
 
   /** Transport op to be applied post-parsing */
   grpc_transport_op *post_parsing_op;
-
-  /** Message explaining the reason of dropping connection */
-  gpr_slice optional_drop_message;
 };
 
 typedef struct {
@@ -439,6 +436,9 @@
   bool seen_error;
   bool exceeded_metadata_size;
 
+  /** the error that resulted in this stream being removed */
+  grpc_error *removal_error;
+
   bool published_initial_metadata;
   bool published_trailing_metadata;
   bool final_metadata_requested;
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index bbba85d..42075b1 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -263,6 +263,6 @@
                                    grpc_call_element *cur_elem) {
   grpc_transport_stream_op op;
   memset(&op, 0, sizeof(op));
-  op.cancel_with_status = GRPC_STATUS_CANCELLED;
+  op.cancel_error = GRPC_ERROR_CANCELLED;
   grpc_call_next_op(exec_ctx, cur_elem, &op);
 }
diff --git a/src/core/lib/debug/trace.c b/src/core/lib/debug/trace.c
index 555f497..c560467 100644
--- a/src/core/lib/debug/trace.c
+++ b/src/core/lib/debug/trace.c
@@ -88,7 +88,11 @@
   split(s, &strings, &nstrings);
 
   for (i = 0; i < nstrings; i++) {
-    grpc_tracer_set_enabled(strings[i], 1);
+    if (strings[i][0] == '-') {
+      grpc_tracer_set_enabled(strings[i] + 1, 0);
+    } else {
+      grpc_tracer_set_enabled(strings[i], 1);
+    }
   }
 
   for (i = 0; i < nstrings; i++) {
@@ -117,7 +121,7 @@
   tracer *t;
   if (0 == strcmp(name, "all")) {
     for (t = tracers; t; t = t->next) {
-      *t->flag = 1;
+      *t->flag = enabled;
     }
   } else {
     int found = 0;
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index 540fb4f..e20a016 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -37,6 +37,7 @@
 #include <stdbool.h>
 #include <string.h>
 
+#include <grpc/status.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/avl.h>
 #include <grpc/support/log.h>
@@ -47,6 +48,8 @@
 #include <grpc/support/log_windows.h>
 #endif
 
+#include "src/core/lib/profiling/timers.h"
+
 static void destroy_integer(void *key) {}
 
 static void *copy_integer(void *key) { return key; }
@@ -115,6 +118,8 @@
       return "wsa_error";
     case GRPC_ERROR_INT_HTTP_STATUS:
       return "http_status";
+    case GRPC_ERROR_INT_LIMIT:
+      return "limit";
   }
   GPR_UNREACHABLE_CODE(return "unknown");
 }
@@ -213,6 +218,7 @@
 grpc_error *grpc_error_create(const char *file, int line, const char *desc,
                               grpc_error **referencing,
                               size_t num_referencing) {
+  GPR_TIMER_BEGIN("grpc_error_create", 0);
   grpc_error *err = gpr_malloc(sizeof(*err));
   if (err == NULL) {  // TODO(ctiller): make gpr_malloc return NULL
     return GRPC_ERROR_OOM;
@@ -238,57 +244,91 @@
                            (void *)(uintptr_t)GRPC_ERROR_TIME_CREATED,
                            box_time(gpr_now(GPR_CLOCK_REALTIME)));
   gpr_ref_init(&err->refs, 1);
+  GPR_TIMER_END("grpc_error_create", 0);
   return err;
 }
 
 static grpc_error *copy_error_and_unref(grpc_error *in) {
+  GPR_TIMER_BEGIN("copy_error_and_unref", 0);
+  grpc_error *out;
   if (is_special(in)) {
-    if (in == GRPC_ERROR_NONE) return GRPC_ERROR_CREATE("no error");
-    if (in == GRPC_ERROR_OOM) return GRPC_ERROR_CREATE("oom");
-    if (in == GRPC_ERROR_CANCELLED) return GRPC_ERROR_CREATE("cancelled");
-    return GRPC_ERROR_CREATE("unknown");
-  }
-  grpc_error *out = gpr_malloc(sizeof(*out));
+    if (in == GRPC_ERROR_NONE)
+      out = GRPC_ERROR_CREATE("no error");
+    else if (in == GRPC_ERROR_OOM)
+      out = GRPC_ERROR_CREATE("oom");
+    else if (in == GRPC_ERROR_CANCELLED)
+      out =
+          grpc_error_set_int(GRPC_ERROR_CREATE("cancelled"),
+                             GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
+    else
+      out = GRPC_ERROR_CREATE("unknown");
+  } else {
+    out = gpr_malloc(sizeof(*out));
 #ifdef GRPC_ERROR_REFCOUNT_DEBUG
-  gpr_log(GPR_DEBUG, "%p create copying", out);
+    gpr_log(GPR_DEBUG, "%p create copying", out);
 #endif
-  out->ints = gpr_avl_ref(in->ints);
-  out->strs = gpr_avl_ref(in->strs);
-  out->errs = gpr_avl_ref(in->errs);
-  out->times = gpr_avl_ref(in->times);
-  out->next_err = in->next_err;
-  gpr_ref_init(&out->refs, 1);
-  GRPC_ERROR_UNREF(in);
+    out->ints = gpr_avl_ref(in->ints);
+    out->strs = gpr_avl_ref(in->strs);
+    out->errs = gpr_avl_ref(in->errs);
+    out->times = gpr_avl_ref(in->times);
+    out->next_err = in->next_err;
+    gpr_ref_init(&out->refs, 1);
+    GRPC_ERROR_UNREF(in);
+  }
+  GPR_TIMER_END("copy_error_and_unref", 0);
   return out;
 }
 
 grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
                                intptr_t value) {
+  GPR_TIMER_BEGIN("grpc_error_set_int", 0);
   grpc_error *new = copy_error_and_unref(src);
   new->ints = gpr_avl_add(new->ints, (void *)(uintptr_t)which, (void *)value);
+  GPR_TIMER_END("grpc_error_set_int", 0);
   return new;
 }
 
 bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
+  GPR_TIMER_BEGIN("grpc_error_get_int", 0);
   void *pp;
+  if (is_special(err)) {
+    if (err == GRPC_ERROR_CANCELLED && which == GRPC_ERROR_INT_GRPC_STATUS) {
+      *p = GRPC_STATUS_CANCELLED;
+      GPR_TIMER_END("grpc_error_get_int", 0);
+      return true;
+    }
+    GPR_TIMER_END("grpc_error_get_int", 0);
+    return false;
+  }
   if (gpr_avl_maybe_get(err->ints, (void *)(uintptr_t)which, &pp)) {
     if (p != NULL) *p = (intptr_t)pp;
+    GPR_TIMER_END("grpc_error_get_int", 0);
     return true;
   }
+  GPR_TIMER_END("grpc_error_get_int", 0);
   return false;
 }
 
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
                                const char *value) {
+  GPR_TIMER_BEGIN("grpc_error_set_str", 0);
   grpc_error *new = copy_error_and_unref(src);
   new->strs =
       gpr_avl_add(new->strs, (void *)(uintptr_t)which, gpr_strdup(value));
+  GPR_TIMER_END("grpc_error_set_str", 0);
   return new;
 }
 
+const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
+  if (is_special(err)) return NULL;
+  return gpr_avl_get(err->strs, (void *)(uintptr_t)which);
+}
+
 grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
+  GPR_TIMER_BEGIN("grpc_error_add_child", 0);
   grpc_error *new = copy_error_and_unref(src);
   new->errs = gpr_avl_add(new->errs, (void *)(new->next_err++), child);
+  GPR_TIMER_END("grpc_error_add_child", 0);
   return new;
 }
 
@@ -480,6 +520,7 @@
 }
 
 const char *grpc_error_string(grpc_error *err) {
+  GPR_TIMER_BEGIN("grpc_error_string", 0);
   if (err == GRPC_ERROR_NONE) return no_error_string;
   if (err == GRPC_ERROR_OOM) return oom_error_string;
   if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string;
@@ -496,7 +537,9 @@
 
   qsort(kvs.kvs, kvs.num_kvs, sizeof(kv_pair), cmp_kvs);
 
-  return finish_kvs(&kvs);
+  const char *out = finish_kvs(&kvs);
+  GPR_TIMER_END("grpc_error_string", 0);
+  return out;
 }
 
 grpc_error *grpc_os_error(const char *file, int line, int err,
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 69cdf30..13f898e 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -92,6 +92,8 @@
   GRPC_ERROR_INT_FD,
   /// HTTP status (i.e. 404)
   GRPC_ERROR_INT_HTTP_STATUS,
+  /// context sensitive limit associated with the error
+  GRPC_ERROR_INT_LIMIT,
 } grpc_error_ints;
 
 typedef enum {
@@ -163,23 +165,25 @@
 #endif
 
 grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
-                               intptr_t value);
+                               intptr_t value) GRPC_MUST_USE_RESULT;
 bool grpc_error_get_int(grpc_error *error, grpc_error_ints which, intptr_t *p);
 grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which,
-                                gpr_timespec value);
+                                gpr_timespec value) GRPC_MUST_USE_RESULT;
 grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
-                               const char *value);
+                               const char *value) GRPC_MUST_USE_RESULT;
+const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which);
 /// Add a child error: an error that is believed to have contributed to this
 /// error occurring. Allows root causing high level errors from lower level
 /// errors that contributed to them.
-grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child);
+grpc_error *grpc_error_add_child(grpc_error *src,
+                                 grpc_error *child) GRPC_MUST_USE_RESULT;
 grpc_error *grpc_os_error(const char *file, int line, int err,
-                          const char *call_name);
+                          const char *call_name) GRPC_MUST_USE_RESULT;
 /// create an error associated with errno!=0 (an 'operating system' error)
 #define GRPC_OS_ERROR(err, call_name) \
   grpc_os_error(__FILE__, __LINE__, err, call_name)
 grpc_error *grpc_wsa_error(const char *file, int line, int err,
-                           const char *call_name);
+                           const char *call_name) GRPC_MUST_USE_RESULT;
 /// windows only: create an error associated with WSAGetLastError()!=0
 #define GRPC_WSA_ERROR(err, call_name) \
   grpc_wsa_error(__FILE__, __LINE__, err, call_name)
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 5460d72..cf0fe73 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -60,6 +60,13 @@
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/support/block_annotate.h"
 
+/* TODO: sreek - Move this to init.c and initialize this like other tracers. */
+static int grpc_polling_trace = 0; /* Disabled by default */
+#define GRPC_POLLING_TRACE(fmt, ...)       \
+  if (grpc_polling_trace) {                \
+    gpr_log(GPR_INFO, (fmt), __VA_ARGS__); \
+  }
+
 static int grpc_wakeup_signal = -1;
 static bool is_grpc_wakeup_signal_initialized = false;
 
@@ -195,7 +202,11 @@
  * Pollset Declarations
  */
 struct grpc_pollset_worker {
-  pthread_t pt_id; /* Thread id of this worker */
+  /* Thread id of this worker */
+  pthread_t pt_id;
+
+  /* Used to prevent a worker from getting kicked multiple times */
+  gpr_atm is_kicked;
   struct grpc_pollset_worker *next;
   struct grpc_pollset_worker *prev;
 };
@@ -1031,6 +1042,8 @@
  */
 GPR_TLS_DECL(g_current_thread_pollset);
 GPR_TLS_DECL(g_current_thread_worker);
+static __thread bool g_initialized_sigmask;
+static __thread sigset_t g_orig_sigmask;
 
 static void sig_handler(int sig_num) {
 #ifdef GRPC_EPOLL_DEBUG
@@ -1056,9 +1069,16 @@
 
 static grpc_error *pollset_worker_kick(grpc_pollset_worker *worker) {
   grpc_error *err = GRPC_ERROR_NONE;
-  int err_num = pthread_kill(worker->pt_id, grpc_wakeup_signal);
-  if (err_num != 0) {
-    err = GRPC_OS_ERROR(err_num, "pthread_kill");
+
+  /* Kick the worker only if it was not already kicked */
+  if (gpr_atm_no_barrier_cas(&worker->is_kicked, (gpr_atm)0, (gpr_atm)1)) {
+    GRPC_POLLING_TRACE(
+        "pollset_worker_kick: Kicking worker: %p (thread id: %ld)",
+        (void *)worker, worker->pt_id);
+    int err_num = pthread_kill(worker->pt_id, grpc_wakeup_signal);
+    if (err_num != 0) {
+      err = GRPC_OS_ERROR(err_num, "pthread_kill");
+    }
   }
   return err;
 }
@@ -1102,7 +1122,6 @@
   GPR_TIMER_BEGIN("pollset_kick", 0);
   grpc_error *error = GRPC_ERROR_NONE;
   const char *err_desc = "Kick Failure";
-
   grpc_pollset_worker *worker = specific_worker;
   if (worker != NULL) {
     if (worker == GRPC_POLLSET_KICK_BROADCAST) {
@@ -1268,7 +1287,8 @@
 #define GRPC_EPOLL_MAX_EVENTS 1000
 /* Note: sig_mask contains the signal mask to use *during* epoll_wait() */
 static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
-                                    grpc_pollset *pollset, int timeout_ms,
+                                    grpc_pollset *pollset,
+                                    grpc_pollset_worker *worker, int timeout_ms,
                                     sigset_t *sig_mask, grpc_error **error) {
   struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS];
   int epoll_fd = -1;
@@ -1296,6 +1316,8 @@
     }
 
     PI_ADD_REF(pollset->polling_island, "ps");
+    GRPC_POLLING_TRACE("pollset_work: pollset: %p created new pi: %p",
+                       (void *)pollset, (void *)pollset->polling_island);
   }
 
   pi = polling_island_maybe_get_latest(pollset->polling_island);
@@ -1329,6 +1351,9 @@
       } else {
         /* We were interrupted. Save an interation by doing a zero timeout
            epoll_wait to see if there are any other events of interest */
+        GRPC_POLLING_TRACE(
+            "pollset_work: pollset: %p, worker: %p received kick",
+            (void *)pollset, (void *)worker);
         ep_rv = epoll_wait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0);
       }
     }
@@ -1345,6 +1370,10 @@
                      grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd),
                      err_desc);
       } else if (data_ptr == &polling_island_wakeup_fd) {
+        GRPC_POLLING_TRACE(
+            "pollset_work: pollset: %p, worker: %p polling island (epoll_fd: "
+            "%d) got merged",
+            (void *)pollset, (void *)worker, epoll_fd);
         /* This means that our polling island is merged with a different
            island. We do not have to do anything here since the subsequent call
            to the function pollset_work_and_unlock() will pick up the correct
@@ -1388,11 +1417,11 @@
   int timeout_ms = poll_deadline_to_millis_timeout(deadline, now);
 
   sigset_t new_mask;
-  sigset_t orig_mask;
 
   grpc_pollset_worker worker;
   worker.next = worker.prev = NULL;
   worker.pt_id = pthread_self();
+  gpr_atm_no_barrier_store(&worker.is_kicked, (gpr_atm)0);
 
   *worker_hdl = &worker;
 
@@ -1408,39 +1437,49 @@
     pollset->kicked_without_pollers = 0;
   } else if (!pollset->shutting_down) {
     /* We use the posix-signal with number 'grpc_wakeup_signal' for waking up
-       (i.e 'kicking') a worker in the pollset.
-       A 'kick' is a way to inform that worker that there is some pending work
-       that needs immediate attention (like an event on the completion queue,
-       or a polling island merge that results in a new epoll-fd to wait on) and
-       that the worker should not spend time waiting in epoll_pwait().
+       (i.e 'kicking') a worker in the pollset. A 'kick' is a way to inform the
+       worker that there is some pending work that needs immediate attention
+       (like an event on the completion queue, or a polling island merge that
+       results in a new epoll-fd to wait on) and that the worker should not
+       spend time waiting in epoll_pwait().
 
-       A kick can come at anytime (i.e before/during or after the worker calls
-       epoll_pwait()) but in all cases we have to make sure that when a worker
-       gets a kick, it does not spend time in epoll_pwait(). In other words, one
-       kick should result in skipping/exiting of one epoll_pwait();
+       A worker can be kicked anytime from the point it is added to the pollset
+       via push_front_worker() (or push_back_worker()) to the point it is
+       removed via remove_worker().
+       If the worker is kicked before/during it calls epoll_pwait(), it should
+       immediately exit from epoll_wait(). If the worker is kicked after it
+       returns from epoll_wait(), then nothing really needs to be done.
 
-       To accomplish this, we mask 'grpc_wakeup_signal' on this worker at all
+       To accomplish this, we mask 'grpc_wakeup_signal' on this thread at all
        times *except* when it is in epoll_pwait(). This way, the worker never
        misses acting on a kick */
 
-    sigemptyset(&new_mask);
-    sigaddset(&new_mask, grpc_wakeup_signal);
-    pthread_sigmask(SIG_BLOCK, &new_mask, &orig_mask);
-    sigdelset(&orig_mask, grpc_wakeup_signal);
-    /* new_mask:  The new thread mask which blocks 'grpc_wakeup_signal'. This is
-                  the mask used at all times *except during epoll_wait()*"
-       orig_mask: The thread mask which allows 'grpc_wakeup_signal' and this is
-                  the mask to use *during epoll_wait()*
+    if (!g_initialized_sigmask) {
+      sigemptyset(&new_mask);
+      sigaddset(&new_mask, grpc_wakeup_signal);
+      pthread_sigmask(SIG_BLOCK, &new_mask, &g_orig_sigmask);
+      sigdelset(&g_orig_sigmask, grpc_wakeup_signal);
+      g_initialized_sigmask = true;
+      /* new_mask:       The new thread mask which blocks 'grpc_wakeup_signal'.
+                         This is the mask used at all times *except during
+                         epoll_wait()*"
+         g_orig_sigmask: The thread mask which allows 'grpc_wakeup_signal' and
+                         this is the mask to use *during epoll_wait()*
 
-       The new_mask is set on the worker before it is added to the pollset (i.e
-       before it can be kicked) */
+         The new_mask is set on the worker before it is added to the pollset
+         (i.e before it can be kicked) */
+    }
 
     push_front_worker(pollset, &worker); /* Add worker to pollset */
 
-    pollset_work_and_unlock(exec_ctx, pollset, timeout_ms, &orig_mask, &error);
+    pollset_work_and_unlock(exec_ctx, pollset, &worker, timeout_ms,
+                            &g_orig_sigmask, &error);
     grpc_exec_ctx_flush(exec_ctx);
 
     gpr_mu_lock(&pollset->mu);
+
+    /* Note: There is no need to reset worker.is_kicked to 0 since we are no
+       longer going to use this worker */
     remove_worker(pollset, &worker);
   }
 
@@ -1500,17 +1539,38 @@
     pi_new = fd->polling_island;
     if (pi_new == NULL) {
       pi_new = polling_island_create(fd, &error);
+
+      GRPC_POLLING_TRACE(
+          "pollset_add_fd: Created new polling island. pi_new: %p (fd: %d, "
+          "pollset: %p)",
+          (void *)pi_new, fd->fd, (void *)pollset);
     }
   } else if (fd->polling_island == NULL) {
     pi_new = polling_island_lock(pollset->polling_island);
     polling_island_add_fds_locked(pi_new, &fd, 1, true, &error);
     gpr_mu_unlock(&pi_new->mu);
+
+    GRPC_POLLING_TRACE(
+        "pollset_add_fd: fd->pi was NULL. pi_new: %p (fd: %d, pollset: %p, "
+        "pollset->pi: %p)",
+        (void *)pi_new, fd->fd, (void *)pollset,
+        (void *)pollset->polling_island);
   } else if (pollset->polling_island == NULL) {
     pi_new = polling_island_lock(fd->polling_island);
     gpr_mu_unlock(&pi_new->mu);
+
+    GRPC_POLLING_TRACE(
+        "pollset_add_fd: pollset->pi was NULL. pi_new: %p (fd: %d, pollset: "
+        "%p, fd->pi: %p",
+        (void *)pi_new, fd->fd, (void *)pollset, (void *)fd->polling_island);
   } else {
     pi_new = polling_island_merge(fd->polling_island, pollset->polling_island,
                                   &error);
+    GRPC_POLLING_TRACE(
+        "pollset_add_fd: polling islands merged. pi_new: %p (fd: %d, pollset: "
+        "%p, fd->pi: %p, pollset->pi: %p)",
+        (void *)pi_new, fd->fd, (void *)pollset, (void *)fd->polling_island,
+        (void *)pollset->polling_island);
   }
 
   /* At this point, pi_new is the polling island that both fd->polling_island
diff --git a/src/core/lib/iomgr/wakeup_fd_eventfd.c b/src/core/lib/iomgr/wakeup_fd_eventfd.c
index 667b4a5..95f6102 100644
--- a/src/core/lib/iomgr/wakeup_fd_eventfd.c
+++ b/src/core/lib/iomgr/wakeup_fd_eventfd.c
@@ -84,8 +84,10 @@
 }
 
 static int eventfd_check_availability(void) {
-  /* TODO(klempner): Actually check if eventfd is available */
-  return 1;
+  const int efd = eventfd(0, 0);
+  const int is_available = efd >= 0;
+  if (is_available) close(efd);
+  return is_available;
 }
 
 const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable = {
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 399b92c..14ccf72 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -224,8 +224,7 @@
   grpc_linked_mdelem *l;
   grpc_client_security_context *sec_ctx = NULL;
 
-  if (calld->security_context_set == 0 &&
-      op->cancel_with_status == GRPC_STATUS_OK) {
+  if (calld->security_context_set == 0 && op->cancel_error == GRPC_ERROR_NONE) {
     calld->security_context_set = 1;
     GPR_ASSERT(op->context);
     if (op->context[GRPC_CONTEXT_SECURITY].value == NULL) {
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 04291b0..708ea35 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -402,8 +402,51 @@
 
   call->status[source].is_set = 1;
   call->status[source].code = (grpc_status_code)status;
+}
 
-  /* TODO(ctiller): what to do about the flush that was previously here */
+static void set_status_details(grpc_call *call, status_source source,
+                               grpc_mdstr *status) {
+  if (call->status[source].details != NULL) {
+    GRPC_MDSTR_UNREF(status);
+  } else {
+    call->status[source].details = status;
+  }
+}
+
+static void get_final_status(grpc_call *call,
+                             void (*set_value)(grpc_status_code code,
+                                               void *user_data),
+                             void *set_value_user_data) {
+  int i;
+  for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
+    if (call->status[i].is_set) {
+      set_value(call->status[i].code, set_value_user_data);
+      return;
+    }
+  }
+  if (call->is_client) {
+    set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
+  } else {
+    set_value(GRPC_STATUS_OK, set_value_user_data);
+  }
+}
+
+static void set_status_from_error(grpc_call *call, status_source source,
+                                  grpc_error *error) {
+  intptr_t status;
+  if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) {
+    set_status_code(call, source, (uint32_t)status);
+  } else {
+    set_status_code(call, source, GRPC_STATUS_INTERNAL);
+  }
+  const char *msg = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE);
+  bool free_msg = false;
+  if (msg == NULL) {
+    free_msg = true;
+    msg = grpc_error_string(error);
+  }
+  set_status_details(call, source, grpc_mdstr_from_string(msg));
+  if (free_msg) grpc_error_free_string(msg);
 }
 
 static void set_incoming_compression_algorithm(
@@ -492,32 +535,6 @@
   return encodings_accepted_by_peer;
 }
 
-static void set_status_details(grpc_call *call, status_source source,
-                               grpc_mdstr *status) {
-  if (call->status[source].details != NULL) {
-    GRPC_MDSTR_UNREF(call->status[source].details);
-  }
-  call->status[source].details = status;
-}
-
-static void get_final_status(grpc_call *call,
-                             void (*set_value)(grpc_status_code code,
-                                               void *user_data),
-                             void *set_value_user_data) {
-  int i;
-  for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
-    if (call->status[i].is_set) {
-      set_value(call->status[i].code, set_value_user_data);
-      return;
-    }
-  }
-  if (call->is_client) {
-    set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
-  } else {
-    set_value(GRPC_STATUS_OK, set_value_user_data);
-  }
-}
-
 static void get_final_details(grpc_call *call, char **out_details,
                               size_t *out_details_capacity) {
   int i;
@@ -741,8 +758,7 @@
 typedef struct termination_closure {
   grpc_closure closure;
   grpc_call *call;
-  grpc_status_code status;
-  gpr_slice optional_message;
+  grpc_error *error;
   grpc_closure *op_closure;
   enum { TC_CANCEL, TC_CLOSE } type;
 } termination_closure;
@@ -758,7 +774,7 @@
       GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "close");
       break;
   }
-  gpr_slice_unref(tc->optional_message);
+  GRPC_ERROR_UNREF(tc->error);
   grpc_exec_ctx_sched(exec_ctx, tc->op_closure, GRPC_ERROR_NONE, NULL);
   gpr_free(tc);
 }
@@ -767,7 +783,7 @@
   grpc_transport_stream_op op;
   termination_closure *tc = tcp;
   memset(&op, 0, sizeof(op));
-  op.cancel_with_status = tc->status;
+  op.cancel_error = tc->error;
   /* reuse closure to catch completion */
   grpc_closure_init(&tc->closure, done_termination, tc);
   op.on_complete = &tc->closure;
@@ -778,8 +794,7 @@
   grpc_transport_stream_op op;
   termination_closure *tc = tcp;
   memset(&op, 0, sizeof(op));
-  tc->optional_message = gpr_slice_ref(tc->optional_message);
-  grpc_transport_stream_op_add_close(&op, tc->status, &tc->optional_message);
+  op.close_error = tc->error;
   /* reuse closure to catch completion */
   grpc_closure_init(&tc->closure, done_termination, tc);
   tc->op_closure = op.on_complete;
@@ -789,14 +804,7 @@
 
 static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
                                              termination_closure *tc) {
-  grpc_mdstr *details = NULL;
-  if (GPR_SLICE_LENGTH(tc->optional_message) > 0) {
-    tc->optional_message = gpr_slice_ref(tc->optional_message);
-    details = grpc_mdstr_from_slice(tc->optional_message);
-  }
-
-  set_status_code(tc->call, STATUS_FROM_API_OVERRIDE, (uint32_t)tc->status);
-  set_status_details(tc->call, STATUS_FROM_API_OVERRIDE, details);
+  set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
 
   if (tc->type == TC_CANCEL) {
     grpc_closure_init(&tc->closure, send_cancel, tc);
@@ -812,13 +820,15 @@
 static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
                                           grpc_status_code status,
                                           const char *description) {
+  GPR_ASSERT(status != GRPC_STATUS_OK);
   termination_closure *tc = gpr_malloc(sizeof(*tc));
   memset(tc, 0, sizeof(termination_closure));
   tc->type = TC_CANCEL;
   tc->call = c;
-  tc->optional_message = gpr_slice_from_copied_string(description);
-  GPR_ASSERT(status != GRPC_STATUS_OK);
-  tc->status = status;
+  tc->error = grpc_error_set_int(
+      grpc_error_set_str(GRPC_ERROR_CREATE(description),
+                         GRPC_ERROR_STR_GRPC_MESSAGE, description),
+      GRPC_ERROR_INT_GRPC_STATUS, status);
 
   return terminate_with_status(exec_ctx, tc);
 }
@@ -826,13 +836,15 @@
 static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
                                          grpc_status_code status,
                                          const char *description) {
+  GPR_ASSERT(status != GRPC_STATUS_OK);
   termination_closure *tc = gpr_malloc(sizeof(*tc));
   memset(tc, 0, sizeof(termination_closure));
   tc->type = TC_CLOSE;
   tc->call = c;
-  tc->optional_message = gpr_slice_from_copied_string(description);
-  GPR_ASSERT(status != GRPC_STATUS_OK);
-  tc->status = status;
+  tc->error = grpc_error_set_int(
+      grpc_error_set_str(GRPC_ERROR_CREATE(description),
+                         GRPC_ERROR_STR_GRPC_MESSAGE, description),
+      GRPC_ERROR_INT_GRPC_STATUS, status);
 
   return terminate_with_status(exec_ctx, tc);
 }
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index b640345..3a78fe3 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -37,7 +37,6 @@
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/context.h"
 #include "src/core/lib/surface/api_trace.h"
-#include "src/core/lib/surface/surface_trace.h"
 
 #include <grpc/grpc.h>
 #include <grpc/impl/codegen/compression_types.h>
diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c
index b5f2f65..5978884 100644
--- a/src/core/lib/surface/completion_queue.c
+++ b/src/core/lib/surface/completion_queue.c
@@ -48,7 +48,6 @@
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/event_string.h"
-#include "src/core/lib/surface/surface_trace.h"
 
 int grpc_trace_operation_failures;
 
@@ -93,6 +92,17 @@
 static gpr_mu g_freelist_mu;
 static grpc_completion_queue *g_freelist;
 
+int grpc_cq_pluck_trace;
+int grpc_cq_event_timeout_trace;
+
+#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event)                  \
+  if (grpc_api_trace &&                                               \
+      (grpc_cq_pluck_trace || (event)->type != GRPC_QUEUE_TIMEOUT)) { \
+    char *_ev = grpc_event_string(event);                             \
+    gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev);               \
+    gpr_free(_ev);                                                    \
+  }
+
 static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc,
                                      grpc_error *error);
 
@@ -240,7 +250,7 @@
         "grpc_cq_end_op(exec_ctx=%p, cc=%p, tag=%p, error=%s, done=%p, "
         "done_arg=%p, storage=%p)",
         7, (exec_ctx, cc, tag, errmsg, done, done_arg, storage));
-    if (grpc_trace_operation_failures) {
+    if (grpc_trace_operation_failures && error != GRPC_ERROR_NONE) {
       gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
     }
     grpc_error_free_string(errmsg);
@@ -426,14 +436,16 @@
 
   GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0);
 
-  GRPC_API_TRACE(
-      "grpc_completion_queue_pluck("
-      "cc=%p, tag=%p, "
-      "deadline=gpr_timespec { tv_sec: %" PRId64
-      ", tv_nsec: %d, clock_type: %d }, "
-      "reserved=%p)",
-      6, (cc, tag, deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
-          reserved));
+  if (grpc_cq_pluck_trace) {
+    GRPC_API_TRACE(
+        "grpc_completion_queue_pluck("
+        "cc=%p, tag=%p, "
+        "deadline=gpr_timespec { tv_sec: %" PRId64
+        ", tv_nsec: %d, clock_type: %d }, "
+        "reserved=%p)",
+        6, (cc, tag, deadline.tv_sec, deadline.tv_nsec,
+            (int)deadline.clock_type, reserved));
+  }
   GPR_ASSERT(!reserved);
 
   deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h
index b9dd109..3049284 100644
--- a/src/core/lib/surface/completion_queue.h
+++ b/src/core/lib/surface/completion_queue.h
@@ -39,6 +39,10 @@
 #include <grpc/grpc.h>
 #include "src/core/lib/iomgr/pollset.h"
 
+/* These trace flags default to 1. The corresponding lines are only traced
+   if grpc_api_trace is also truthy */
+extern int grpc_cq_pluck_trace;
+extern int grpc_cq_event_timeout_trace;
 extern int grpc_trace_operation_failures;
 
 typedef struct grpc_cq_completion {
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index f07039c..5397913 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -57,7 +57,6 @@
 #include "src/core/lib/surface/init.h"
 #include "src/core/lib/surface/lame_client.h"
 #include "src/core/lib/surface/server.h"
-#include "src/core/lib/surface/surface_trace.h"
 #include "src/core/lib/transport/connectivity_state.h"
 #include "src/core/lib/transport/transport_impl.h"
 
@@ -165,6 +164,12 @@
                          &grpc_trace_channel_stack_builder);
     grpc_register_tracer("http1", &grpc_http1_trace);
     grpc_register_tracer("compression", &grpc_compression_trace);
+    grpc_register_tracer("queue_pluck", &grpc_cq_pluck_trace);
+    // Default pluck trace to 1
+    grpc_cq_pluck_trace = 1;
+    grpc_register_tracer("queue_timeout", &grpc_cq_event_timeout_trace);
+    // Default timeout trace to 1
+    grpc_cq_event_timeout_trace = 1;
     grpc_register_tracer("op_failure", &grpc_trace_operation_failures);
     grpc_security_pre_init();
     grpc_iomgr_init();
diff --git a/src/core/lib/surface/surface_trace.h b/src/core/lib/surface/surface_trace.h
deleted file mode 100644
index a69a0ff..0000000
--- a/src/core/lib/surface/surface_trace.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H
-#define GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H
-
-#include <grpc/support/log.h>
-#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/surface/api_trace.h"
-
-#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event)    \
-  if (grpc_api_trace) {                                 \
-    char *_ev = grpc_event_string(event);               \
-    gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
-    gpr_free(_ev);                                      \
-  }
-
-#endif /* GRPC_CORE_LIB_SURFACE_SURFACE_TRACE_H */
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index 1105494..79a20e1 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -36,6 +36,7 @@
 #include <grpc/support/atm.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
+#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/transport_impl.h"
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -162,55 +163,63 @@
   grpc_exec_ctx_sched(exec_ctx, op->on_complete, error, NULL);
 }
 
-void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
-                                               grpc_status_code status) {
-  GPR_ASSERT(status != GRPC_STATUS_OK);
-  if (op->cancel_with_status == GRPC_STATUS_OK) {
-    op->cancel_with_status = status;
-  }
-  if (op->close_with_status != GRPC_STATUS_OK) {
-    op->close_with_status = GRPC_STATUS_OK;
-    if (op->optional_close_message != NULL) {
-      gpr_slice_unref(*op->optional_close_message);
-      op->optional_close_message = NULL;
-    }
-  }
-}
-
 typedef struct {
-  gpr_slice message;
+  grpc_error *error;
   grpc_closure *then_call;
   grpc_closure closure;
 } close_message_data;
 
 static void free_message(grpc_exec_ctx *exec_ctx, void *p, grpc_error *error) {
   close_message_data *cmd = p;
-  gpr_slice_unref(cmd->message);
+  GRPC_ERROR_UNREF(cmd->error);
   if (cmd->then_call != NULL) {
     cmd->then_call->cb(exec_ctx, cmd->then_call->cb_arg, GRPC_ERROR_REF(error));
   }
   gpr_free(cmd);
 }
 
+static void add_error(grpc_transport_stream_op *op, grpc_error **which,
+                      grpc_error *error) {
+  close_message_data *cmd;
+  cmd = gpr_malloc(sizeof(*cmd));
+  cmd->error = error;
+  cmd->then_call = op->on_complete;
+  grpc_closure_init(&cmd->closure, free_message, cmd);
+  op->on_complete = &cmd->closure;
+  *which = error;
+}
+
+void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
+                                               grpc_status_code status) {
+  GPR_ASSERT(status != GRPC_STATUS_OK);
+  if (op->cancel_error == GRPC_ERROR_NONE) {
+    op->cancel_error = grpc_error_set_int(GRPC_ERROR_CANCELLED,
+                                          GRPC_ERROR_INT_GRPC_STATUS, status);
+    op->close_error = GRPC_ERROR_NONE;
+  }
+}
+
 void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
                                         grpc_status_code status,
                                         gpr_slice *optional_message) {
-  close_message_data *cmd;
   GPR_ASSERT(status != GRPC_STATUS_OK);
-  if (op->cancel_with_status != GRPC_STATUS_OK ||
-      op->close_with_status != GRPC_STATUS_OK) {
+  if (op->cancel_error != GRPC_ERROR_NONE ||
+      op->close_error != GRPC_ERROR_NONE) {
     if (optional_message) {
       gpr_slice_unref(*optional_message);
     }
     return;
   }
-  if (optional_message) {
-    cmd = gpr_malloc(sizeof(*cmd));
-    cmd->message = *optional_message;
-    cmd->then_call = op->on_complete;
-    grpc_closure_init(&cmd->closure, free_message, cmd);
-    op->on_complete = &cmd->closure;
-    op->optional_close_message = &cmd->message;
+  grpc_error *error;
+  if (optional_message != NULL) {
+    char *msg = gpr_dump_slice(*optional_message, GPR_DUMP_ASCII);
+    error = grpc_error_set_str(GRPC_ERROR_CREATE(msg),
+                               GRPC_ERROR_STR_GRPC_MESSAGE, msg);
+    gpr_free(msg);
+    gpr_slice_unref(*optional_message);
+  } else {
+    error = GRPC_ERROR_CREATE("Call force closed");
   }
-  op->close_with_status = status;
+  error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, status);
+  add_error(op, &op->close_error, error);
 }
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index a46ccb6..d2f6344 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -135,13 +135,12 @@
   /** Collect any stats into provided buffer, zero internal stat counters */
   grpc_transport_stream_stats *collect_stats;
 
-  /** If != GRPC_STATUS_OK, cancel this stream */
-  grpc_status_code cancel_with_status;
+  /** If != GRPC_ERROR_NONE, cancel this stream */
+  grpc_error *cancel_error;
 
-  /** If != GRPC_STATUS_OK, send grpc-status, grpc-message, and close this
+  /** If != GRPC_ERROR, send grpc-status, grpc-message, and close this
       stream for both reading and writing */
-  grpc_status_code close_with_status;
-  gpr_slice *optional_close_message;
+  grpc_error *close_error;
 
   /* Indexes correspond to grpc_context_index enum values */
   grpc_call_context_element *context;
diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c
index aeaba53..138591d 100644
--- a/src/core/lib/transport/transport_op_string.c
+++ b/src/core/lib/transport/transport_op_string.c
@@ -119,10 +119,21 @@
     gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA"));
   }
 
-  if (op->cancel_with_status != GRPC_STATUS_OK) {
+  if (op->cancel_error != GRPC_ERROR_NONE) {
     if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
     first = 0;
-    gpr_asprintf(&tmp, "CANCEL:%d", op->cancel_with_status);
+    const char *msg = grpc_error_string(op->cancel_error);
+    gpr_asprintf(&tmp, "CANCEL:%s", msg);
+    grpc_error_free_string(msg);
+    gpr_strvec_add(&b, tmp);
+  }
+
+  if (op->close_error != GRPC_ERROR_NONE) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    const char *msg = grpc_error_string(op->close_error);
+    gpr_asprintf(&tmp, "CLOSE:%s", msg);
+    grpc_error_free_string(msg);
     gpr_strvec_add(&b, tmp);
   }
 
diff --git a/src/cpp/README.md b/src/cpp/README.md
index f2935e5..8c0f85e 100644
--- a/src/cpp/README.md
+++ b/src/cpp/README.md
@@ -51,7 +51,7 @@
 #Build from Source
 
 ```sh
- $ git clone https://github.com/grpc/grpc.git
+ $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
  $ cd grpc
  $ git submodule update --init
  $ make
diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json
index 4c5c960..72c258a 100644
--- a/src/csharp/Grpc.Auth/project.json
+++ b/src/csharp/Grpc.Auth/project.json
@@ -12,6 +12,15 @@
     "requireLicenseAcceptance": false,
     "tags": [ "gRPC RPC Protocol HTTP/2 Auth OAuth2" ],
   },
+  "buildOptions": {
+    "define": [ "SIGNED" ],
+    "keyFile": "../keys/Grpc.snk",
+    "publicSign": true,
+    "xmlDoc": true,
+    "compile": {
+      "includeFiles": [ "../Grpc.Core/Version.cs" ]
+    }
+  },
   "dependencies": {
     "Grpc.Core": "0.16.0-dev",
     "Google.Apis.Auth": "1.11.1"
diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json
index 3ad081d..f58bcbb 100644
--- a/src/csharp/Grpc.Core.Tests/project.json
+++ b/src/csharp/Grpc.Core.Tests/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
@@ -17,6 +24,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json
index 4729a93..201e548 100644
--- a/src/csharp/Grpc.Core/project.json
+++ b/src/csharp/Grpc.Core/project.json
@@ -12,17 +12,23 @@
     "requireLicenseAcceptance": false,
     "tags": [ "gRPC RPC Protocol HTTP/2" ],
     "files": {
-      "build/net45/": "Grpc.Core.targets",
-      "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll",
-      "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll",
-      "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so",
-      "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so",
-      "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib",
-      "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib"
+      "mappings": {
+        "build/net45/": "Grpc.Core.targets",
+        "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll",
+        "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll",
+        "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so",
+        "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so",
+        "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib",
+        "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib"
+      }
     }
   },
   "buildOptions": {
-    "embed": [ "../../../etc/roots.pem" ]
+    "embed": [ "../../../etc/roots.pem" ],
+    "define": [ "SIGNED" ],
+    "keyFile": "../keys/Grpc.snk",
+    "publicSign": true,
+    "xmlDoc": true
   },
   "dependencies": {
     "Ix-Async": "1.2.5"
diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json
index b254f15..b865cd5 100644
--- a/src/csharp/Grpc.Examples.MathClient/project.json
+++ b/src/csharp/Grpc.Examples.MathClient/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
@@ -17,6 +24,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json
index b254f15..b865cd5 100644
--- a/src/csharp/Grpc.Examples.MathServer/project.json
+++ b/src/csharp/Grpc.Examples.MathServer/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
@@ -17,6 +24,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json
index d2779e8..cc518eb 100644
--- a/src/csharp/Grpc.Examples.Tests/project.json
+++ b/src/csharp/Grpc.Examples.Tests/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
@@ -17,6 +24,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json
index 74599bd..fbf8d92 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/project.json
+++ b/src/csharp/Grpc.HealthCheck.Tests/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
@@ -17,6 +24,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "mappings": {
             "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json
index c4895c2..d9daef7 100644
--- a/src/csharp/Grpc.HealthCheck/project.json
+++ b/src/csharp/Grpc.HealthCheck/project.json
@@ -12,6 +12,15 @@
     "requireLicenseAcceptance": false,
     "tags": [ "gRPC health check" ]
   },
+  "buildOptions": {
+    "define": [ "SIGNED" ],
+    "keyFile": "../keys/Grpc.snk",
+    "publicSign": true,
+    "xmlDoc": true,
+    "compile": {
+      "includeFiles": [ "../Grpc.Core/Version.cs" ]
+    }
+  },
   "dependencies": {
     "Grpc.Core": "0.16.0-dev",
     "Google.Protobuf": "3.0.0-beta3"
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json
index e5ba04d..4a2846f 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
@@ -18,6 +25,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
index e5ba04d..4a2846f 100644
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
@@ -18,6 +25,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json
index e5ba04d..4a2846f 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
@@ -18,6 +25,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
index e5ba04d..4a2846f 100644
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
@@ -18,6 +25,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json
index 3493ab0..6297600 100644
--- a/src/csharp/Grpc.IntegrationTesting/project.json
+++ b/src/csharp/Grpc.IntegrationTesting/project.json
@@ -5,6 +5,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
@@ -18,6 +25,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           "include": "data/*",
           "mappings": {
diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js
index 794215b..0a21572 100644
--- a/src/node/test/credentials_test.js
+++ b/src/node/test/credentials_test.js
@@ -318,7 +318,7 @@
       done();
     });
   });
-  it.skip('should propagate errors that the updater emits', function(done) {
+  it('should propagate errors that the updater emits', function(done) {
     var metadataUpdater = function(service_url, callback) {
       var error = new Error('Authentication error');
       error.code = grpc.status.UNAUTHENTICATED;
@@ -370,7 +370,7 @@
       done();
     });
   });
-  it.skip('should get an error from a Google credential', function(done) {
+  it('should get an error from a Google credential', function(done) {
     var creds = grpc.credentials.createFromGoogleCredential(
         fakeFailingGoogleCredentials);
     var combined_creds = grpc.credentials.combineChannelCredentials(
diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m
index 9740190..3487fac 100644
--- a/src/objective-c/ProtoRPC/ProtoService.m
+++ b/src/objective-c/ProtoRPC/ProtoService.m
@@ -65,18 +65,18 @@
   return self;
 }
 
-- (ProtoRPC *)RPCToMethod:(NSString *)method
-           requestsWriter:(GRXWriter *)requestsWriter
-            responseClass:(Class)responseClass
-       responsesWriteable:(id<GRXWriteable>)responsesWriteable {
+- (GRPCProtoCall *)RPCToMethod:(NSString *)method
+                requestsWriter:(GRXWriter *)requestsWriter
+                 responseClass:(Class)responseClass
+            responsesWriteable:(id<GRXWriteable>)responsesWriteable {
   GRPCProtoMethod *methodName = [[GRPCProtoMethod alloc] initWithPackage:_packageName
                                                                  service:_serviceName
                                                                   method:method];
-  return [[ProtoRPC alloc] initWithHost:_host
-                                 method:methodName
-                         requestsWriter:requestsWriter
-                          responseClass:responseClass
-                     responsesWriteable:responsesWriteable];
+  return [[GRPCProtoCall alloc] initWithHost:_host
+                                      method:methodName
+                              requestsWriter:requestsWriter
+                               responseClass:responseClass
+                          responsesWriteable:responsesWriteable];
 }
 @end
 
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme b/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme
new file mode 100644
index 0000000..d399e22
--- /dev/null
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0730"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "6369A2691A9322E20015FC5C"
+               BuildableName = "Sample.app"
+               BlueprintName = "Sample"
+               ReferencedContainer = "container:Sample.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "6369A2691A9322E20015FC5C"
+            BuildableName = "Sample.app"
+            BlueprintName = "Sample"
+            ReferencedContainer = "container:Sample.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "6369A2691A9322E20015FC5C"
+            BuildableName = "Sample.app"
+            BlueprintName = "Sample"
+            ReferencedContainer = "container:Sample.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "6369A2691A9322E20015FC5C"
+            BuildableName = "Sample.app"
+            BlueprintName = "Sample"
+            ReferencedContainer = "container:Sample.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/xcshareddata/xcschemes/SwiftSample.xcscheme b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/xcshareddata/xcschemes/SwiftSample.xcscheme
new file mode 100644
index 0000000..bba6a02
--- /dev/null
+++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/xcshareddata/xcschemes/SwiftSample.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "0730"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "633BFFC11B950B210007E424"
+               BuildableName = "SwiftSample.app"
+               BlueprintName = "SwiftSample"
+               ReferencedContainer = "container:SwiftSample.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "633BFFC11B950B210007E424"
+            BuildableName = "SwiftSample.app"
+            BlueprintName = "SwiftSample"
+            ReferencedContainer = "container:SwiftSample.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "633BFFC11B950B210007E424"
+            BuildableName = "SwiftSample.app"
+            BlueprintName = "SwiftSample"
+            ReferencedContainer = "container:SwiftSample.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "633BFFC11B950B210007E424"
+            BuildableName = "SwiftSample.app"
+            BlueprintName = "SwiftSample"
+            ReferencedContainer = "container:SwiftSample.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index 15ce120..392e7cb 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -58,7 +58,7 @@
                  requestedResponseSize:(NSNumber *)responseSize {
   RMTStreamingOutputCallRequest *request = [self message];
   RMTResponseParameters *parameters = [RMTResponseParameters message];
-  parameters.size = (int)responseSize.integerValue;
+  parameters.size = responseSize.intValue;
   [request.responseParametersArray addObject:parameters];
   request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue];
   return request;
@@ -188,7 +188,7 @@
   RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message];
   for (NSNumber *size in expectedSizes) {
     RMTResponseParameters *parameters = [RMTResponseParameters message];
-    parameters.size = (int)[size integerValue];
+    parameters.size = [size intValue];
     [request.responseParametersArray addObject:parameters];
   }
 
@@ -284,9 +284,10 @@
   // A buffered pipe to which we never write any value acts as a writer that just hangs.
   GRXBufferedPipe *requestsBuffer = [[GRXBufferedPipe alloc] init];
 
-  GRPCProtoCall *call = [_service RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
-                                                                    handler:^(RMTStreamingInputCallResponse *response,
-                                                                              NSError *error) {
+  GRPCProtoCall *call =
+      [_service RPCToStreamingInputCallWithRequestsWriter:requestsBuffer
+                                                  handler:^(RMTStreamingInputCallResponse *response,
+                                                            NSError *error) {
     XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
     [expectation fulfill];
   }];
diff --git a/src/php/README.md b/src/php/README.md
index cf8f2c1..6cc1ba4 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -58,7 +58,7 @@
 Clone this repository
 
 ```sh
-$ git clone https://github.com/grpc/grpc.git
+$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
 ```
 
 Build and install the gRPC C core library
@@ -101,7 +101,7 @@
 You will need the source code to run tests
 
 ```sh
-$ git clone https://github.com/grpc/grpc.git
+$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc
 $ cd grpc
 $ git pull --recurse-submodules && git submodule update --init --recursive
 ```
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 0ec5022..2cd45f1 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -248,6 +248,7 @@
   call->wrapped = grpc_channel_create_call(
       channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, completion_queue, method,
       host_override, deadline->wrapped, NULL);
+  call->owned = true;
 }
 
 /**
diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst
index afc4fe6..3fc3185 100644
--- a/src/python/grpcio/README.rst
+++ b/src/python/grpcio/README.rst
@@ -46,7 +46,7 @@
 ::
 
   $ export REPO_ROOT=grpc  # REPO_ROOT can be any directory of your choice
-  $ git clone https://github.com/grpc/grpc.git $REPO_ROOT
+  $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc $REPO_ROOT
   $ cd $REPO_ROOT
   $ git submodule update --init
 
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index cf6175d..a89b501 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -364,13 +364,13 @@
     with self._state.condition:
       while self._state.initial_metadata is None:
         self._state.condition.wait()
-      return self._state.initial_metadata
+      return _common.application_metadata(self._state.initial_metadata)
 
   def trailing_metadata(self):
     with self._state.condition:
       while self._state.trailing_metadata is None:
         self._state.condition.wait()
-      return self._state.trailing_metadata
+      return _common.application_metadata(self._state.trailing_metadata)
 
   def code(self):
     with self._state.condition:
@@ -382,7 +382,7 @@
     with self._state.condition:
       while self._state.details is None:
         self._state.condition.wait()
-      return self._state.details
+      return _common.decode(self._state.details)
 
   def _repr(self):
     with self._state.condition:
@@ -390,7 +390,7 @@
         return '<_Rendezvous object of in-flight RPC>'
       else:
         return '<_Rendezvous of RPC that terminated with ({}, {})>'.format(
-            self._state.code, self._state.details)
+            self._state.code, _common.decode(self._state.details))
 
   def __repr__(self):
     return self._repr()
@@ -451,7 +451,7 @@
       state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
       operations = (
           cygrpc.operation_send_initial_metadata(
-              _common.metadata(metadata), _EMPTY_FLAGS),
+              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
           cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
           cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
           cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
@@ -529,7 +529,7 @@
             event_handler)
         operations = (
             cygrpc.operation_send_initial_metadata(
-                _common.metadata(metadata), _EMPTY_FLAGS),
+                _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
             cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
             cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
             cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
@@ -564,7 +564,7 @@
           None)
       operations = (
           cygrpc.operation_send_initial_metadata(
-              _common.metadata(metadata), _EMPTY_FLAGS),
+              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
           cygrpc.operation_receive_message(_EMPTY_FLAGS),
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
@@ -608,7 +608,7 @@
           event_handler)
       operations = (
           cygrpc.operation_send_initial_metadata(
-              _common.metadata(metadata), _EMPTY_FLAGS),
+              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
           cygrpc.operation_receive_message(_EMPTY_FLAGS),
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
@@ -645,7 +645,7 @@
           event_handler)
       operations = (
           cygrpc.operation_send_initial_metadata(
-              _common.metadata(metadata), _EMPTY_FLAGS),
+              _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
           cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
       )
       call.start_batch(cygrpc.Operations(operations), event_handler)
@@ -846,8 +846,13 @@
   else:
     pairs = list(options) + [
         (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)]
-  return cygrpc.ChannelArgs(
-      cygrpc.ChannelArg(arg_name, arg_value) for arg_name, arg_value in pairs)
+  encoded_pairs = [
+      (_common.encode(arg_name), arg_value) if isinstance(arg_value, int)
+      else (_common.encode(arg_name), _common.encode(arg_value))
+      for arg_name, arg_value in pairs]
+  return cygrpc.ChannelArgs([
+      cygrpc.ChannelArg(arg_name, arg_value)
+      for arg_name, arg_value in encoded_pairs])
 
 
 class Channel(grpc.Channel):
@@ -860,7 +865,8 @@
       options: Configuration options for the channel.
       credentials: A cygrpc.ChannelCredentials or None.
     """
-    self._channel = cygrpc.Channel(target, _options(options), credentials)
+    self._channel = cygrpc.Channel(
+        _common.encode(target), _options(options), credentials)
     self._call_state = _ChannelCallState(self._channel)
     self._connectivity_state = _ChannelConnectivityState(self._channel)
 
@@ -873,26 +879,26 @@
   def unary_unary(
       self, method, request_serializer=None, response_deserializer=None):
     return _UnaryUnaryMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state), method,
-        request_serializer, response_deserializer)
+        self._channel, _create_channel_managed_call(self._call_state),
+        _common.encode(method), request_serializer, response_deserializer)
 
   def unary_stream(
       self, method, request_serializer=None, response_deserializer=None):
     return _UnaryStreamMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state), method,
-        request_serializer, response_deserializer)
+        self._channel, _create_channel_managed_call(self._call_state),
+        _common.encode(method), request_serializer, response_deserializer)
 
   def stream_unary(
       self, method, request_serializer=None, response_deserializer=None):
     return _StreamUnaryMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state), method,
-        request_serializer, response_deserializer)
+        self._channel, _create_channel_managed_call(self._call_state),
+        _common.encode(method), request_serializer, response_deserializer)
 
   def stream_stream(
       self, method, request_serializer=None, response_deserializer=None):
     return _StreamStreamMultiCallable(
-        self._channel, _create_channel_managed_call(self._call_state), method,
-        request_serializer, response_deserializer)
+        self._channel, _create_channel_managed_call(self._call_state),
+        _common.encode(method), request_serializer, response_deserializer)
 
   def __del__(self):
     _moot(self._connectivity_state)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index f351bea..4d7d521 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -76,9 +76,37 @@
 }
 
 
-def metadata(application_metadata):
+def encode(s):
+  if isinstance(s, bytes):
+    return s
+  else:
+    return s.encode('ascii')
+
+
+def decode(b):
+  if isinstance(b, str):
+    return b
+  else:
+    try:
+      return b.decode('utf8')
+    except UnicodeDecodeError:
+      logging.exception('Invalid encoding on {}'.format(b))
+      return b.decode('latin1')
+
+
+def cygrpc_metadata(application_metadata):
   return _EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
-      cygrpc.Metadatum(key, value) for key, value in application_metadata)
+      cygrpc.Metadatum(encode(key), encode(value))
+      for key, value in application_metadata)
+
+
+def application_metadata(cygrpc_metadata):
+  if cygrpc_metadata is None:
+    return ()
+  else:
+    return tuple(
+        (decode(key), value if key[-4:] == b'-bin' else decode(value))
+        for key, value in cygrpc_metadata)
 
 
 def _transform(message, transformer, exception_message):
@@ -101,17 +129,8 @@
                     'Exception deserializing message!')
 
 
-def _encode(s):
-  if isinstance(s, bytes):
-    return s
-  else:
-    return s.encode('ascii')
-
-
 def fully_qualified_method(group, method):
-  group = _encode(group)
-  method = _encode(method)
-  return b'/' + group + b'/' + method
+  return '/{}/{}'.format(group, method)
 
 
 class CleanupThread(threading.Thread):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index 866cff0..1406696 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -32,9 +32,8 @@
 
 cdef class Channel:
 
-  def __cinit__(self, target, ChannelArgs arguments=None,
+  def __cinit__(self, bytes target, ChannelArgs arguments=None,
                 ChannelCredentials channel_credentials=None):
-    target = str_to_bytes(target)
     cdef grpc_channel_args *c_arguments = NULL
     cdef char *c_target = NULL
     self.c_channel = NULL
@@ -57,8 +56,6 @@
   def create_call(self, Call parent, int flags,
                   CompletionQueue queue not None,
                   method, host, Timespec deadline not None):
-    method = str_to_bytes(method)
-    host = str_to_bytes(host)
     if queue.is_shutting_down:
       raise ValueError("queue must not be shutting down or shutdown")
     cdef char *method_c_string = method
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 470382d..b24e692 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -82,7 +82,7 @@
 
 cdef class CredentialsMetadataPlugin:
 
-  def __cinit__(self, object plugin_callback, name):
+  def __cinit__(self, object plugin_callback, bytes name):
     """
     Args:
       plugin_callback (callable): Callback accepting a service URL (str/bytes)
@@ -91,9 +91,8 @@
         when called should be non-blocking and eventually call the callback
         object with the appropriate status code/details and metadata (if
         successful).
-      name (str): Plugin name.
+      name (bytes): Plugin name.
     """
-    name = str_to_bytes(name)
     if not callable(plugin_callback):
       raise ValueError('expected callable plugin_callback')
     self.plugin_callback = plugin_callback
@@ -130,8 +129,7 @@
     grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil:
   def python_callback(
       Metadata metadata, grpc_status_code status,
-      error_details):
-    error_details = str_to_bytes(error_details)
+      bytes error_details):
     cb(user_data, metadata.c_metadata_array.metadata,
        metadata.c_metadata_array.count, status, error_details)
   cdef CredentialsMetadataPlugin self = <CredentialsMetadataPlugin>state
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index 0055d0d..8e651e8 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -231,17 +231,10 @@
 
 cdef class ByteBuffer:
 
-  def __cinit__(self, data):
+  def __cinit__(self, bytes data):
     if data is None:
       self.c_byte_buffer = NULL
       return
-    if isinstance(data, ByteBuffer):
-      data = (<ByteBuffer>data).bytes()
-      if data is None:
-        self.c_byte_buffer = NULL
-        return
-    else:
-      data = str_to_bytes(data)
 
     cdef char *c_data = data
     cdef gpr_slice data_slice
@@ -296,26 +289,28 @@
 
 cdef class SslPemKeyCertPair:
 
-  def __cinit__(self, private_key, certificate_chain):
-    self.private_key = str_to_bytes(private_key)
-    self.certificate_chain = str_to_bytes(certificate_chain)
+  def __cinit__(self, bytes private_key, bytes certificate_chain):
+    self.private_key = private_key
+    self.certificate_chain = certificate_chain
     self.c_pair.private_key = self.private_key
     self.c_pair.certificate_chain = self.certificate_chain
 
 
 cdef class ChannelArg:
 
-  def __cinit__(self, key, value):
-    self.key = str_to_bytes(key)
+  def __cinit__(self, bytes key, value):
+    self.key = key
     self.c_arg.key = self.key
     if isinstance(value, int):
-      self.value = int(value)
+      self.value = value
       self.c_arg.type = GRPC_ARG_INTEGER
       self.c_arg.value.integer = self.value
-    else:
-      self.value = str_to_bytes(value)
+    elif isinstance(value, bytes):
+      self.value = value
       self.c_arg.type = GRPC_ARG_STRING
       self.c_arg.value.string = self.value
+    else:
+      raise TypeError('Expected int or bytes, got {}'.format(type(value)))
 
 
 cdef class ChannelArgs:
@@ -347,9 +342,9 @@
 
 cdef class Metadatum:
 
-  def __cinit__(self, key, value):
-    self._key = str_to_bytes(key)
-    self._value = str_to_bytes(value)
+  def __cinit__(self, bytes key, bytes value):
+    self._key = key
+    self._value = value
     self.c_metadata.key = self._key
     self.c_metadata.value = self._value
     self.c_metadata.value_length = len(self._value)
@@ -563,8 +558,7 @@
   return op
 
 def operation_send_status_from_server(
-    Metadata metadata, grpc_status_code code, details, int flags):
-  details = str_to_bytes(details)
+    Metadata metadata, grpc_status_code code, bytes details, int flags):
   cdef Operation op = Operation()
   op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
   op.c_op.flags = flags
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 42afeb8..3e03b6e 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -101,7 +101,7 @@
     # Ensure the core has gotten a chance to do the start-up work
     self.backup_shutdown_queue.poll(Timespec(None))
 
-  def add_http2_port(self, address,
+  def add_http2_port(self, bytes address,
                      ServerCredentials server_credentials=None):
     address = str_to_bytes(address)
     self.references.append(address)
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index c92a8d1..7a8d0dd 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -53,6 +53,8 @@
   if 'win32' in sys.platform:
     filename = pkg_resources.resource_filename(
         'grpc._cython', '_windows/grpc_c.64.python')
+    if not isinstance(filename, bytes):
+      filename = filename.encode()
     if not pygrpc_load_core(filename):
       raise ImportError('failed to load core gRPC library')
   if not pygrpc_initialize_core():
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 4e9cfe7..7cb5218 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -31,6 +31,7 @@
 import threading
 
 import grpc
+from grpc import _common
 from grpc._cython import cygrpc
 
 
@@ -62,17 +63,16 @@
     # TODO(atash) translate different Exception superclasses into different
     # status codes.
     self.cygrpc_callback(
-        cygrpc.Metadata([]), cygrpc.StatusCode.internal, error.message)
+        _common.EMPTY_METADATA, cygrpc.StatusCode.internal,
+        _common.encode(str(error)))
 
   def _invoke_success(self, metadata):
     try:
-      cygrpc_metadata = cygrpc.Metadata(
-          cygrpc.Metadatum(key, value)
-          for key, value in metadata)
+      cygrpc_metadata = _common.cygrpc_metadata(metadata)
     except Exception as error:
       self._invoke_failure(error)
       return
-    self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, '')
+    self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')
 
   def __call__(self, metadata, error):
     with self.is_called_lock:
@@ -101,7 +101,7 @@
   def __call__(self, context, cygrpc_callback):
     wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
     wrapped_context = AuthMetadataContext(
-        context.service_url, context.method_name)
+        _common.decode(context.service_url), _common.decode(context.method_name))
     try:
       self.plugin(
           wrapped_context, AuthMetadataPluginCallback(wrapped_cygrpc_callback))
@@ -120,4 +120,4 @@
       plugin's invocation must be non-blocking.
   """
   return cygrpc.call_credentials_metadata_plugin(
-      cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), name))
+      cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), _common.encode(name)))
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index bf20f15..f4c1140 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -87,7 +87,7 @@
 
 
 def _details(state):
-  return '' if state.details is None else state.details
+  return b'' if state.details is None else state.details
 
 
 class _HandlerCallDetails(
@@ -146,14 +146,14 @@
           cygrpc.operation_send_initial_metadata(
               _EMPTY_METADATA, _EMPTY_FLAGS),
           cygrpc.operation_send_status_from_server(
-              _common.metadata(state.trailing_metadata), effective_code,
+              _common.cygrpc_metadata(state.trailing_metadata), effective_code,
               effective_details, _EMPTY_FLAGS),
       )
       token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
     else:
       operations = (
           cygrpc.operation_send_status_from_server(
-              _common.metadata(state.trailing_metadata), effective_code,
+              _common.cygrpc_metadata(state.trailing_metadata), effective_code,
               effective_details, _EMPTY_FLAGS),
       )
       token = _SEND_STATUS_FROM_SERVER_TOKEN
@@ -191,7 +191,7 @@
         if request is None:
           _abort(
               state, call, cygrpc.StatusCode.internal,
-              'Exception deserializing request!')
+              b'Exception deserializing request!')
         else:
           state.request = request
         state.condition.notify_all()
@@ -244,10 +244,10 @@
       self._state.disable_next_compression = True
 
   def invocation_metadata(self):
-    return self._rpc_event.request_metadata
+    return _common.application_metadata(self._rpc_event.request_metadata)
 
   def peer(self):
-    return self._rpc_event.operation_call.peer()
+    return _common.decode(self._rpc_event.operation_call.peer())
 
   def send_initial_metadata(self, initial_metadata):
     with self._state.condition:
@@ -256,7 +256,7 @@
       else:
         if self._state.initial_metadata_allowed:
           operation = cygrpc.operation_send_initial_metadata(
-              _common.metadata(initial_metadata), _EMPTY_FLAGS)
+              _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
           self._rpc_event.operation_call.start_batch(
               cygrpc.Operations((operation,)),
               _send_initial_metadata(self._state))
@@ -267,7 +267,8 @@
 
   def set_trailing_metadata(self, trailing_metadata):
     with self._state.condition:
-      self._state.trailing_metadata = trailing_metadata
+      self._state.trailing_metadata = _common.cygrpc_metadata(
+          trailing_metadata)
 
   def set_code(self, code):
     with self._state.condition:
@@ -275,7 +276,7 @@
 
   def set_details(self, details):
     with self._state.condition:
-      self._state.details = details
+      self._state.details = _common.encode(details)
 
 
 class _RequestIterator(object):
@@ -346,7 +347,7 @@
                   rpc_event.request_call_details.method)
               _abort(
                   state, rpc_event.operation_call,
-                  cygrpc.StatusCode.unimplemented, details)
+                  cygrpc.StatusCode.unimplemented, _common.encode(details))
               return None
             elif state.client is _CANCELLED:
               return None
@@ -366,8 +367,8 @@
       if e not in state.rpc_errors:
         details = 'Exception calling application: {}'.format(e)
         logging.exception(details)
-        _abort(
-            state, rpc_event.operation_call, cygrpc.StatusCode.unknown, details)
+        _abort(state, rpc_event.operation_call,
+               cygrpc.StatusCode.unknown, _common.encode(details))
     return None, False
 
 
@@ -381,8 +382,8 @@
       if e not in state.rpc_errors:
         details = 'Exception iterating responses: {}'.format(e)
         logging.exception(details)
-        _abort(
-            state, rpc_event.operation_call, cygrpc.StatusCode.unknown, details)
+        _abort(state, rpc_event.operation_call,
+               cygrpc.StatusCode.unknown, _common.encode(details))
     return None, False
 
 
@@ -392,7 +393,7 @@
     with state.condition:
       _abort(
           state, rpc_event.operation_call, cygrpc.StatusCode.internal,
-          'Failed to serialize response!')
+          b'Failed to serialize response!')
     return None
   else:
     return serialized_response
@@ -428,7 +429,7 @@
 def _status(rpc_event, state, serialized_response):
   with state.condition:
     if state.client is not _CANCELLED:
-      trailing_metadata = _common.metadata(state.trailing_metadata)
+      trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
       code = _completion_code(state)
       details = _details(state)
       operations = [
@@ -532,7 +533,8 @@
   for generic_handler in generic_handlers:
     method_handler = generic_handler.service(
         _HandlerCallDetails(
-            rpc_event.request_call_details.method, rpc_event.request_metadata))
+            _common.decode(rpc_event.request_call_details.method),
+            rpc_event.request_metadata))
     if method_handler is not None:
       return method_handler
   else:
@@ -545,7 +547,7 @@
       cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
       cygrpc.operation_send_status_from_server(
           _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
-          'Method not found!', _EMPTY_FLAGS),
+          b'Method not found!', _EMPTY_FLAGS),
   )
   rpc_state = _RPCState()
   rpc_event.operation_call.start_batch(
@@ -740,10 +742,10 @@
     _add_generic_handlers(self._state, generic_rpc_handlers)
 
   def add_insecure_port(self, address):
-    return _add_insecure_port(self._state, address)
+    return _add_insecure_port(self._state, _common.encode(address))
 
   def add_secure_port(self, address, server_credentials):
-    return _add_secure_port(self._state, address, server_credentials)
+    return _add_secure_port(self._state, _common.encode(address), server_credentials)
 
   def start(self):
     _start(self._state)
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index c695434..1e1f801 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -79,7 +79,8 @@
     return _ServerProtocolContext(self._servicer_context)
 
   def invocation_metadata(self):
-    return self._servicer_context.invocation_metadata()
+    return _common.cygrpc_metadata(
+        self._servicer_context.invocation_metadata())
 
   def initial_metadata(self, initial_metadata):
     self._servicer_context.send_initial_metadata(initial_metadata)
diff --git a/src/python/grpcio/tests/interop/methods.py b/src/python/grpcio/tests/interop/methods.py
index 7eac511..86aa049 100644
--- a/src/python/grpcio/tests/interop/methods.py
+++ b/src/python/grpcio/tests/interop/methods.py
@@ -79,10 +79,11 @@
 
   def FullDuplexCall(self, request_iterator, context):
     for request in request_iterator:
-      yield messages_pb2.StreamingOutputCallResponse(
-          payload=messages_pb2.Payload(
-              type=request.payload.type,
-              body=b'\x00' * request.response_parameters[0].size))
+      for response_parameters in request.response_parameters:
+        yield messages_pb2.StreamingOutputCallResponse(
+            payload=messages_pb2.Payload(
+                type=request.payload.type,
+                body=b'\x00' * response_parameters.size))
 
   # NOTE(nathaniel): Apparently this is the same as the full-duplex call?
   # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)...
diff --git a/src/python/grpcio/tests/tests.json b/src/python/grpcio/tests/tests.json
index 9c118ef..45eb75b 100644
--- a/src/python/grpcio/tests/tests.json
+++ b/src/python/grpcio/tests/tests.json
@@ -11,7 +11,6 @@
   "_channel_ready_future_test.ChannelReadyFutureTest",
   "_channel_test.ChannelTest", 
   "_compression_test.CompressionTest",
-  "_connectivity_channel_test.ChannelConnectivityTest", 
   "_connectivity_channel_test.ConnectivityStatesTest",
   "_empty_message_test.EmptyMessageTest",
   "_exit_test.ExitTest",
diff --git a/src/python/grpcio/tests/unit/_compression_test.py b/src/python/grpcio/tests/unit/_compression_test.py
index 6eddb6f..9e8b857 100644
--- a/src/python/grpcio/tests/unit/_compression_test.py
+++ b/src/python/grpcio/tests/unit/_compression_test.py
@@ -37,8 +37,8 @@
 from tests.unit import test_common
 from tests.unit.framework.common import test_constants
 
-_UNARY_UNARY = b'/test/UnaryUnary'
-_STREAM_STREAM = b'/test/StreamStream'
+_UNARY_UNARY = '/test/UnaryUnary'
+_STREAM_STREAM = '/test/StreamStream'
 
 
 def handle_unary(request, servicer_context):
diff --git a/src/python/grpcio/tests/unit/_cython/_cancel_many_calls_test.py b/src/python/grpcio/tests/unit/_cython/_cancel_many_calls_test.py
index c1de779..cac0c8b 100644
--- a/src/python/grpcio/tests/unit/_cython/_cancel_many_calls_test.py
+++ b/src/python/grpcio/tests/unit/_cython/_cancel_many_calls_test.py
@@ -159,9 +159,9 @@
     server_completion_queue = cygrpc.CompletionQueue()
     server = cygrpc.Server()
     server.register_completion_queue(server_completion_queue)
-    port = server.add_http2_port('[::]:0')
+    port = server.add_http2_port(b'[::]:0')
     server.start()
-    channel = cygrpc.Channel('localhost:{}'.format(port))
+    channel = cygrpc.Channel('localhost:{}'.format(port).encode())
 
     state = _State()
 
diff --git a/src/python/grpcio/tests/unit/_cython/_channel_test.py b/src/python/grpcio/tests/unit/_cython/_channel_test.py
index 3dc7a24..f9c8a3a 100644
--- a/src/python/grpcio/tests/unit/_cython/_channel_test.py
+++ b/src/python/grpcio/tests/unit/_cython/_channel_test.py
@@ -37,7 +37,7 @@
 
 
 def _channel_and_completion_queue():
-  channel = cygrpc.Channel('localhost:54321', cygrpc.ChannelArgs(()))
+  channel = cygrpc.Channel(b'localhost:54321', cygrpc.ChannelArgs(()))
   completion_queue = cygrpc.CompletionQueue()
   return channel, completion_queue
 
diff --git a/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py b/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py
index 6ae7a90..27fcee0 100644
--- a/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py
+++ b/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py
@@ -126,9 +126,9 @@
     server_completion_queue = cygrpc.CompletionQueue()
     server = cygrpc.Server()
     server.register_completion_queue(server_completion_queue)
-    port = server.add_http2_port('[::]:0')
+    port = server.add_http2_port(b'[::]:0')
     server.start()
-    channel = cygrpc.Channel('localhost:{}'.format(port))
+    channel = cygrpc.Channel('localhost:{}'.format(port).encode())
 
     server_shutdown_tag = 'server_shutdown_tag'
     server_driver = _ServerDriver(server_completion_queue, server_shutdown_tag)
diff --git a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
index a006a20..b740695 100644
--- a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
@@ -46,38 +46,38 @@
   callback(cygrpc.Metadata(
       [cygrpc.Metadatum(_CALL_CREDENTIALS_METADATA_KEY,
                         _CALL_CREDENTIALS_METADATA_VALUE)]),
-      cygrpc.StatusCode.ok, '')
+      cygrpc.StatusCode.ok, b'')
 
 
 class TypeSmokeTest(unittest.TestCase):
 
   def testStringsInUtilitiesUpDown(self):
     self.assertEqual(0, cygrpc.StatusCode.ok)
-    metadatum = cygrpc.Metadatum('a', 'b')
-    self.assertEqual('a'.encode(), metadatum.key)
-    self.assertEqual('b'.encode(), metadatum.value)
+    metadatum = cygrpc.Metadatum(b'a', b'b')
+    self.assertEqual(b'a', metadatum.key)
+    self.assertEqual(b'b', metadatum.value)
     metadata = cygrpc.Metadata([metadatum])
     self.assertEqual(1, len(metadata))
     self.assertEqual(metadatum.key, metadata[0].key)
 
   def testMetadataIteration(self):
     metadata = cygrpc.Metadata([
-        cygrpc.Metadatum('a', 'b'), cygrpc.Metadatum('c', 'd')])
+        cygrpc.Metadatum(b'a', b'b'), cygrpc.Metadatum(b'c', b'd')])
     iterator = iter(metadata)
     metadatum = next(iterator)
     self.assertIsInstance(metadatum, cygrpc.Metadatum)
-    self.assertEqual(metadatum.key, 'a'.encode())
-    self.assertEqual(metadatum.value, 'b'.encode())
+    self.assertEqual(metadatum.key, b'a')
+    self.assertEqual(metadatum.value, b'b')
     metadatum = next(iterator)
     self.assertIsInstance(metadatum, cygrpc.Metadatum)
-    self.assertEqual(metadatum.key, 'c'.encode())
-    self.assertEqual(metadatum.value, 'd'.encode())
+    self.assertEqual(metadatum.key, b'c')
+    self.assertEqual(metadatum.value, b'd')
     with self.assertRaises(StopIteration):
       next(iterator)
 
   def testOperationsIteration(self):
     operations = cygrpc.Operations([
-        cygrpc.operation_send_message('asdf', _EMPTY_FLAGS)])
+        cygrpc.operation_send_message(b'asdf', _EMPTY_FLAGS)])
     iterator = iter(operations)
     operation = next(iterator)
     self.assertIsInstance(operation, cygrpc.Operation)
@@ -87,7 +87,7 @@
       next(iterator)
 
   def testOperationFlags(self):
-    operation = cygrpc.operation_send_message('asdf',
+    operation = cygrpc.operation_send_message(b'asdf',
                                               cygrpc.WriteFlag.no_compress)
     self.assertEqual(cygrpc.WriteFlag.no_compress, operation.flags)
 
@@ -105,16 +105,16 @@
     del server
 
   def testChannelUpDown(self):
-    channel = cygrpc.Channel('[::]:0', cygrpc.ChannelArgs([]))
+    channel = cygrpc.Channel(b'[::]:0', cygrpc.ChannelArgs([]))
     del channel
 
   def testCredentialsMetadataPluginUpDown(self):
     plugin = cygrpc.CredentialsMetadataPlugin(
-        lambda ignored_a, ignored_b: None, '')
+        lambda ignored_a, ignored_b: None, b'')
     del plugin
 
   def testCallCredentialsFromPluginUpDown(self):
-    plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, '')
+    plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, b'')
     call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
     del plugin
     del call_credentials
@@ -123,7 +123,7 @@
     server = cygrpc.Server()
     completion_queue = cygrpc.CompletionQueue()
     server.register_completion_queue(completion_queue)
-    port = server.add_http2_port('[::]:0')
+    port = server.add_http2_port(b'[::]:0')
     self.assertIsInstance(port, int)
     server.start()
     del server
@@ -131,7 +131,7 @@
   def testServerStartShutdown(self):
     completion_queue = cygrpc.CompletionQueue()
     server = cygrpc.Server()
-    server.add_http2_port('[::]:0')
+    server.add_http2_port(b'[::]:0')
     server.register_completion_queue(completion_queue)
     server.start()
     shutdown_tag = object()
@@ -150,9 +150,9 @@
     self.server = cygrpc.Server()
     self.server.register_completion_queue(self.server_completion_queue)
     if server_credentials:
-      self.port = self.server.add_http2_port('[::]:0', server_credentials)
+      self.port = self.server.add_http2_port(b'[::]:0', server_credentials)
     else:
-      self.port = self.server.add_http2_port('[::]:0')
+      self.port = self.server.add_http2_port(b'[::]:0')
     self.server.start()
     self.client_completion_queue = cygrpc.CompletionQueue()
     if client_credentials:
@@ -160,10 +160,10 @@
           cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
                             host_override)])
       self.client_channel = cygrpc.Channel(
-          'localhost:{}'.format(self.port), client_channel_arguments,
+          'localhost:{}'.format(self.port).encode(), client_channel_arguments,
           client_credentials)
     else:
-      self.client_channel = cygrpc.Channel('localhost:{}'.format(self.port))
+      self.client_channel = cygrpc.Channel('localhost:{}'.format(self.port).encode())
     if host_override:
       self.host_argument = None  # default host
       self.expected_host = host_override
diff --git a/src/python/grpcio/tests/unit/_empty_message_test.py b/src/python/grpcio/tests/unit/_empty_message_test.py
index f324f62..8c7d697 100644
--- a/src/python/grpcio/tests/unit/_empty_message_test.py
+++ b/src/python/grpcio/tests/unit/_empty_message_test.py
@@ -37,10 +37,10 @@
 _REQUEST = b''
 _RESPONSE = b''
 
-_UNARY_UNARY = b'/test/UnaryUnary'
-_UNARY_STREAM = b'/test/UnaryStream'
-_STREAM_UNARY = b'/test/StreamUnary'
-_STREAM_STREAM = b'/test/StreamStream'
+_UNARY_UNARY = '/test/UnaryUnary'
+_UNARY_STREAM = '/test/UnaryStream'
+_STREAM_UNARY = '/test/StreamUnary'
+_STREAM_STREAM = '/test/StreamStream'
 
 
 def handle_unary_unary(request, servicer_context):
diff --git a/src/python/grpcio/tests/unit/_metadata_code_details_test.py b/src/python/grpcio/tests/unit/_metadata_code_details_test.py
index dd74268..0fd02d2 100644
--- a/src/python/grpcio/tests/unit/_metadata_code_details_test.py
+++ b/src/python/grpcio/tests/unit/_metadata_code_details_test.py
@@ -47,29 +47,29 @@
 _RESPONSE_SERIALIZER = lambda unused_response: _SERIALIZED_RESPONSE
 _RESPONSE_DESERIALIZER = lambda unused_serialized_resopnse: object()
 
-_SERVICE = b'test.TestService'
-_UNARY_UNARY = b'UnaryUnary'
-_UNARY_STREAM = b'UnaryStream'
-_STREAM_UNARY = b'StreamUnary'
-_STREAM_STREAM = b'StreamStream'
+_SERVICE = 'test.TestService'
+_UNARY_UNARY = 'UnaryUnary'
+_UNARY_STREAM = 'UnaryStream'
+_STREAM_UNARY = 'StreamUnary'
+_STREAM_STREAM = 'StreamStream'
 
 _CLIENT_METADATA = (
-    (b'client-md-key', b'client-md-key'),
-    (b'client-md-key-bin', b'\x00\x01')
+    ('client-md-key', 'client-md-key'),
+    ('client-md-key-bin', b'\x00\x01')
 )
 
 _SERVER_INITIAL_METADATA = (
-    (b'server-initial-md-key', b'server-initial-md-value'),
-    (b'server-initial-md-key-bin', b'\x00\x02')
+    ('server-initial-md-key', 'server-initial-md-value'),
+    ('server-initial-md-key-bin', b'\x00\x02')
 )
 
 _SERVER_TRAILING_METADATA = (
-    (b'server-trailing-md-key', b'server-trailing-md-value'),
-    (b'server-trailing-md-key-bin', b'\x00\x03')
+    ('server-trailing-md-key', 'server-trailing-md-value'),
+    ('server-trailing-md-key-bin', b'\x00\x03')
 )
 
 _NON_OK_CODE = grpc.StatusCode.NOT_FOUND
-_DETAILS = b'Test details!'
+_DETAILS = 'Test details!'
 
 
 class _Servicer(object):
@@ -195,15 +195,15 @@
 
     channel = grpc.insecure_channel('localhost:{}'.format(port))
     self._unary_unary = channel.unary_unary(
-        b'/'.join((b'', _SERVICE, _UNARY_UNARY,)),
+        '/'.join(('', _SERVICE, _UNARY_UNARY,)),
         request_serializer=_REQUEST_SERIALIZER,
         response_deserializer=_RESPONSE_DESERIALIZER,)
     self._unary_stream = channel.unary_stream(
-        b'/'.join((b'', _SERVICE, _UNARY_STREAM,)),)
+        '/'.join(('', _SERVICE, _UNARY_STREAM,)),)
     self._stream_unary = channel.stream_unary(
-        b'/'.join((b'', _SERVICE, _STREAM_UNARY,)),)
+        '/'.join(('', _SERVICE, _STREAM_UNARY,)),)
     self._stream_stream = channel.stream_stream(
-        b'/'.join((b'', _SERVICE, _STREAM_STREAM,)),
+        '/'.join(('', _SERVICE, _STREAM_STREAM,)),
         request_serializer=_REQUEST_SERIALIZER,
         response_deserializer=_RESPONSE_DESERIALIZER,)
 
diff --git a/src/python/grpcio/tests/unit/_metadata_test.py b/src/python/grpcio/tests/unit/_metadata_test.py
index 2cb13f2..c637a28 100644
--- a/src/python/grpcio/tests/unit/_metadata_test.py
+++ b/src/python/grpcio/tests/unit/_metadata_test.py
@@ -44,33 +44,33 @@
 _REQUEST = b'\x00\x00\x00'
 _RESPONSE = b'\x00\x00\x00'
 
-_UNARY_UNARY = b'/test/UnaryUnary'
-_UNARY_STREAM = b'/test/UnaryStream'
-_STREAM_UNARY = b'/test/StreamUnary'
-_STREAM_STREAM = b'/test/StreamStream'
+_UNARY_UNARY = '/test/UnaryUnary'
+_UNARY_STREAM = '/test/UnaryStream'
+_STREAM_UNARY = '/test/StreamUnary'
+_STREAM_STREAM = '/test/StreamStream'
 
 _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
 
 _CLIENT_METADATA = (
-    (b'client-md-key', b'client-md-key'),
-    (b'client-md-key-bin', b'\x00\x01')
+    ('client-md-key', 'client-md-key'),
+    ('client-md-key-bin', b'\x00\x01')
 )
 
 _SERVER_INITIAL_METADATA = (
-    (b'server-initial-md-key', b'server-initial-md-value'),
-    (b'server-initial-md-key-bin', b'\x00\x02')
+    ('server-initial-md-key', 'server-initial-md-value'),
+    ('server-initial-md-key-bin', b'\x00\x02')
 )
 
 _SERVER_TRAILING_METADATA = (
-    (b'server-trailing-md-key', b'server-trailing-md-value'),
-    (b'server-trailing-md-key-bin', b'\x00\x03')
+    ('server-trailing-md-key', 'server-trailing-md-value'),
+    ('server-trailing-md-key-bin', b'\x00\x03')
 )
 
 
 def user_agent(metadata):
   for key, val in metadata:
-    if key == b'user-agent':
-      return val.decode('ascii')
+    if key == 'user-agent':
+      return val
   raise KeyError('No user agent!')
 
 
diff --git a/src/python/grpcio/tests/unit/_rpc_test.py b/src/python/grpcio/tests/unit/_rpc_test.py
index 9814504..c70d65a 100644
--- a/src/python/grpcio/tests/unit/_rpc_test.py
+++ b/src/python/grpcio/tests/unit/_rpc_test.py
@@ -45,10 +45,10 @@
 _SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
 _DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
 
-_UNARY_UNARY = b'/test/UnaryUnary'
-_UNARY_STREAM = b'/test/UnaryStream'
-_STREAM_UNARY = b'/test/StreamUnary'
-_STREAM_STREAM = b'/test/StreamStream'
+_UNARY_UNARY = '/test/UnaryUnary'
+_UNARY_STREAM = '/test/UnaryStream'
+_STREAM_UNARY = '/test/StreamUnary'
+_STREAM_STREAM = '/test/StreamStream'
 
 
 class _Callback(object):
@@ -79,7 +79,7 @@
   def handle_unary_unary(self, request, servicer_context):
     self._control.control()
     if servicer_context is not None:
-      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
     return request
 
   def handle_unary_stream(self, request, servicer_context):
@@ -88,7 +88,7 @@
       yield request
     self._control.control()
     if servicer_context is not None:
-      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
 
   def handle_stream_unary(self, request_iterator, servicer_context):
     if servicer_context is not None:
@@ -100,13 +100,13 @@
       response_elements.append(request)
     self._control.control()
     if servicer_context is not None:
-      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
     return b''.join(response_elements)
 
   def handle_stream_stream(self, request_iterator, servicer_context):
     self._control.control()
     if servicer_context is not None:
-      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+      servicer_context.set_trailing_metadata((('testkey', 'testvalue',),))
     for request in request_iterator:
       self._control.control()
       yield request
@@ -185,7 +185,7 @@
     self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
 
     self._server = grpc.server((), self._server_pool)
-    port = self._server.add_insecure_port(b'[::]:0')
+    port = self._server.add_insecure_port('[::]:0')
     self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
     self._server.start()
 
@@ -195,7 +195,7 @@
     request = b'abc'
 
     with self.assertRaises(grpc.RpcError) as exception_context:
-      self._channel.unary_unary(b'NoSuchMethod')(request)
+      self._channel.unary_unary('NoSuchMethod')(request)
 
     self.assertEqual(
         grpc.StatusCode.UNIMPLEMENTED, exception_context.exception.code())
@@ -207,7 +207,7 @@
     multi_callable = _unary_unary_multi_callable(self._channel)
     response = multi_callable(
         request, metadata=(
-            (b'test', b'SuccessfulUnaryRequestBlockingUnaryResponse'),))
+            ('test', 'SuccessfulUnaryRequestBlockingUnaryResponse'),))
 
     self.assertEqual(expected_response, response)
 
@@ -218,7 +218,7 @@
     multi_callable = _unary_unary_multi_callable(self._channel)
     response, call = multi_callable.with_call(
         request, metadata=(
-            (b'test', b'SuccessfulUnaryRequestBlockingUnaryResponseWithCall'),))
+            ('test', 'SuccessfulUnaryRequestBlockingUnaryResponseWithCall'),))
 
     self.assertEqual(expected_response, response)
     self.assertIs(grpc.StatusCode.OK, call.code())
@@ -230,7 +230,7 @@
     multi_callable = _unary_unary_multi_callable(self._channel)
     response_future = multi_callable.future(
         request, metadata=(
-            (b'test', b'SuccessfulUnaryRequestFutureUnaryResponse'),))
+            ('test', 'SuccessfulUnaryRequestFutureUnaryResponse'),))
     response = response_future.result()
 
     self.assertEqual(expected_response, response)
@@ -242,7 +242,7 @@
     multi_callable = _unary_stream_multi_callable(self._channel)
     response_iterator = multi_callable(
         request,
-        metadata=((b'test', b'SuccessfulUnaryRequestStreamResponse'),))
+        metadata=(('test', 'SuccessfulUnaryRequestStreamResponse'),))
     responses = tuple(response_iterator)
 
     self.assertSequenceEqual(expected_responses, responses)
@@ -255,7 +255,7 @@
     multi_callable = _stream_unary_multi_callable(self._channel)
     response = multi_callable(
         request_iterator,
-        metadata=((b'test', b'SuccessfulStreamRequestBlockingUnaryResponse'),))
+        metadata=(('test', 'SuccessfulStreamRequestBlockingUnaryResponse'),))
 
     self.assertEqual(expected_response, response)
 
@@ -268,7 +268,7 @@
     response, call = multi_callable.with_call(
         request_iterator,
         metadata=(
-            (b'test', b'SuccessfulStreamRequestBlockingUnaryResponseWithCall'),
+            ('test', 'SuccessfulStreamRequestBlockingUnaryResponseWithCall'),
         ))
 
     self.assertEqual(expected_response, response)
@@ -283,7 +283,7 @@
     response_future = multi_callable.future(
         request_iterator,
         metadata=(
-            (b'test', b'SuccessfulStreamRequestFutureUnaryResponse'),))
+            ('test', 'SuccessfulStreamRequestFutureUnaryResponse'),))
     response = response_future.result()
 
     self.assertEqual(expected_response, response)
@@ -297,7 +297,7 @@
     multi_callable = _stream_stream_multi_callable(self._channel)
     response_iterator = multi_callable(
         request_iterator,
-        metadata=((b'test', b'SuccessfulStreamRequestStreamResponse'),))
+        metadata=(('test', 'SuccessfulStreamRequestStreamResponse'),))
     responses = tuple(response_iterator)
 
     self.assertSequenceEqual(expected_responses, responses)
@@ -312,9 +312,9 @@
 
     multi_callable = _unary_unary_multi_callable(self._channel)
     first_response = multi_callable(
-        first_request, metadata=((b'test', b'SequentialInvocations'),))
+        first_request, metadata=(('test', 'SequentialInvocations'),))
     second_response = multi_callable(
-        second_request, metadata=((b'test', b'SequentialInvocations'),))
+        second_request, metadata=(('test', 'SequentialInvocations'),))
 
     self.assertEqual(expected_first_response, first_response)
     self.assertEqual(expected_second_response, second_response)
@@ -331,7 +331,7 @@
       request_iterator = iter(requests)
       response_future = pool.submit(
           multi_callable, request_iterator,
-          metadata=((b'test', b'ConcurrentBlockingInvocations'),))
+          metadata=(('test', 'ConcurrentBlockingInvocations'),))
       response_futures[index] = response_future
     responses = tuple(
         response_future.result() for response_future in response_futures)
@@ -350,7 +350,7 @@
       request_iterator = iter(requests)
       response_future = multi_callable.future(
           request_iterator,
-          metadata=((b'test', b'ConcurrentFutureInvocations'),))
+          metadata=(('test', 'ConcurrentFutureInvocations'),))
       response_futures[index] = response_future
     responses = tuple(
         response_future.result() for response_future in response_futures)
@@ -380,8 +380,8 @@
       inner_response_future = multi_callable.future(
           request,
           metadata=(
-              (b'test',
-               b'WaitingForSomeButNotAllConcurrentFutureInvocations'),))
+              ('test',
+               'WaitingForSomeButNotAllConcurrentFutureInvocations'),))
       outer_response_future = pool.submit(wrap_future(inner_response_future))
       response_futures[index] = outer_response_future
 
@@ -400,7 +400,7 @@
     response_iterator = multi_callable(
         request,
         metadata=(
-            (b'test', b'ConsumingOneStreamResponseUnaryRequest'),))
+            ('test', 'ConsumingOneStreamResponseUnaryRequest'),))
     next(response_iterator)
 
   def testConsumingSomeButNotAllStreamResponsesUnaryRequest(self):
@@ -410,7 +410,7 @@
     response_iterator = multi_callable(
         request,
         metadata=(
-            (b'test', b'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),))
+            ('test', 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),))
     for _ in range(test_constants.STREAM_LENGTH // 2):
       next(response_iterator)
 
@@ -422,7 +422,7 @@
     response_iterator = multi_callable(
         request_iterator,
         metadata=(
-            (b'test', b'ConsumingSomeButNotAllStreamResponsesStreamRequest'),))
+            ('test', 'ConsumingSomeButNotAllStreamResponsesStreamRequest'),))
     for _ in range(test_constants.STREAM_LENGTH // 2):
       next(response_iterator)
 
@@ -434,7 +434,7 @@
     response_iterator = multi_callable(
         request_iterator,
         metadata=(
-            (b'test', b'ConsumingTooManyStreamResponsesStreamRequest'),))
+            ('test', 'ConsumingTooManyStreamResponsesStreamRequest'),))
     for _ in range(test_constants.STREAM_LENGTH):
       next(response_iterator)
     for _ in range(test_constants.STREAM_LENGTH):
@@ -453,7 +453,7 @@
     with self._control.pause():
       response_future = multi_callable.future(
           request,
-          metadata=((b'test', b'CancelledUnaryRequestUnaryResponse'),))
+          metadata=(('test', 'CancelledUnaryRequestUnaryResponse'),))
       response_future.cancel()
 
     self.assertTrue(response_future.cancelled())
@@ -468,7 +468,7 @@
     with self._control.pause():
       response_iterator = multi_callable(
           request,
-          metadata=((b'test', b'CancelledUnaryRequestStreamResponse'),))
+          metadata=(('test', 'CancelledUnaryRequestStreamResponse'),))
       self._control.block_until_paused()
       response_iterator.cancel()
 
@@ -488,7 +488,7 @@
     with self._control.pause():
       response_future = multi_callable.future(
           request_iterator,
-          metadata=((b'test', b'CancelledStreamRequestUnaryResponse'),))
+          metadata=(('test', 'CancelledStreamRequestUnaryResponse'),))
       self._control.block_until_paused()
       response_future.cancel()
 
@@ -508,7 +508,7 @@
     with self._control.pause():
       response_iterator = multi_callable(
           request_iterator,
-          metadata=((b'test', b'CancelledStreamRequestStreamResponse'),))
+          metadata=(('test', 'CancelledStreamRequestStreamResponse'),))
       response_iterator.cancel()
 
     with self.assertRaises(grpc.RpcError):
@@ -526,7 +526,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         multi_callable.with_call(
             request, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=((b'test', b'ExpiredUnaryRequestBlockingUnaryResponse'),))
+            metadata=(('test', 'ExpiredUnaryRequestBlockingUnaryResponse'),))
 
     self.assertIsNotNone(exception_context.exception.initial_metadata())
     self.assertIs(
@@ -542,7 +542,7 @@
     with self._control.pause():
       response_future = multi_callable.future(
           request, timeout=test_constants.SHORT_TIMEOUT,
-          metadata=((b'test', b'ExpiredUnaryRequestFutureUnaryResponse'),))
+          metadata=(('test', 'ExpiredUnaryRequestFutureUnaryResponse'),))
       response_future.add_done_callback(callback)
       value_passed_to_callback = callback.value()
 
@@ -567,7 +567,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         response_iterator = multi_callable(
             request, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=((b'test', b'ExpiredUnaryRequestStreamResponse'),))
+            metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),))
         next(response_iterator)
 
     self.assertIs(
@@ -583,7 +583,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         multi_callable(
             request_iterator, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=((b'test', b'ExpiredStreamRequestBlockingUnaryResponse'),))
+            metadata=(('test', 'ExpiredStreamRequestBlockingUnaryResponse'),))
 
     self.assertIsNotNone(exception_context.exception.initial_metadata())
     self.assertIs(
@@ -600,7 +600,7 @@
     with self._control.pause():
       response_future = multi_callable.future(
           request_iterator, timeout=test_constants.SHORT_TIMEOUT,
-          metadata=((b'test', b'ExpiredStreamRequestFutureUnaryResponse'),))
+          metadata=(('test', 'ExpiredStreamRequestFutureUnaryResponse'),))
       response_future.add_done_callback(callback)
       value_passed_to_callback = callback.value()
 
@@ -625,7 +625,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         response_iterator = multi_callable(
             request_iterator, timeout=test_constants.SHORT_TIMEOUT,
-            metadata=((b'test', b'ExpiredStreamRequestStreamResponse'),))
+            metadata=(('test', 'ExpiredStreamRequestStreamResponse'),))
         next(response_iterator)
 
     self.assertIs(
@@ -640,7 +640,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         multi_callable.with_call(
             request,
-            metadata=((b'test', b'FailedUnaryRequestBlockingUnaryResponse'),))
+            metadata=(('test', 'FailedUnaryRequestBlockingUnaryResponse'),))
 
     self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
 
@@ -652,7 +652,7 @@
     with self._control.fail():
       response_future = multi_callable.future(
           request,
-          metadata=((b'test', b'FailedUnaryRequestFutureUnaryResponse'),))
+          metadata=(('test', 'FailedUnaryRequestFutureUnaryResponse'),))
       response_future.add_done_callback(callback)
       value_passed_to_callback = callback.value()
 
@@ -672,7 +672,7 @@
       with self._control.fail():
         response_iterator = multi_callable(
             request,
-            metadata=((b'test', b'FailedUnaryRequestStreamResponse'),))
+            metadata=(('test', 'FailedUnaryRequestStreamResponse'),))
         next(response_iterator)
 
     self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
@@ -686,7 +686,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         multi_callable(
             request_iterator,
-            metadata=((b'test', b'FailedStreamRequestBlockingUnaryResponse'),))
+            metadata=(('test', 'FailedStreamRequestBlockingUnaryResponse'),))
 
     self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
 
@@ -699,7 +699,7 @@
     with self._control.fail():
       response_future = multi_callable.future(
           request_iterator,
-          metadata=((b'test', b'FailedStreamRequestFutureUnaryResponse'),))
+          metadata=(('test', 'FailedStreamRequestFutureUnaryResponse'),))
       response_future.add_done_callback(callback)
       value_passed_to_callback = callback.value()
 
@@ -720,7 +720,7 @@
       with self.assertRaises(grpc.RpcError) as exception_context:
         response_iterator = multi_callable(
             request_iterator,
-            metadata=((b'test', b'FailedStreamRequestStreamResponse'),))
+            metadata=(('test', 'FailedStreamRequestStreamResponse'),))
         tuple(response_iterator)
 
     self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
@@ -732,7 +732,7 @@
     multi_callable = _unary_unary_multi_callable(self._channel)
     multi_callable.future(
         request,
-        metadata=((b'test', b'IgnoredUnaryRequestFutureUnaryResponse'),))
+        metadata=(('test', 'IgnoredUnaryRequestFutureUnaryResponse'),))
 
   def testIgnoredUnaryRequestStreamResponse(self):
     request = b'\x37\x17'
@@ -740,7 +740,7 @@
     multi_callable = _unary_stream_multi_callable(self._channel)
     multi_callable(
         request,
-        metadata=((b'test', b'IgnoredUnaryRequestStreamResponse'),))
+        metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),))
 
   def testIgnoredStreamRequestFutureUnaryResponse(self):
     requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
@@ -749,7 +749,7 @@
     multi_callable = _stream_unary_multi_callable(self._channel)
     multi_callable.future(
         request_iterator,
-        metadata=((b'test', b'IgnoredStreamRequestFutureUnaryResponse'),))
+        metadata=(('test', 'IgnoredStreamRequestFutureUnaryResponse'),))
 
   def testIgnoredStreamRequestStreamResponse(self):
     requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
@@ -758,7 +758,7 @@
     multi_callable = _stream_stream_multi_callable(self._channel)
     multi_callable(
         request_iterator,
-        metadata=((b'test', b'IgnoredStreamRequestStreamResponse'),))
+        metadata=(('test', 'IgnoredStreamRequestStreamResponse'),))
 
 
 if __name__ == '__main__':
diff --git a/src/python/grpcio/tests/unit/beta/_connectivity_channel_test.py b/src/python/grpcio/tests/unit/beta/_connectivity_channel_test.py
index 488f7d7..5d826a2 100644
--- a/src/python/grpcio/tests/unit/beta/_connectivity_channel_test.py
+++ b/src/python/grpcio/tests/unit/beta/_connectivity_channel_test.py
@@ -29,162 +29,9 @@
 
 """Tests of grpc.beta._connectivity_channel."""
 
-import threading
-import time
 import unittest
 
-from grpc._adapter import _low
-from grpc._adapter import _types
-from grpc.beta import _connectivity_channel
 from grpc.beta import interfaces
-from tests.unit.framework.common import test_constants
-
-
-def _drive_completion_queue(completion_queue):
-  while True:
-    event = completion_queue.next(time.time() + 24 * 60 * 60)
-    if event.type == _types.EventType.QUEUE_SHUTDOWN:
-      break
-
-
-class _Callback(object):
-
-  def __init__(self):
-    self._condition = threading.Condition()
-    self._connectivities = []
-
-  def update(self, connectivity):
-    with self._condition:
-      self._connectivities.append(connectivity)
-      self._condition.notify()
-
-  def connectivities(self):
-    with self._condition:
-      return tuple(self._connectivities)
-
-  def block_until_connectivities_satisfy(self, predicate):
-    with self._condition:
-      while True:
-        connectivities = tuple(self._connectivities)
-        if predicate(connectivities):
-          return connectivities
-        else:
-          self._condition.wait()
-
-
-class ChannelConnectivityTest(unittest.TestCase):
-
-  def test_lonely_channel_connectivity(self):
-    low_channel = _low.Channel('localhost:12345', ())
-    callback = _Callback()
-
-    connectivity_channel = _connectivity_channel.ConnectivityChannel(
-        low_channel)
-    connectivity_channel.subscribe(callback.update, try_to_connect=False)
-    first_connectivities = callback.block_until_connectivities_satisfy(bool)
-    connectivity_channel.subscribe(callback.update, try_to_connect=True)
-    second_connectivities = callback.block_until_connectivities_satisfy(
-        lambda connectivities: 2 <= len(connectivities))
-    # Wait for a connection that will never happen.
-    time.sleep(test_constants.SHORT_TIMEOUT)
-    third_connectivities = callback.connectivities()
-    connectivity_channel.unsubscribe(callback.update)
-    fourth_connectivities = callback.connectivities()
-    connectivity_channel.unsubscribe(callback.update)
-    fifth_connectivities = callback.connectivities()
-
-    self.assertSequenceEqual(
-        (interfaces.ChannelConnectivity.IDLE,), first_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.READY, second_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.READY, third_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.READY, fourth_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.READY, fifth_connectivities)
-
-  def test_immediately_connectable_channel_connectivity(self):
-    server_completion_queue = _low.CompletionQueue()
-    server = _low.Server(server_completion_queue, [])
-    port = server.add_http2_port('[::]:0')
-    server.start()
-    server_completion_queue_thread = threading.Thread(
-        target=_drive_completion_queue, args=(server_completion_queue,))
-    server_completion_queue_thread.start()
-    low_channel = _low.Channel('localhost:%d' % port, ())
-    first_callback = _Callback()
-    second_callback = _Callback()
-
-    connectivity_channel = _connectivity_channel.ConnectivityChannel(
-        low_channel)
-    connectivity_channel.subscribe(first_callback.update, try_to_connect=False)
-    first_connectivities = first_callback.block_until_connectivities_satisfy(
-        bool)
-    # Wait for a connection that will never happen because try_to_connect=True
-    # has not yet been passed.
-    time.sleep(test_constants.SHORT_TIMEOUT)
-    second_connectivities = first_callback.connectivities()
-    connectivity_channel.subscribe(second_callback.update, try_to_connect=True)
-    third_connectivities = first_callback.block_until_connectivities_satisfy(
-        lambda connectivities: 2 <= len(connectivities))
-    fourth_connectivities = second_callback.block_until_connectivities_satisfy(
-        bool)
-    # Wait for a connection that will happen (or may already have happened).
-    first_callback.block_until_connectivities_satisfy(
-        lambda connectivities:
-        interfaces.ChannelConnectivity.READY in connectivities)
-    second_callback.block_until_connectivities_satisfy(
-        lambda connectivities:
-        interfaces.ChannelConnectivity.READY in connectivities)
-    connectivity_channel.unsubscribe(first_callback.update)
-    connectivity_channel.unsubscribe(second_callback.update)
-
-    server.shutdown()
-    server_completion_queue.shutdown()
-    server_completion_queue_thread.join()
-
-    self.assertSequenceEqual(
-        (interfaces.ChannelConnectivity.IDLE,), first_connectivities)
-    self.assertSequenceEqual(
-        (interfaces.ChannelConnectivity.IDLE,), second_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.TRANSIENT_FAILURE, third_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.FATAL_FAILURE, third_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.TRANSIENT_FAILURE,
-        fourth_connectivities)
-    self.assertNotIn(
-        interfaces.ChannelConnectivity.FATAL_FAILURE, fourth_connectivities)
-
-  def test_reachable_then_unreachable_channel_connectivity(self):
-    server_completion_queue = _low.CompletionQueue()
-    server = _low.Server(server_completion_queue, [])
-    port = server.add_http2_port('[::]:0')
-    server.start()
-    server_completion_queue_thread = threading.Thread(
-        target=_drive_completion_queue, args=(server_completion_queue,))
-    server_completion_queue_thread.start()
-    low_channel = _low.Channel('localhost:%d' % port, ())
-    callback = _Callback()
-
-    connectivity_channel = _connectivity_channel.ConnectivityChannel(
-        low_channel)
-    connectivity_channel.subscribe(callback.update, try_to_connect=True)
-    callback.block_until_connectivities_satisfy(
-        lambda connectivities:
-        interfaces.ChannelConnectivity.READY in connectivities)
-    # Now take down the server and confirm that channel readiness is repudiated.
-    server.shutdown()
-    callback.block_until_connectivities_satisfy(
-        lambda connectivities:
-        connectivities[-1] is not interfaces.ChannelConnectivity.READY)
-    connectivity_channel.unsubscribe(callback.update)
-
-    server.shutdown()
-    server_completion_queue.shutdown()
-    server_completion_queue_thread.join()
 
 
 class ConnectivityStatesTest(unittest.TestCase):
diff --git a/src/python/grpcio/tests/unit/beta/_utilities_test.py b/src/python/grpcio/tests/unit/beta/_utilities_test.py
index 08ce98e..90fe10c 100644
--- a/src/python/grpcio/tests/unit/beta/_utilities_test.py
+++ b/src/python/grpcio/tests/unit/beta/_utilities_test.py
@@ -33,21 +33,12 @@
 import time
 import unittest
 
-from grpc._adapter import _low
-from grpc._adapter import _types
 from grpc.beta import implementations
 from grpc.beta import utilities
 from grpc.framework.foundation import future
 from tests.unit.framework.common import test_constants
 
 
-def _drive_completion_queue(completion_queue):
-  while True:
-    event = completion_queue.next(time.time() + 24 * 60 * 60)
-    if event.type == _types.EventType.QUEUE_SHUTDOWN:
-      break
-
-
 class _Callback(object):
 
   def __init__(self):
@@ -87,13 +78,9 @@
     self.assertFalse(ready_future.running())
 
   def test_immediately_connectable_channel_connectivity(self):
-    server_completion_queue = _low.CompletionQueue()
-    server = _low.Server(server_completion_queue, [])
-    port = server.add_http2_port('[::]:0')
+    server = implementations.server({})
+    port = server.add_insecure_port('[::]:0')
     server.start()
-    server_completion_queue_thread = threading.Thread(
-        target=_drive_completion_queue, args=(server_completion_queue,))
-    server_completion_queue_thread.start()
     channel = implementations.insecure_channel('localhost', port)
     callback = _Callback()
 
@@ -114,9 +101,7 @@
       self.assertFalse(ready_future.running())
     finally:
       ready_future.cancel()
-      server.shutdown()
-      server_completion_queue.shutdown()
-      server_completion_queue_thread.join()
+      server.stop(0)
 
 
 if __name__ == '__main__':
diff --git a/src/python/grpcio/tests/unit/beta/test_utilities.py b/src/python/grpcio/tests/unit/beta/test_utilities.py
index 8ccad04..692da9c 100644
--- a/src/python/grpcio/tests/unit/beta/test_utilities.py
+++ b/src/python/grpcio/tests/unit/beta/test_utilities.py
@@ -51,5 +51,5 @@
   target = '%s:%d' % (host, port)
   channel = grpc.secure_channel(
       target, channel_credentials,
-      ((b'grpc.ssl_target_name_override', server_host_override,),))
+      (('grpc.ssl_target_name_override', server_host_override,),))
   return implementations.Channel(channel)
diff --git a/src/python/grpcio/tests/unit/test_common.py b/src/python/grpcio/tests/unit/test_common.py
index b779f65..c8886bf 100644
--- a/src/python/grpcio/tests/unit/test_common.py
+++ b/src/python/grpcio/tests/unit/test_common.py
@@ -33,10 +33,10 @@
 
 import six
 
-INVOCATION_INITIAL_METADATA = ((b'0', b'abc'), (b'1', b'def'), (b'2', b'ghi'),)
-SERVICE_INITIAL_METADATA = ((b'3', b'jkl'), (b'4', b'mno'), (b'5', b'pqr'),)
-SERVICE_TERMINAL_METADATA = ((b'6', b'stu'), (b'7', b'vwx'), (b'8', b'yza'),)
-DETAILS = b'test details'
+INVOCATION_INITIAL_METADATA = (('0', 'abc'), ('1', 'def'), ('2', 'ghi'),)
+SERVICE_INITIAL_METADATA = (('3', 'jkl'), ('4', 'mno'), ('5', 'pqr'),)
+SERVICE_TERMINAL_METADATA = (('6', 'stu'), ('7', 'vwx'), ('8', 'yza'),)
+DETAILS = 'test details'
 
 
 def metadata_transmitted(original_metadata, transmitted_metadata):
@@ -59,16 +59,10 @@
       original_metadata after having been transmitted via gRPC.
   """
   original = collections.defaultdict(list)
-  for key_value_pair in original_metadata:
-    key, value = tuple(key_value_pair)
-    if not isinstance(key, bytes):
-      key = key.encode()
-    if not isinstance(value, bytes):
-      value = value.encode()
+  for key, value in original_metadata:
     original[key].append(value)
   transmitted = collections.defaultdict(list)
-  for key_value_pair in transmitted_metadata:
-    key, value = tuple(key_value_pair)
+  for key, value in transmitted_metadata:
     transmitted[key].append(value)
 
   for key, values in six.iteritems(original):
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index aedeca2..d60d849 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -43,11 +43,11 @@
     Time.now + 5
   end
 
-  def server_allows_client_to_proceed
+  def server_allows_client_to_proceed(metadata = {})
     recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
     expect(recvd_rpc).to_not eq nil
     server_call = recvd_rpc.call
-    ops = { CallOps::SEND_INITIAL_METADATA => {} }
+    ops = { CallOps::SEND_INITIAL_METADATA => metadata }
     svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline, ops)
     expect(svr_batch.send_metadata).to be true
     server_call
@@ -135,6 +135,48 @@
     expect(svr_batch.send_message).to be true
   end
 
+  it 'compressed messages can be sent and received' do
+    call = new_client_call
+    server_call = nil
+    long_request_str = '0' * 2000
+    long_response_str = '1' * 2000
+    md = { 'grpc-internal-encoding-request' => 'gzip' }
+
+    server_thread = Thread.new do
+      server_call = server_allows_client_to_proceed(md)
+    end
+
+    client_ops = {
+      CallOps::SEND_INITIAL_METADATA => md,
+      CallOps::SEND_MESSAGE => long_request_str
+    }
+    batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+                                  client_ops)
+    expect(batch_result.send_metadata).to be true
+    expect(batch_result.send_message).to be true
+
+    # confirm the server can read the inbound message
+    server_thread.join
+    server_ops = {
+      CallOps::RECV_MESSAGE => nil,
+      CallOps::SEND_MESSAGE => long_response_str
+    }
+    svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
+                                      server_ops)
+    expect(svr_batch.message).to eq(long_request_str)
+    expect(svr_batch.send_message).to be true
+
+    client_ops = {
+      CallOps::SEND_CLOSE_FROM_CLIENT => nil,
+      CallOps::RECV_INITIAL_METADATA => nil,
+      CallOps::RECV_MESSAGE => nil
+    }
+    batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+                                  client_ops)
+    expect(batch_result.send_close).to be true
+    expect(batch_result.message).to eq long_response_str
+  end
+
   it 'servers can ignore a client write and send a status' do
     call = new_client_call
     server_call = nil
diff --git a/templates/package.xml.template b/templates/package.xml.template
index a620a2d..d8155cd 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -12,7 +12,7 @@
     <email>grpc-packages@google.com</email>
     <active>yes</active>
    </lead>
-   <date>2016-05-19</date>
+   <date>2016-06-30</date>
    <time>16:06:07</time>
    <version>
     <release>${settings.php_version.php()}</release>
@@ -24,7 +24,7 @@
    </stability>
    <license>BSD</license>
    <notes>
-  - TBD
+  - Fix shutdown hang problem #4017
    </notes>
    <contents>
     <dir baseinstalldir="/" name="/">
@@ -153,6 +153,7 @@
      <license>BSD</license>
      <notes>
   - Simplify gRPC PHP installation #4517
+  - Wrap gRPC core library version 0.13
      </notes>
     </release>
     <release>
@@ -182,13 +183,14 @@
      <date>2016-04-19</date>
      <license>BSD</license>
      <notes>
+  - wrap grpc C core version 0.14.0
   - destroy grpc_byte_buffer after startBatch #6096
      </notes>
     </release>
     <release>
      <version>
-      <release>0.14.2</release>
-      <api>0.14.2</api>
+      <release>0.15.0</release>
+      <api>0.15.0</api>
      </version>
      <stability>
       <release>beta</release>
@@ -198,6 +200,22 @@
      <license>BSD</license>
      <notes>
   - Updated functions with TSRM macros for ZTS support #6607
+  - Load default roots.pem via grpc_set_ssl_roots_override_callback #6848
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.15.1</release>
+      <api>0.15.1</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2016-06-30</date>
+     <license>BSD</license>
+     <notes>
+  - Fix shutdown hang problem #4017
      </notes>
     </release>
    </changelog>
diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template
index 90ad0eb..d91bd8c 100644
--- a/templates/src/csharp/Grpc.Auth/project.json.template
+++ b/templates/src/csharp/Grpc.Auth/project.json.template
@@ -14,6 +14,15 @@
       "requireLicenseAcceptance": false,
       "tags": [ "gRPC RPC Protocol HTTP/2 Auth OAuth2" ],
     },
+    "buildOptions": {
+      "define": [ "SIGNED" ],
+      "keyFile": "../keys/Grpc.snk",
+      "publicSign": true,
+      "xmlDoc": true,
+      "compile": {
+        "includeFiles": [ "../Grpc.Core/Version.cs" ]
+      }
+    },
     "dependencies": {
       "Grpc.Core": "${settings.csharp_version}",
       "Google.Apis.Auth": "1.11.1"
diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template
index 6f9197f..cdcebc5 100644
--- a/templates/src/csharp/Grpc.Core/project.json.template
+++ b/templates/src/csharp/Grpc.Core/project.json.template
@@ -14,17 +14,23 @@
       "requireLicenseAcceptance": false,
       "tags": [ "gRPC RPC Protocol HTTP/2" ],
       "files": {
-        "build/net45/": "Grpc.Core.targets",
-        "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll",
-        "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll",
-        "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so",
-        "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so",
-        "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib",
-        "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib"
+        "mappings": {
+          "build/net45/": "Grpc.Core.targets",
+          "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll",
+          "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll",
+          "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so",
+          "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so",
+          "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib",
+          "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib"
+        }
       }
     },
     "buildOptions": {
-      "embed": [ "../../../etc/roots.pem" ]
+      "embed": [ "../../../etc/roots.pem" ],
+      "define": [ "SIGNED" ],
+      "keyFile": "../keys/Grpc.snk",
+      "publicSign": true,
+      "xmlDoc": true
     },
     "dependencies": {
       "Ix-Async": "1.2.5"
diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template
index 59073af..264ed29 100644
--- a/templates/src/csharp/Grpc.HealthCheck/project.json.template
+++ b/templates/src/csharp/Grpc.HealthCheck/project.json.template
@@ -14,6 +14,15 @@
       "requireLicenseAcceptance": false,
       "tags": [ "gRPC health check" ]
     },
+    "buildOptions": {
+      "define": [ "SIGNED" ],
+      "keyFile": "../keys/Grpc.snk",
+      "publicSign": true,
+      "xmlDoc": true,
+      "compile": {
+        "includeFiles": [ "../Grpc.Core/Version.cs" ]
+      }
+    },
     "dependencies": {
       "Grpc.Core": "${settings.csharp_version}",
       "Google.Protobuf": "3.0.0-beta3"
diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include
index 468d281..ae96b94 100644
--- a/templates/src/csharp/build_options.include
+++ b/templates/src/csharp/build_options.include
@@ -8,6 +8,13 @@
   "configurations": {
     "Debug": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           % if includeData:
           "include": "data/*",
@@ -23,6 +30,13 @@
     },
     "Release": {
       "buildOptions": {
+        "define": [ "SIGNED" ],
+        "keyFile": "../keys/Grpc.snk",
+        "publicSign": true,
+        "xmlDoc": true,
+        "compile": {
+          "includeFiles": [ "../Grpc.Core/Version.cs" ]
+        },
         "copyToOutput": {
           % if includeData:
           "include": "data/*",
diff --git a/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
index 35782d6..e9cab57 100644
--- a/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
@@ -29,9 +29,25 @@
   # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   
-  FROM microsoft/dotnet:1.0.0-preview1
+  FROM debian:jessie
   
   <%include file="../../apt_get_basic.include"/>
+  <%include file="../../csharp_deps.include"/>
+  
+  # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+  RUN apt-get update && apt-get install -y curl libunwind8 gettext
+  RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+  RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+  RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+  
+  # Trigger the population of the local package cache
+  ENV NUGET_XMLDOC_MODE skip
+  RUN mkdir warmup ${'\\'}
+      && cd warmup ${'\\'}
+      && dotnet new ${'\\'}
+      && cd .. ${'\\'}
+      && rm -rf warmup
+  
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c
index 7e76283..1020784 100644
--- a/test/core/end2end/tests/network_status_change.c
+++ b/test/core/end2end/tests/network_status_change.c
@@ -212,7 +212,6 @@
 
   // Expected behavior of a RPC when network is lost.
   GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
-  GPR_ASSERT(0 == strcmp(details, ""));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
   GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c
index 1b40895..9038d07 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.c
+++ b/test/core/network_benchmarks/low_level_ping_pong.c
@@ -583,7 +583,7 @@
     return rv;
   }
 
-  gpr_log(GPR_INFO, "Starting test %s %s %d", client_args->strategy_name,
+  gpr_log(GPR_INFO, "Starting test %s %s %zu", client_args->strategy_name,
           socket_type, client_args->msg_size);
 
   gpr_thd_new(&tid, server_thread_wrap, server_args, NULL);
diff --git a/test/core/profiling/timers_test.c b/test/core/profiling/timers_test.c
deleted file mode 100644
index 284589a..0000000
--- a/test/core/profiling/timers_test.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/profiling/timers.h"
-#include <stdlib.h>
-#include "test/core/util/test_config.h"
-
-void test_log_events(size_t num_seqs) {
-  size_t start = 0;
-  size_t *state;
-  state = calloc(num_seqs, sizeof(state[0]));
-  while (start < num_seqs) {
-    size_t i;
-    size_t row;
-    if (state[start] == 3) { /* Already done with this posn */
-      start++;
-      continue;
-    }
-
-    row = (size_t)rand() % 10; /* how many in a row */
-    for (i = start; (i < start + row) && (i < num_seqs); i++) {
-      size_t j;
-      size_t advance = 1 + (size_t)rand() % 3; /* how many to advance by */
-      for (j = 0; j < advance; j++) {
-        switch (state[i]) {
-          case 0:
-            GPR_TIMER_MARK(STATE_0, i);
-            state[i]++;
-            break;
-          case 1:
-            GPR_TIMER_MARK(STATE_1, i);
-            state[i]++;
-            break;
-          case 2:
-            GPR_TIMER_MARK(STATE_2, i);
-            state[i]++;
-            break;
-          case 3:
-            break;
-        }
-      }
-    }
-  }
-  free(state);
-}
-
-int main(int argc, char **argv) {
-  grpc_test_init(argc, argv);
-  gpr_timers_global_init();
-  test_log_events(1000000);
-  gpr_timers_global_destroy();
-  return 0;
-}
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 89f841d..8861bc1 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -576,11 +576,10 @@
   if (k < sizes.size()) {
     // stream->Read() failed before reading all the expected messages. This
     // is most likely due to a connection failure.
-    gpr_log(GPR_ERROR, "%s(): Responses read (k=%" PRIuPTR
-                       ") is "
-                       "less than the expected messages (i.e "
-                       "response_stream_sizes.size() (%" PRIuPTR ")).",
-            __func__, k, response_stream_sizes.size());
+    gpr_log(GPR_ERROR,
+            "%s(): Responses read (k=%" PRIuPTR
+            ") is less than the expected number of  messages (%" PRIuPTR ").",
+            __func__, k, sizes.size());
     return TransientFailureOrAbort();
   }
 
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 3d98ab0..1507d1e 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -180,14 +180,14 @@
 
     using namespace std::placeholders;
     int t = 0;
-    for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
-      for (int ch = 0; ch < config.client_channels(); ch++) {
+    for (int ch = 0; ch < config.client_channels(); ch++) {
+      for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
         auto* cq = cli_cqs_[t].get();
         auto ctx =
             setup_ctx(channels_[ch].get_stub(), next_issuers_[t], request_);
         ctx->Start(cq);
-        t = (t + 1) % cli_cqs_.size();
       }
+      t = (t + 1) % cli_cqs_.size();
     }
   }
   virtual ~AsyncClient() {
diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst
index e9f1374..8946a1d 100644
--- a/tools/distrib/python/grpcio_tools/README.rst
+++ b/tools/distrib/python/grpcio_tools/README.rst
@@ -53,7 +53,7 @@
 ::
 
   $ export REPO_ROOT=grpc  # REPO_ROOT can be any directory of your choice
-  $ git clone https://github.com/grpc/grpc.git $REPO_ROOT
+  $ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc $REPO_ROOT
   $ cd $REPO_ROOT
   $ git submodule update --init
 
diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
index 9dfc040..fd72157 100644
--- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
@@ -27,7 +27,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-FROM microsoft/dotnet:1.0.0-preview1
+FROM debian:jessie
 
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y \
@@ -63,6 +63,38 @@
 # Build profiling
 RUN apt-get update && apt-get install -y time && apt-get clean
 
+#================
+# C# dependencies
+
+# Update to a newer version of mono
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+
+# Install dependencies
+RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
+    mono-devel \
+    ca-certificates-mono \
+    nuget \
+    && apt-get clean
+
+
+# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+RUN apt-get update && apt-get install -y curl libunwind8 gettext
+RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+
+# Trigger the population of the local package cache
+ENV NUGET_XMLDOC_MODE skip
+RUN mkdir warmup \
+    && cd warmup \
+    && dotnet new \
+    && cd .. \
+    && rm -rf warmup
+
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
 RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 163e9ff..b846237 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -861,7 +861,6 @@
 src/core/lib/surface/init.h \
 src/core/lib/surface/lame_client.h \
 src/core/lib/surface/server.h \
-src/core/lib/surface/surface_trace.h \
 src/core/lib/transport/byte_stream.h \
 src/core/lib/transport/connectivity_state.h \
 src/core/lib/transport/metadata.h \
diff --git a/tools/run_tests/build_csharp_coreclr.sh b/tools/run_tests/build_csharp_coreclr.sh
index 68c19cb..733b1a2 100755
--- a/tools/run_tests/build_csharp_coreclr.sh
+++ b/tools/run_tests/build_csharp_coreclr.sh
@@ -36,7 +36,3 @@
 dotnet restore .
 
 dotnet build -f netstandard1.5 --configuration $MSBUILD_CONFIG '**/project.json'
-
-# Grpc.IntegrationTesting doesn't get built by the previous command for some reason.
-# TODO(jtattermusch): get rid of the hack
-dotnet build -f netstandard1.5 --configuration $MSBUILD_CONFIG Grpc.IntegrationTesting/project.json
diff --git a/tools/run_tests/build_package_csharp_coreclr.sh b/tools/run_tests/build_package_csharp_coreclr.sh
new file mode 100755
index 0000000..e1c363d
--- /dev/null
+++ b/tools/run_tests/build_package_csharp_coreclr.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+cd $(dirname $0)/../..
+
+mkdir -p artifacts/
+
+cd src/csharp
+
+# IMPORTANT: NuGet packages generated by dotnet CLI are considered experimental.
+# The official nugets are generated by src/csharp/build_packages.bat
+
+mkdir -p nativelibs/windows_x86 nativelibs/windows_x64 \
+    nativelibs/linux_x86 nativelibs/linux_x64 \
+    nativelibs/macosx_x86 nativelibs/macosx_x64
+
+cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=windows/artifacts/* nativelibs/windows_x86 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=windows/artifacts/* nativelibs/windows_x64 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=linux/artifacts/* nativelibs/linux_x86 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=linux/artifacts/* nativelibs/linux_x64 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=macos/artifacts/* nativelibs/macosx_x86 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=macos/artifacts/* nativelibs/macosx_x64 || true
+
+dotnet restore .
+
+dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
+dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
+dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
+
+tar -czf ../../artifacts/csharp_nugets_experimental.tar.gz ../../artifacts/*.nupkg
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py
index 820b539..39a11a2 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/package_targets.py
@@ -71,18 +71,29 @@
 class CSharpPackage:
   """Builds C# nuget packages."""
 
-  def __init__(self):
-    self.name = 'csharp_package'
-    self.labels = ['package', 'csharp', 'windows']
+  def __init__(self, use_coreclr=False):
+    self.use_coreclr = use_coreclr
+    self.name = 'csharp_package_coreclr' if use_coreclr else 'csharp_package'
+    self.labels = ['package', 'csharp']
+    if use_coreclr:
+      self.labels += ['linux']
+    else:
+      self.labels += ['windows']
 
   def pre_build_jobspecs(self):
     return []
 
   def build_jobspec(self):
-    return create_jobspec(self.name,
-                          ['build_packages.bat'],
-                          cwd='src\\csharp',
-                          shell=True)
+    if self.use_coreclr:
+      return create_docker_jobspec(
+          self.name,
+          'tools/dockerfile/test/csharp_coreclr_x64',
+          'tools/run_tests/build_package_csharp_coreclr.sh')
+    else:
+      return create_jobspec(self.name,
+                            ['build_packages.bat'],
+                            cwd='src\\csharp',
+                            shell=True)
 
   def __str__(self):
     return self.name
@@ -159,6 +170,7 @@
 def targets():
   """Gets list of supported targets"""
   return [CSharpPackage(),
+          CSharpPackage(use_coreclr=True),
           NodePackage(),
           RubyPackage(),
           PythonPackage(),
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 3798bf4..28a93dd 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -522,7 +522,7 @@
       if self.platform == 'linux':
         assembly_subdir += '/netstandard1.5/debian.8-x64'
         assembly_extension = ''
-      if self.platform == 'mac':
+      elif self.platform == 'mac':
         assembly_subdir += '/netstandard1.5/osx.10.11-x64'
         assembly_extension = ''
       else:
@@ -1055,7 +1055,7 @@
   try:
     version = int(urllib2.urlopen(
         'http://localhost:%d/version_number' % port_server_port,
-        timeout=1).read())
+        timeout=10).read())
     print 'detected port server running version %d' % version
     running = True
   except Exception as e:
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 6c59715..65de89c 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1720,22 +1720,6 @@
     ], 
     "headers": [], 
     "language": "c", 
-    "name": "timers_test", 
-    "src": [
-      "test/core/profiling/timers_test.c"
-    ], 
-    "third_party": false, 
-    "type": "target"
-  }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_test_util", 
-      "grpc", 
-      "grpc_test_util"
-    ], 
-    "headers": [], 
-    "language": "c", 
     "name": "transport_connectivity_state_test", 
     "src": [
       "test/core/transport/connectivity_state_test.c"
@@ -5701,19 +5685,6 @@
   }, 
   {
     "deps": [
-      "grpc++_codegen_base"
-    ], 
-    "headers": [], 
-    "language": "c", 
-    "name": "grpc++_codegen_base_src", 
-    "src": [
-      "src/cpp/codegen/codegen_init.cc"
-    ], 
-    "third_party": false, 
-    "type": "filegroup"
-  }, 
-  {
-    "deps": [
       "gpr", 
       "grpc_codegen"
     ], 
@@ -5795,7 +5766,6 @@
       "src/core/lib/surface/init.h", 
       "src/core/lib/surface/lame_client.h", 
       "src/core/lib/surface/server.h", 
-      "src/core/lib/surface/surface_trace.h", 
       "src/core/lib/transport/byte_stream.h", 
       "src/core/lib/transport/connectivity_state.h", 
       "src/core/lib/transport/metadata.h", 
@@ -5962,7 +5932,6 @@
       "src/core/lib/surface/metadata_array.c", 
       "src/core/lib/surface/server.c", 
       "src/core/lib/surface/server.h", 
-      "src/core/lib/surface/surface_trace.h", 
       "src/core/lib/surface/validate_metadata.c", 
       "src/core/lib/surface/version.c", 
       "src/core/lib/transport/byte_stream.c", 
@@ -6748,6 +6717,19 @@
   }, 
   {
     "deps": [
+      "grpc++_codegen_base"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "grpc++_codegen_base_src", 
+    "src": [
+      "src/cpp/codegen/codegen_init.cc"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
       "grpc++_codegen_base", 
       "grpc++_config_proto"
     ], 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 1c97e9a..dedd557 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -1826,27 +1826,6 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "timers_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
     "name": "transport_connectivity_state_test", 
     "platforms": [
       "linux", 
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index a847add..10be520 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -1364,17 +1364,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timers_test", "vcxproj\test\timers_test\timers_test.vcxproj", "{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "transport_connectivity_state_test", "vcxproj\test\transport_connectivity_state_test\transport_connectivity_state_test.vcxproj", "{659121F6-1639-AC6B-053E-9D17A8B94D56}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -3476,22 +3465,6 @@
 		{C43EA45B-1E72-C58D-8CE3-A879D1B1E2DB}.Release-DLL|Win32.Build.0 = Release|Win32
 		{C43EA45B-1E72-C58D-8CE3-A879D1B1E2DB}.Release-DLL|x64.ActiveCfg = Release|x64
 		{C43EA45B-1E72-C58D-8CE3-A879D1B1E2DB}.Release-DLL|x64.Build.0 = Release|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug|Win32.ActiveCfg = Debug|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug|x64.ActiveCfg = Debug|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release|Win32.ActiveCfg = Release|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release|x64.ActiveCfg = Release|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug|Win32.Build.0 = Debug|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug|x64.Build.0 = Debug|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release|Win32.Build.0 = Release|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release|x64.Build.0 = Release|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Debug-DLL|x64.Build.0 = Debug|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release-DLL|Win32.Build.0 = Release|Win32
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release-DLL|x64.ActiveCfg = Release|x64
-		{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}.Release-DLL|x64.Build.0 = Release|x64
 		{659121F6-1639-AC6B-053E-9D17A8B94D56}.Debug|Win32.ActiveCfg = Debug|Win32
 		{659121F6-1639-AC6B-053E-9D17A8B94D56}.Debug|x64.ActiveCfg = Debug|x64
 		{659121F6-1639-AC6B-053E-9D17A8B94D56}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index c0c1972..a9e96da 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -370,7 +370,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\surface_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index a2758e8..be77e53 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -866,9 +866,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\surface_trace.h">
-      <Filter>src\core\lib\surface</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h">
       <Filter>src\core\lib\transport</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 1993af0..1cfe06a 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -359,7 +359,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\surface_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index ca17396..c33c665 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -773,9 +773,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h">
       <Filter>src\core\lib\surface</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\surface_trace.h">
-      <Filter>src\core\lib\surface</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h">
       <Filter>src\core\lib\transport</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/timers_test/timers_test.vcxproj b/vsprojects/vcxproj/test/timers_test/timers_test.vcxproj
deleted file mode 100644
index fa1ba6a..0000000
--- a/vsprojects/vcxproj/test/timers_test/timers_test.vcxproj
+++ /dev/null
@@ -1,199 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{FFE98236-3F4D-2CBA-29FB-D0A7467D2FA5}</ProjectGuid>
-    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
-    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
-    <PlatformToolset>v100</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
-    <PlatformToolset>v110</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
-    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
-    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
-    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>timers_test</TargetName>
-    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
-    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
-    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
-    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>timers_test</TargetName>
-    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
-    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
-    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
-    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
-  </PropertyGroup>
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\profiling\timers_test.c">
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
-      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
-      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
-      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
-      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
-  </ImportGroup>
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
-  </Target>
-</Project>
-
diff --git a/vsprojects/vcxproj/test/timers_test/timers_test.vcxproj.filters b/vsprojects/vcxproj/test/timers_test/timers_test.vcxproj.filters
deleted file mode 100644
index d4901c4..0000000
--- a/vsprojects/vcxproj/test/timers_test/timers_test.vcxproj.filters
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\profiling\timers_test.c">
-      <Filter>test\core\profiling</Filter>
-    </ClCompile>
-  </ItemGroup>
-
-  <ItemGroup>
-    <Filter Include="test">
-      <UniqueIdentifier>{babbbe28-0bb3-2bc8-dee6-43fe0bef8f98}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="test\core">
-      <UniqueIdentifier>{f321526c-3617-e2b9-8f09-2e15e92bc30a}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="test\core\profiling">
-      <UniqueIdentifier>{62fa1b4c-6baf-0b0c-52a9-a5694834dbbb}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-</Project>
-