Merge pull request #3007 from jboeuf/core_md_processor_fixes

Have a richer interface for auth metadata processors.
diff --git a/Makefile b/Makefile
index f3944ec..31628b4 100644
--- a/Makefile
+++ b/Makefile
@@ -889,6 +889,7 @@
 secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test
 server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
 server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
+shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
 status_test: $(BINDIR)/$(CONFIG)/status_test
 sync_streaming_ping_pong_test: $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test
 sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test
@@ -1735,7 +1736,7 @@
 buildtests_cxx: buildtests_zookeeper privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/auth_property_iterator_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test $(BINDIR)/$(CONFIG)/cxx_slice_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/dynamic_thread_pool_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/fixed_size_thread_pool_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/mock_test $(BINDIR)/$(CONFIG)/qps_interarrival_test $(BINDIR)/$(CONFIG)/qps_openloop_test $(BINDIR)/$(CONFIG)/qps_test $(BINDIR)/$(CONFIG)/reconnect_interop_client $(BINDIR)/$(CONFIG)/reconnect_interop_server $(BINDIR)/$(CONFIG)/secure_auth_context_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_stress_test
 
 ifeq ($(HAS_ZOOKEEPER),true)
-buildtests_zookeeper: privatelibs_zookeeper $(BINDIR)/$(CONFIG)/zookeeper_test
+buildtests_zookeeper: privatelibs_zookeeper $(BINDIR)/$(CONFIG)/shutdown_test $(BINDIR)/$(CONFIG)/zookeeper_test
 else
 buildtests_zookeeper:
 endif
@@ -3363,6 +3364,8 @@
 
 ifeq ($(HAS_ZOOKEEPER),true)
 test_zookeeper: buildtests_zookeeper
+	$(E) "[RUN]     Testing shutdown_test"
+	$(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing zookeeper_test"
 	$(Q) $(BINDIR)/$(CONFIG)/zookeeper_test || ( echo test zookeeper_test failed ; exit 1 )
 
@@ -10262,6 +10265,46 @@
 endif
 
 
+SHUTDOWN_TEST_SRC = \
+    test/cpp/end2end/shutdown_test.cc \
+
+SHUTDOWN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SHUTDOWN_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/shutdown_test: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/shutdown_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -lzookeeper_mt $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/shutdown_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+deps_shutdown_test: $(SHUTDOWN_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SHUTDOWN_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 STATUS_TEST_SRC = \
     test/cpp/util/status_test.cc \
 
diff --git a/build.json b/build.json
index 85457dd..bd707d2 100644
--- a/build.json
+++ b/build.json
@@ -2488,6 +2488,9 @@
         "gpr",
         "grpc++_test_config"
       ],
+      "exclude_configs": [
+        "tsan"
+      ],
       "platforms": [
         "mac",
         "linux",
@@ -2611,6 +2614,26 @@
       ]
     },
     {
+      "name": "shutdown_test",
+      "build": "test",
+      "language": "c++",
+      "src": [
+        "test/cpp/end2end/shutdown_test.cc"
+      ],
+      "deps": [
+        "grpc++_test_util",
+        "grpc_test_util",
+        "grpc++",
+        "grpc_zookeeper",
+        "grpc",
+        "gpr_test_util",
+        "gpr"
+      ],
+      "external_deps": [
+        "zookeeper"
+      ]
+    },
+    {
       "name": "status_test",
       "build": "test",
       "language": "c++",
diff --git a/doc/connection-backoff-interop-test-description.md b/doc/connection-backoff-interop-test-description.md
index 0f00c86..6440543 100644
--- a/doc/connection-backoff-interop-test-description.md
+++ b/doc/connection-backoff-interop-test-description.md
@@ -31,9 +31,9 @@
 * --server_retry_port=PORT
     * The server port to connect to for testing backoffs. For example, "8081"
 
-The client must connect to the control port without TLS. The client should
-either assert on the server returned backoff status or check the returned
-backoffs on its own.
+The client must connect to the control port without TLS. The client must connect
+to the retry port with TLS. The client should either assert on the server
+returned backoff status or check the returned backoffs on its own.
 
 Procedure of client:
 
diff --git a/doc/connection-backoff.md b/doc/connection-backoff.md
index 7094e73..251a60f 100644
--- a/doc/connection-backoff.md
+++ b/doc/connection-backoff.md
@@ -44,3 +44,12 @@
 Alternate implementations must ensure that connection backoffs started at the
 same time disperse, and must not attempt connections substantially more often
 than the above algorithm.
+
+## Reset Backoff
+
+The back off should be reset to INITIAL_BACKOFF at some time point, so that the
+reconnecting behavior is consistent no matter the connection is a newly started
+one or a previously disconnected one.
+
+We choose to reset the Backoff when the SETTINGS frame is received, at that time
+point, we know for sure that this connection was accepted by the server.
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 99f288d..a2bc097 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -63,7 +63,14 @@
   ~Server();
 
   // Shutdown the server, block until all rpc processing finishes.
-  void Shutdown();
+  // Forcefully terminate pending calls after deadline expires.
+  template <class T>
+  void Shutdown(const T& deadline) {
+    ShutdownInternal(TimePoint<T>(deadline).raw_time());
+  }
+
+  // Shutdown the server, waiting for all rpc processing to finish.
+  void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
 
   // Block waiting for all work to complete (the server must either
   // be shutting down or some other thread must call Shutdown for this
@@ -99,6 +106,8 @@
 
   void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
 
+  void ShutdownInternal(gpr_timespec deadline);
+
   class BaseAsyncRequest : public CompletionQueueTag {
    public:
     BaseAsyncRequest(Server* server, ServerContext* context,
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index e35fb03..9924bae 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -67,7 +67,9 @@
                                      grpc_compression_algorithm *algorithm);
 
 /** Updates \a name with the encoding name corresponding to a valid \a
- * algorithm.  Returns 1 upon success, 0 otherwise. */
+ * algorithm. Note that the string returned through \a name upon success is
+ * statically allocated and shouldn't be freed. Returns 1 upon success, 0
+ * otherwise. */
 int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
                                     char **name);
 
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 2220e8f..7869e92 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -386,13 +386,6 @@
     the reverse order they were initialized. */
 void grpc_register_plugin(void (*init)(void), void (*destroy)(void));
 
-/** Frees the memory used by all the plugin information.
-
-    While grpc_init and grpc_shutdown can be called multiple times, the plugins
-    won't be unregistered and their memory cleaned up unless you call that
-    function. Using atexit(grpc_unregister_all_plugins) is a valid method. */
-void grpc_unregister_all_plugins();
-
 /* Propagation bits: this can be bitwise or-ed to form propagation_mask for
  * grpc_call */
 /** Propagate deadline */
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c
index 20d723b..762a4ed 100644
--- a/src/core/channel/compress_filter.c
+++ b/src/core/channel/compress_filter.c
@@ -216,7 +216,7 @@
                                   [calld->compression_algorithm]));
 
           /* convey supported compression algorithms */
-          grpc_metadata_batch_add_head(
+          grpc_metadata_batch_add_tail(
               &(sop->data.metadata), &calld->accept_encoding_storage,
               GRPC_MDELEM_REF(channeld->mdelem_accept_encoding));
 
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 27472f4..e039c07 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -90,6 +90,26 @@
     return mrd;
   }
 
+  static bool AsyncWait(CompletionQueue* cq, SyncRequest** req, bool* ok,
+                        gpr_timespec deadline) {
+    void* tag = nullptr;
+    *ok = false;
+    switch (cq->AsyncNext(&tag, ok, deadline)) {
+      case CompletionQueue::TIMEOUT:
+        *req = nullptr;
+        return true;
+      case CompletionQueue::SHUTDOWN:
+        *req = nullptr;
+        return false;
+      case CompletionQueue::GOT_EVENT:
+        *req = static_cast<SyncRequest*>(tag);
+        GPR_ASSERT((*req)->in_flight_);
+        return true;
+    }
+    gpr_log(GPR_ERROR, "Should never reach here");
+    abort();
+  }
+
   void SetupRequest() { cq_ = grpc_completion_queue_create(nullptr); }
 
   void TeardownRequest() {
@@ -303,12 +323,27 @@
   return true;
 }
 
-void Server::Shutdown() {
+void Server::ShutdownInternal(gpr_timespec deadline) {
   grpc::unique_lock<grpc::mutex> lock(mu_);
   if (started_ && !shutdown_) {
     shutdown_ = true;
     grpc_server_shutdown_and_notify(server_, cq_.cq(), new ShutdownRequest());
     cq_.Shutdown();
+    // Spin, eating requests until the completion queue is completely shutdown.
+    // If the deadline expires then cancel anything that's pending and keep
+    // spinning forever until the work is actually drained.
+    // Since nothing else needs to touch state guarded by mu_, holding it 
+    // through this loop is fine.
+    SyncRequest* request;
+    bool ok;
+    while (SyncRequest::AsyncWait(&cq_, &request, &ok, deadline)) {
+      if (request == NULL) {  // deadline expired
+        grpc_server_cancel_all_calls(server_);
+        deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+      } else if (ok) {
+        SyncRequest::CallData call_data(this, request);
+      }
+    }
 
     // Wait for running callbacks to finish.
     while (num_running_cb_ != 0) {
diff --git a/src/csharp/.gitignore b/src/csharp/.gitignore
index ae48956..48365e3 100644
--- a/src/csharp/.gitignore
+++ b/src/csharp/.gitignore
@@ -5,4 +5,5 @@
 packages
 Grpc.v12.suo
 TestResult.xml
+/TestResults
 *.nupkg
diff --git a/src/csharp/Grpc.Core.Tests/ChannelTest.cs b/src/csharp/Grpc.Core.Tests/ChannelTest.cs
index 2787572..dfbd928 100644
--- a/src/csharp/Grpc.Core.Tests/ChannelTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ChannelTest.cs
@@ -41,12 +41,6 @@
 {
     public class ChannelTest
     {
-        [TestFixtureTearDown]
-        public void CleanupClass()
-        {
-            GrpcEnvironment.Shutdown();
-        }
-
         [Test]
         public void Constructor_RejectsInvalidParams()
         {
@@ -56,36 +50,33 @@
         [Test]
         public void State_IdleAfterCreation()
         {
-            using (var channel = new Channel("localhost", Credentials.Insecure))
-            {
-                Assert.AreEqual(ChannelState.Idle, channel.State);
-            }
+            var channel = new Channel("localhost", Credentials.Insecure);
+            Assert.AreEqual(ChannelState.Idle, channel.State);
+            channel.ShutdownAsync().Wait();
         }
 
         [Test]
         public void WaitForStateChangedAsync_InvalidArgument()
         {
-            using (var channel = new Channel("localhost", Credentials.Insecure))
-            {
-                Assert.Throws(typeof(ArgumentException), () => channel.WaitForStateChangedAsync(ChannelState.FatalFailure));
-            }
+            var channel = new Channel("localhost", Credentials.Insecure);
+            Assert.Throws(typeof(ArgumentException), () => channel.WaitForStateChangedAsync(ChannelState.FatalFailure));
+            channel.ShutdownAsync().Wait();
         }
 
         [Test]
         public void ResolvedTarget()
         {
-            using (var channel = new Channel("127.0.0.1", Credentials.Insecure))
-            {
-                Assert.IsTrue(channel.ResolvedTarget.Contains("127.0.0.1"));
-            }
+            var channel = new Channel("127.0.0.1", Credentials.Insecure);
+            Assert.IsTrue(channel.ResolvedTarget.Contains("127.0.0.1"));
+            channel.ShutdownAsync().Wait();
         }
 
         [Test]
-        public void Dispose_IsIdempotent()
+        public void Shutdown_AllowedOnlyOnce()
         {
             var channel = new Channel("localhost", Credentials.Insecure);
-            channel.Dispose();
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
+            Assert.Throws(typeof(InvalidOperationException), () => channel.ShutdownAsync().GetAwaiter().GetResult());
         }
     }
 }
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index e49fdb5..68279a2 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -63,16 +63,10 @@
         [TearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
         }
 
-        [TestFixtureTearDown]
-        public void CleanupClass()
-        {
-            GrpcEnvironment.Shutdown();
-        }
-
         [Test]
         public async Task UnaryCall()
         {
@@ -208,13 +202,6 @@
         }
 
         [Test]
-        public void UnaryCall_DisposedChannel()
-        {
-            channel.Dispose();
-            Assert.Throws(typeof(ObjectDisposedException), () => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "ABC"));
-        }
-
-        [Test]
         public void UnaryCallPerformance()
         {
             helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
diff --git a/src/csharp/Grpc.Core.Tests/CompressionTest.cs b/src/csharp/Grpc.Core.Tests/CompressionTest.cs
index 9547683..378c818 100644
--- a/src/csharp/Grpc.Core.Tests/CompressionTest.cs
+++ b/src/csharp/Grpc.Core.Tests/CompressionTest.cs
@@ -62,16 +62,10 @@
         [TearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
         }
 
-        [TestFixtureTearDown]
-        public void CleanupClass()
-        {
-            GrpcEnvironment.Shutdown();
-        }
-
         [Test]
         public void WriteOptions_Unary()
         {
diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
index db5f953..2db3f28 100644
--- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
@@ -62,16 +62,10 @@
         [TearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
         }
 
-        [TestFixtureTearDown]
-        public void CleanupClass()
-        {
-            GrpcEnvironment.Shutdown();
-        }
-
         [Test]
         public async Task PropagateCancellation()
         {
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index d6a8f52..b571fe9 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -64,6 +64,8 @@
       <Link>Version.cs</Link>
     </Compile>
     <Compile Include="ClientBaseTest.cs" />
+    <Compile Include="ShutdownTest.cs" />
+    <Compile Include="Internal\AsyncCallTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ClientServerTest.cs" />
     <Compile Include="ServerTest.cs" />
@@ -82,6 +84,7 @@
     <Compile Include="ResponseHeadersTest.cs" />
     <Compile Include="CompressionTest.cs" />
     <Compile Include="ContextPropagationTest.cs" />
+    <Compile Include="MetadataTest.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
index 4ed93c7..78295cf 100644
--- a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
+++ b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
@@ -43,31 +43,40 @@
         [Test]
         public void InitializeAndShutdownGrpcEnvironment()
         {
-            var env = GrpcEnvironment.GetInstance();
+            var env = GrpcEnvironment.AddRef();
             Assert.IsNotNull(env.CompletionQueue);
-            GrpcEnvironment.Shutdown();
+            GrpcEnvironment.Release();
         }
 
         [Test]
         public void SubsequentInvocations()
         {
-            var env1 = GrpcEnvironment.GetInstance();
-            var env2 = GrpcEnvironment.GetInstance();
-            Assert.IsTrue(object.ReferenceEquals(env1, env2));
-            GrpcEnvironment.Shutdown();
-            GrpcEnvironment.Shutdown();
+            var env1 = GrpcEnvironment.AddRef();
+            var env2 = GrpcEnvironment.AddRef();
+            Assert.AreSame(env1, env2);
+            GrpcEnvironment.Release();
+            GrpcEnvironment.Release();
         }
 
         [Test]
         public void InitializeAfterShutdown()
         {
-            var env1 = GrpcEnvironment.GetInstance();
-            GrpcEnvironment.Shutdown();
+            Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
 
-            var env2 = GrpcEnvironment.GetInstance();
-            GrpcEnvironment.Shutdown();
+            var env1 = GrpcEnvironment.AddRef();
+            GrpcEnvironment.Release();
 
-            Assert.IsFalse(object.ReferenceEquals(env1, env2));
+            var env2 = GrpcEnvironment.AddRef();
+            GrpcEnvironment.Release();
+
+            Assert.AreNotSame(env1, env2);
+        }
+
+        [Test]
+        public void ReleaseWithoutAddRef()
+        {
+            Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
+            Assert.Throws(typeof(InvalidOperationException), () => GrpcEnvironment.Release());
         }
 
         [Test]
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
new file mode 100644
index 0000000..685c5f7
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
@@ -0,0 +1,222 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+using Grpc.Core.Internal;
+using NUnit.Framework;
+
+namespace Grpc.Core.Internal.Tests
+{
+    public class AsyncCallTest
+    {
+        Channel channel;
+        FakeNativeCall fakeCall;
+        AsyncCall<string, string> asyncCall;
+
+        [SetUp]
+        public void Init()
+        {
+            channel = new Channel("localhost", Credentials.Insecure);
+
+            fakeCall = new FakeNativeCall();
+
+            var callDetails = new CallInvocationDetails<string, string>(channel, "someMethod", null, Marshallers.StringMarshaller, Marshallers.StringMarshaller, new CallOptions());
+            asyncCall = new AsyncCall<string, string>(callDetails, fakeCall);
+        }
+
+        [TearDown]
+        public void Cleanup()
+        {
+            channel.ShutdownAsync().Wait();
+        }
+
+        [Test]
+        public void AsyncUnary_CompletionSuccess()
+        {
+            var resultTask = asyncCall.UnaryCallAsync("abc");
+            fakeCall.UnaryResponseClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), new byte[] { 1, 2, 3 }, new Metadata());
+            Assert.IsTrue(resultTask.IsCompleted);
+            Assert.IsTrue(fakeCall.IsDisposed);
+            Assert.AreEqual(Status.DefaultSuccess, asyncCall.GetStatus());
+        }
+
+        [Test]
+        public void AsyncUnary_CompletionFailure()
+        {
+            var resultTask = asyncCall.UnaryCallAsync("abc");
+            fakeCall.UnaryResponseClientHandler(false, new ClientSideStatus(new Status(StatusCode.Internal, ""), null), new byte[] { 1, 2, 3 }, new Metadata());
+
+            Assert.IsTrue(resultTask.IsCompleted);
+            Assert.IsTrue(fakeCall.IsDisposed);
+
+            Assert.AreEqual(StatusCode.Internal, asyncCall.GetStatus().StatusCode);
+            Assert.IsNull(asyncCall.GetTrailers());
+            var ex = Assert.Throws<RpcException>(() => resultTask.GetAwaiter().GetResult());
+            Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
+        }
+
+        internal class FakeNativeCall : INativeCall
+        {
+            public UnaryResponseClientHandler UnaryResponseClientHandler
+            {
+                get;
+                set;
+            }
+
+            public ReceivedStatusOnClientHandler ReceivedStatusOnClientHandler
+            {
+                get;
+                set;
+            }
+
+            public ReceivedMessageHandler ReceivedMessageHandler
+            {
+                get;
+                set;
+            }
+
+            public ReceivedResponseHeadersHandler ReceivedResponseHeadersHandler
+            {
+                get;
+                set;
+            }
+
+            public SendCompletionHandler SendCompletionHandler
+            {
+                get;
+                set;
+            }
+
+            public ReceivedCloseOnServerHandler ReceivedCloseOnServerHandler
+            {
+                get;
+                set;
+            }
+
+            public bool IsCancelled
+            {
+                get;
+                set;
+            }
+
+            public bool IsDisposed
+            {
+                get;
+                set;
+            }
+
+            public void Cancel()
+            {
+                IsCancelled = true;
+            }
+
+            public void CancelWithStatus(Status status)
+            {
+                IsCancelled = true;
+            }
+
+            public string GetPeer()
+            {
+                return "PEER";
+            }
+
+            public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+            {
+                UnaryResponseClientHandler = callback;
+            }
+
+            public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+            {
+                throw new NotImplementedException();
+            }
+
+            public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray)
+            {
+                UnaryResponseClientHandler = callback;
+            }
+
+            public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+            {
+                ReceivedStatusOnClientHandler = callback;
+            }
+
+            public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray)
+            {
+                ReceivedStatusOnClientHandler = callback;
+            }
+
+            public void StartReceiveMessage(ReceivedMessageHandler callback)
+            {
+                ReceivedMessageHandler = callback;
+            }
+
+            public void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback)
+            {
+                ReceivedResponseHeadersHandler = callback;
+            }
+
+            public void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray)
+            {
+                SendCompletionHandler = callback;
+            }
+
+            public void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
+            {
+                SendCompletionHandler = callback;
+            }
+
+            public void StartSendCloseFromClient(SendCompletionHandler callback)
+            {
+                SendCompletionHandler = callback;
+            }
+
+            public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata)
+            {
+                SendCompletionHandler = callback;
+            }
+
+            public void StartServerSide(ReceivedCloseOnServerHandler callback)
+            {
+                ReceivedCloseOnServerHandler = callback;
+            }
+
+            public void Dispose()
+            {
+                IsDisposed = true;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Tests/MetadataTest.cs b/src/csharp/Grpc.Core.Tests/MetadataTest.cs
new file mode 100644
index 0000000..c00f945
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/MetadataTest.cs
@@ -0,0 +1,120 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class MetadataTest
+    {
+        [Test]
+        public void AsciiEntry()
+        {
+            var entry = new Metadata.Entry("ABC", "XYZ");
+            Assert.IsFalse(entry.IsBinary);
+            Assert.AreEqual("abc", entry.Key);  // key is in lowercase.
+            Assert.AreEqual("XYZ", entry.Value);
+            CollectionAssert.AreEqual(new[] { (byte)'X', (byte)'Y', (byte)'Z' }, entry.ValueBytes);
+
+            Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc-bin", "xyz"));
+
+            Assert.AreEqual("[Entry: key=abc, value=XYZ]", entry.ToString());
+        }
+
+        [Test]
+        public void BinaryEntry()
+        {
+            var bytes = new byte[] { 1, 2, 3 };
+            var entry = new Metadata.Entry("ABC-BIN", bytes);
+            Assert.IsTrue(entry.IsBinary);
+            Assert.AreEqual("abc-bin", entry.Key);  // key is in lowercase.
+            Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; });
+            CollectionAssert.AreEqual(bytes, entry.ValueBytes);
+
+            Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc", bytes));
+
+            Assert.AreEqual("[Entry: key=abc-bin, valueBytes=System.Byte[]]", entry.ToString());
+        }
+
+        [Test]
+        public void Entry_ConstructionPreconditions()
+        {
+            Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry(null, "xyz"));
+            Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc", (string)null));
+            Assert.Throws(typeof(ArgumentNullException), () => new Metadata.Entry("abc-bin", (byte[])null));
+        }
+
+        [Test]
+        public void Entry_Immutable()
+        {
+            var origBytes = new byte[] { 1, 2, 3 };
+            var bytes = new byte[] { 1, 2, 3 };
+            var entry = new Metadata.Entry("ABC-BIN", bytes);
+            bytes[0] = 255;  // changing the array passed to constructor should have any effect.
+            CollectionAssert.AreEqual(origBytes, entry.ValueBytes);
+
+            entry.ValueBytes[0] = 255;
+            CollectionAssert.AreEqual(origBytes, entry.ValueBytes);
+        }
+
+        [Test]
+        public void Entry_CreateUnsafe_Ascii()
+        {
+            var bytes = new byte[] { (byte)'X', (byte)'y' };
+            var entry = Metadata.Entry.CreateUnsafe("abc", bytes);
+            Assert.IsFalse(entry.IsBinary);
+            Assert.AreEqual("abc", entry.Key);
+            Assert.AreEqual("Xy", entry.Value);
+            CollectionAssert.AreEqual(bytes, entry.ValueBytes);
+        }
+
+        [Test]
+        public void Entry_CreateUnsafe_Binary()
+        {
+            var bytes = new byte[] { 1, 2, 3 };
+            var entry = Metadata.Entry.CreateUnsafe("abc-bin", bytes);
+            Assert.IsTrue(entry.IsBinary);
+            Assert.AreEqual("abc-bin", entry.Key);
+            Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; });
+            CollectionAssert.AreEqual(bytes, entry.ValueBytes);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs b/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
index 981b8ea..a1648f3 100644
--- a/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ResponseHeadersTest.cs
@@ -32,13 +32,16 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+
 using Grpc.Core;
 using Grpc.Core.Internal;
 using Grpc.Core.Utils;
+
 using NUnit.Framework;
 
 namespace Grpc.Core.Tests
@@ -69,14 +72,82 @@
         [TearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
         }
 
-        [TestFixtureTearDown]
-        public void CleanupClass()
+        [Test]
+        public async Task ResponseHeadersAsync_UnaryCall()
         {
-            GrpcEnvironment.Shutdown();
+            helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+            {
+                await context.WriteResponseHeadersAsync(headers);
+                return "PASS";
+            });
+
+            var call = Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "");
+            var responseHeaders = await call.ResponseHeadersAsync;
+
+            Assert.AreEqual(headers.Count, responseHeaders.Count);
+            Assert.AreEqual("ascii-header", responseHeaders[0].Key);
+            Assert.AreEqual("abcdefg", responseHeaders[0].Value);
+
+            Assert.AreEqual("PASS", await call.ResponseAsync);
+        }
+
+        [Test]
+        public async Task ResponseHeadersAsync_ClientStreamingCall()
+        {
+            helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
+            {
+                await context.WriteResponseHeadersAsync(headers);
+                return "PASS";
+            });
+
+            var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall());
+            await call.RequestStream.CompleteAsync();
+            var responseHeaders = await call.ResponseHeadersAsync;
+
+            Assert.AreEqual("ascii-header", responseHeaders[0].Key);
+            Assert.AreEqual("PASS", await call.ResponseAsync);
+        }
+
+        [Test]
+        public async Task ResponseHeadersAsync_ServerStreamingCall()
+        {
+            helper.ServerStreamingHandler = new ServerStreamingServerMethod<string, string>(async (request, responseStream, context) =>
+            {
+                await context.WriteResponseHeadersAsync(headers);
+                await responseStream.WriteAsync("PASS");
+            });
+
+            var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "");
+            var responseHeaders = await call.ResponseHeadersAsync;
+
+            Assert.AreEqual("ascii-header", responseHeaders[0].Key);
+            CollectionAssert.AreEqual(new[] { "PASS" }, await call.ResponseStream.ToListAsync());
+        }
+
+        [Test]
+        public async Task ResponseHeadersAsync_DuplexStreamingCall()
+        {
+            helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
+            {
+                await context.WriteResponseHeadersAsync(headers);
+                while (await requestStream.MoveNext())
+                {
+                    await responseStream.WriteAsync(requestStream.Current);
+                }
+            });
+
+            var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall());
+            var responseHeaders = await call.ResponseHeadersAsync;
+
+            var messages = new[] { "PASS" };
+            await call.RequestStream.WriteAllAsync(messages);
+
+            Assert.AreEqual("ascii-header", responseHeaders[0].Key);
+            CollectionAssert.AreEqual(messages, await call.ResponseStream.ToListAsync());
         }
 
         [Test]
diff --git a/src/csharp/Grpc.Core.Tests/ServerTest.cs b/src/csharp/Grpc.Core.Tests/ServerTest.cs
index 485006e..e7193c8 100644
--- a/src/csharp/Grpc.Core.Tests/ServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ServerTest.cs
@@ -51,7 +51,6 @@
             };
             server.Start();
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
 
         [Test]
@@ -67,8 +66,7 @@
             Assert.Greater(boundPort.BoundPort, 0);
 
             server.Start();
-            server.ShutdownAsync();
-            GrpcEnvironment.Shutdown();
+            server.ShutdownAsync().Wait();
         }
 
         [Test]
@@ -83,7 +81,6 @@
             Assert.Throws(typeof(InvalidOperationException), () => server.Services.Add(ServerServiceDefinition.CreateBuilder("serviceName").Build()));
 
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
     }
 }
diff --git a/src/csharp/Grpc.Core.Tests/ShutdownTest.cs b/src/csharp/Grpc.Core.Tests/ShutdownTest.cs
new file mode 100644
index 0000000..a2be7dd
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/ShutdownTest.cs
@@ -0,0 +1,77 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class ShutdownTest
+    {
+        const string Host = "127.0.0.1";
+
+        MockServiceHelper helper;
+        Server server;
+        Channel channel;
+
+        [SetUp]
+        public void Init()
+        {
+            helper = new MockServiceHelper(Host);
+            server = helper.GetServer();
+            server.Start();
+            channel = helper.GetChannel();
+        }
+
+        [Test]
+        public async Task AbandonedCall()
+        {
+            helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
+            {
+                await requestStream.ToListAsync();
+            });
+
+            var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall(new CallOptions(deadline: DateTime.UtcNow.AddMilliseconds(1))));
+
+            channel.ShutdownAsync().Wait();
+            server.ShutdownAsync().Wait();
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
index d875d60..41f661f 100644
--- a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
+++ b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
@@ -65,16 +65,10 @@
         [TearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
         }
 
-        [TestFixtureTearDown]
-        public void CleanupClass()
-        {
-            GrpcEnvironment.Shutdown();
-        }
-
         [Test]
         public void InfiniteDeadline()
         {
diff --git a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
index fb9b562..dbaa308 100644
--- a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
@@ -44,14 +44,16 @@
     {
         readonly IClientStreamWriter<TRequest> requestStream;
         readonly Task<TResponse> responseAsync;
+        readonly Task<Metadata> responseHeadersAsync;
         readonly Func<Status> getStatusFunc;
         readonly Func<Metadata> getTrailersFunc;
         readonly Action disposeAction;
 
-        public AsyncClientStreamingCall(IClientStreamWriter<TRequest> requestStream, Task<TResponse> responseAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
+        public AsyncClientStreamingCall(IClientStreamWriter<TRequest> requestStream, Task<TResponse> responseAsync, Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
         {
             this.requestStream = requestStream;
             this.responseAsync = responseAsync;
+            this.responseHeadersAsync = responseHeadersAsync;
             this.getStatusFunc = getStatusFunc;
             this.getTrailersFunc = getTrailersFunc;
             this.disposeAction = disposeAction;
@@ -69,6 +71,17 @@
         }
 
         /// <summary>
+        /// Asynchronous access to response headers.
+        /// </summary>
+        public Task<Metadata> ResponseHeadersAsync
+        {
+            get
+            {
+                return this.responseHeadersAsync;
+            }
+        }
+
+        /// <summary>
         /// Async stream to send streaming requests.
         /// </summary>
         public IClientStreamWriter<TRequest> RequestStream
diff --git a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
index 183c842..ee7ba29 100644
--- a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
@@ -32,6 +32,7 @@
 #endregion
 
 using System;
+using System.Threading.Tasks;
 
 namespace Grpc.Core
 {
@@ -42,14 +43,16 @@
     {
         readonly IClientStreamWriter<TRequest> requestStream;
         readonly IAsyncStreamReader<TResponse> responseStream;
+        readonly Task<Metadata> responseHeadersAsync;
         readonly Func<Status> getStatusFunc;
         readonly Func<Metadata> getTrailersFunc;
         readonly Action disposeAction;
 
-        public AsyncDuplexStreamingCall(IClientStreamWriter<TRequest> requestStream, IAsyncStreamReader<TResponse> responseStream, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
+        public AsyncDuplexStreamingCall(IClientStreamWriter<TRequest> requestStream, IAsyncStreamReader<TResponse> responseStream, Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
         {
             this.requestStream = requestStream;
             this.responseStream = responseStream;
+            this.responseHeadersAsync = responseHeadersAsync;
             this.getStatusFunc = getStatusFunc;
             this.getTrailersFunc = getTrailersFunc;
             this.disposeAction = disposeAction;
@@ -78,6 +81,17 @@
         }
 
         /// <summary>
+        /// Asynchronous access to response headers.
+        /// </summary>
+        public Task<Metadata> ResponseHeadersAsync
+        {
+            get
+            {
+                return this.responseHeadersAsync;
+            }
+        }
+
+        /// <summary>
         /// Gets the call status if the call has already finished.
         /// Throws InvalidOperationException otherwise.
         /// </summary>
diff --git a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
index ab2049f..2853a79 100644
--- a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
@@ -32,6 +32,7 @@
 #endregion
 
 using System;
+using System.Threading.Tasks;
 
 namespace Grpc.Core
 {
@@ -41,13 +42,15 @@
     public sealed class AsyncServerStreamingCall<TResponse> : IDisposable
     {
         readonly IAsyncStreamReader<TResponse> responseStream;
+        readonly Task<Metadata> responseHeadersAsync;
         readonly Func<Status> getStatusFunc;
         readonly Func<Metadata> getTrailersFunc;
         readonly Action disposeAction;
 
-        public AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
+        public AsyncServerStreamingCall(IAsyncStreamReader<TResponse> responseStream, Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
         {
             this.responseStream = responseStream;
+            this.responseHeadersAsync = responseHeadersAsync;
             this.getStatusFunc = getStatusFunc;
             this.getTrailersFunc = getTrailersFunc;
             this.disposeAction = disposeAction;
@@ -65,6 +68,17 @@
         }
 
         /// <summary>
+        /// Asynchronous access to response headers.
+        /// </summary>
+        public Task<Metadata> ResponseHeadersAsync
+        {
+            get
+            {
+                return this.responseHeadersAsync;
+            }
+        }
+
+        /// <summary>
         /// Gets the call status if the call has already finished.
         /// Throws InvalidOperationException otherwise.
         /// </summary>
diff --git a/src/csharp/Grpc.Core/AsyncUnaryCall.cs b/src/csharp/Grpc.Core/AsyncUnaryCall.cs
index 224e343..154a17a 100644
--- a/src/csharp/Grpc.Core/AsyncUnaryCall.cs
+++ b/src/csharp/Grpc.Core/AsyncUnaryCall.cs
@@ -43,13 +43,15 @@
     public sealed class AsyncUnaryCall<TResponse> : IDisposable
     {
         readonly Task<TResponse> responseAsync;
+        readonly Task<Metadata> responseHeadersAsync;
         readonly Func<Status> getStatusFunc;
         readonly Func<Metadata> getTrailersFunc;
         readonly Action disposeAction;
 
-        public AsyncUnaryCall(Task<TResponse> responseAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
+        public AsyncUnaryCall(Task<TResponse> responseAsync, Task<Metadata> responseHeadersAsync, Func<Status> getStatusFunc, Func<Metadata> getTrailersFunc, Action disposeAction)
         {
             this.responseAsync = responseAsync;
+            this.responseHeadersAsync = responseHeadersAsync;
             this.getStatusFunc = getStatusFunc;
             this.getTrailersFunc = getTrailersFunc;
             this.disposeAction = disposeAction;
@@ -67,6 +69,17 @@
         }
 
         /// <summary>
+        /// Asynchronous access to response headers.
+        /// </summary>
+        public Task<Metadata> ResponseHeadersAsync
+        {
+            get
+            {
+                return this.responseHeadersAsync;
+            }
+        }
+
+        /// <summary>
         /// Allows awaiting this object directly.
         /// </summary>
         public TaskAwaiter<TResponse> GetAwaiter()
diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs
index 7067456..e57ac89 100644
--- a/src/csharp/Grpc.Core/Calls.cs
+++ b/src/csharp/Grpc.Core/Calls.cs
@@ -74,7 +74,7 @@
         {
             var asyncCall = new AsyncCall<TRequest, TResponse>(call);
             var asyncResult = asyncCall.UnaryCallAsync(req);
-            return new AsyncUnaryCall<TResponse>(asyncResult, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
+            return new AsyncUnaryCall<TResponse>(asyncResult, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
         }
 
         /// <summary>
@@ -93,7 +93,7 @@
             var asyncCall = new AsyncCall<TRequest, TResponse>(call);
             asyncCall.StartServerStreamingCall(req);
             var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
-            return new AsyncServerStreamingCall<TResponse>(responseStream, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
+            return new AsyncServerStreamingCall<TResponse>(responseStream, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
         }
 
         /// <summary>
@@ -110,7 +110,7 @@
             var asyncCall = new AsyncCall<TRequest, TResponse>(call);
             var resultTask = asyncCall.ClientStreamingCallAsync();
             var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
-            return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
+            return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
         }
 
         /// <summary>
@@ -130,7 +130,7 @@
             asyncCall.StartDuplexStreamingCall();
             var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
             var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
-            return new AsyncDuplexStreamingCall<TRequest, TResponse>(requestStream, responseStream, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
+            return new AsyncDuplexStreamingCall<TRequest, TResponse>(requestStream, responseStream, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
         }
     }
 }
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 64c6adf..c11b320 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -45,15 +45,19 @@
     /// <summary>
     /// gRPC Channel
     /// </summary>
-    public class Channel : IDisposable
+    public class Channel
     {
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Channel>();
 
+        readonly object myLock = new object();
+        readonly AtomicCounter activeCallCounter = new AtomicCounter();
+
         readonly string target;
         readonly GrpcEnvironment environment;
         readonly ChannelSafeHandle handle;
         readonly List<ChannelOption> options;
-        bool disposed;
+
+        bool shutdownRequested;
 
         /// <summary>
         /// Creates a channel that connects to a specific host.
@@ -65,7 +69,7 @@
         public Channel(string target, Credentials credentials, IEnumerable<ChannelOption> options = null)
         {
             this.target = Preconditions.CheckNotNull(target, "target");
-            this.environment = GrpcEnvironment.GetInstance();
+            this.environment = GrpcEnvironment.AddRef();
             this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
 
             EnsureUserAgentChannelOption(this.options);
@@ -172,12 +176,26 @@
         }
 
         /// <summary>
-        /// Destroys the underlying channel.
+        /// Waits until there are no more active calls for this channel and then cleans up
+        /// resources used by this channel.
         /// </summary>
-        public void Dispose()
+        public async Task ShutdownAsync()
         {
-            Dispose(true);
-            GC.SuppressFinalize(this);
+            lock (myLock)
+            {
+                Preconditions.CheckState(!shutdownRequested);
+                shutdownRequested = true;
+            }
+
+            var activeCallCount = activeCallCounter.Count;
+            if (activeCallCount > 0)
+            {
+                Logger.Warning("Channel shutdown was called but there are still {0} active calls for that channel.", activeCallCount);
+            }
+
+            handle.Dispose();
+
+            await Task.Run(() => GrpcEnvironment.Release());
         }
 
         internal ChannelSafeHandle Handle
@@ -196,13 +214,20 @@
             }
         }
 
-        protected virtual void Dispose(bool disposing)
+        internal void AddCallReference(object call)
         {
-            if (disposing && handle != null && !disposed)
-            {
-                disposed = true;
-                handle.Dispose();
-            }
+            activeCallCounter.Increment();
+
+            bool success = false;
+            handle.DangerousAddRef(ref success);
+            Preconditions.CheckState(success);
+        }
+
+        internal void RemoveCallReference(object call)
+        {
+            handle.DangerousRelease();
+
+            activeCallCounter.Decrement();
         }
 
         private static void EnsureUserAgentChannelOption(List<ChannelOption> options)
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index 7bc100c..9034494 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -119,7 +119,8 @@
         internal static string GetAuthUriBase(string target)
         {
             var match = ChannelTargetPattern.Match(target);
-            if (!match.Success) {
+            if (!match.Success)
+            {
                 return null;
             }
             return "https://" + match.Groups[2].Value + "/";
diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/ContextPropagationToken.cs
index 2e4bfc9..a5bf1b5 100644
--- a/src/csharp/Grpc.Core/ContextPropagationToken.cs
+++ b/src/csharp/Grpc.Core/ContextPropagationToken.cs
@@ -132,7 +132,6 @@
         bool propagateDeadline;
         bool propagateCancellation;
 
-
         /// <summary>
         /// Creates new context propagation options.
         /// </summary>
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 055aff1..ad2af17 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -49,6 +49,7 @@
     <Compile Include="AsyncDuplexStreamingCall.cs" />
     <Compile Include="AsyncServerStreamingCall.cs" />
     <Compile Include="IClientStreamWriter.cs" />
+    <Compile Include="Internal\INativeCall.cs" />
     <Compile Include="IServerStreamWriter.cs" />
     <Compile Include="IAsyncStreamWriter.cs" />
     <Compile Include="IAsyncStreamReader.cs" />
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 30d8c80..e7c0418 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -58,6 +58,7 @@
 
         static object staticLock = new object();
         static GrpcEnvironment instance;
+        static int refCount;
 
         static ILogger logger = new ConsoleLogger();
 
@@ -67,13 +68,14 @@
         bool isClosed;
 
         /// <summary>
-        /// Returns an instance of initialized gRPC environment.
-        /// Subsequent invocations return the same instance unless Shutdown has been called first.
+        /// Returns a reference-counted instance of initialized gRPC environment.
+        /// Subsequent invocations return the same instance unless reference count has dropped to zero previously.
         /// </summary>
-        internal static GrpcEnvironment GetInstance()
+        internal static GrpcEnvironment AddRef()
         {
             lock (staticLock)
             {
+                refCount++;
                 if (instance == null)
                 {
                     instance = new GrpcEnvironment();
@@ -83,14 +85,16 @@
         }
 
         /// <summary>
-        /// Shuts down the gRPC environment if it was initialized before.
-        /// Blocks until the environment has been fully shutdown.
+        /// Decrements the reference count for currently active environment and shuts down the gRPC environment if reference count drops to zero.
+        /// (and blocks until the environment has been fully shutdown).
         /// </summary>
-        public static void Shutdown()
+        internal static void Release()
         {
             lock (staticLock)
             {
-                if (instance != null)
+                Preconditions.CheckState(refCount > 0);
+                refCount--;
+                if (refCount == 0)
                 {
                     instance.Close();
                     instance = null;
@@ -98,6 +102,14 @@
             }
         }
 
+        internal static int GetRefCount()
+        {
+            lock (staticLock)
+            {
+                return refCount;
+            }
+        }
+
         /// <summary>
         /// Gets application-wide logger used by gRPC.
         /// </summary>
@@ -125,12 +137,10 @@
         private GrpcEnvironment()
         {
             NativeLogRedirector.Redirect();
-            grpcsharp_init();
+            GrpcNativeInit();
             completionRegistry = new CompletionRegistry(this);
             threadPool = new GrpcThreadPool(this, THREAD_POOL_SIZE);
             threadPool.Start();
-            // TODO: use proper logging here
-            Logger.Info("gRPC initialized.");
         }
 
         /// <summary>
@@ -175,6 +185,16 @@
             return Marshal.PtrToStringAnsi(ptr);
         }
 
+        internal static void GrpcNativeInit()
+        {
+            grpcsharp_init();
+        }
+
+        internal static void GrpcNativeShutdown()
+        {
+            grpcsharp_shutdown();
+        }
+
         /// <summary>
         /// Shuts down this environment.
         /// </summary>
@@ -185,12 +205,10 @@
                 throw new InvalidOperationException("Close has already been called");
             }
             threadPool.Stop();
-            grpcsharp_shutdown();
+            GrpcNativeShutdown();
             isClosed = true;
 
             debugStats.CheckOK();
-
-            Logger.Info("gRPC shutdown.");
         }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 2c3e3d7..be5d611 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -51,22 +51,35 @@
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCall<TRequest, TResponse>>();
 
         readonly CallInvocationDetails<TRequest, TResponse> details;
+        readonly INativeCall injectedNativeCall;  // for testing
 
         // Completion of a pending unary response if not null.
         TaskCompletionSource<TResponse> unaryResponseTcs;
 
+        // Indicates that steaming call has finished.
+        TaskCompletionSource<object> streamingCallFinishedTcs = new TaskCompletionSource<object>();
+
+        // Response headers set here once received.
+        TaskCompletionSource<Metadata> responseHeadersTcs = new TaskCompletionSource<Metadata>();
+
         // Set after status is received. Used for both unary and streaming response calls.
         ClientSideStatus? finishedStatus;
 
-        bool readObserverCompleted;  // True if readObserver has already been completed.
-
         public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails)
-            : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer)
+            : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer, callDetails.Channel.Environment)
         {
             this.details = callDetails.WithOptions(callDetails.Options.Normalize());
             this.initialMetadataSent = true;  // we always send metadata at the very beginning of the call.
         }
 
+        /// <summary>
+        /// This constructor should only be used for testing.
+        /// </summary>
+        public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails, INativeCall injectedNativeCall) : this(callDetails)
+        {
+            this.injectedNativeCall = injectedNativeCall;
+        }
+
         // TODO: this method is not Async, so it shouldn't be in AsyncCall class, but 
         // it is reusing fair amount of code in this class, so we are leaving it here.
         /// <summary>
@@ -100,7 +113,7 @@
                         bool success = (ev.success != 0);
                         try
                         {
-                            HandleUnaryResponse(success, ctx);
+                            HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessage(), ctx.GetReceivedInitialMetadata());
                         }
                         catch (Exception e)
                         {
@@ -125,7 +138,7 @@
                 Preconditions.CheckState(!started);
                 started = true;
 
-                Initialize(details.Channel.Environment.CompletionQueue);
+                Initialize(environment.CompletionQueue);
 
                 halfcloseRequested = true;
                 readingDone = true;
@@ -152,7 +165,7 @@
                 Preconditions.CheckState(!started);
                 started = true;
 
-                Initialize(details.Channel.Environment.CompletionQueue);
+                Initialize(environment.CompletionQueue);
 
                 readingDone = true;
 
@@ -176,10 +189,9 @@
                 Preconditions.CheckState(!started);
                 started = true;
 
-                Initialize(details.Channel.Environment.CompletionQueue);
+                Initialize(environment.CompletionQueue);
 
                 halfcloseRequested = true;
-                halfclosed = true;  // halfclose not confirmed yet, but it will be once finishedHandler is called.
 
                 byte[] payload = UnsafeSerialize(msg);
 
@@ -187,6 +199,7 @@
                 {
                     call.StartServerStreaming(HandleFinished, payload, metadataArray, GetWriteFlagsForCall());
                 }
+                call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders);
             }
         }
 
@@ -201,12 +214,13 @@
                 Preconditions.CheckState(!started);
                 started = true;
 
-                Initialize(details.Channel.Environment.CompletionQueue);
+                Initialize(environment.CompletionQueue);
 
                 using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
                 {
                     call.StartDuplexStreaming(HandleFinished, metadataArray);
                 }
+                call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders);
             }
         }
 
@@ -248,6 +262,28 @@
         }
 
         /// <summary>
+        /// Get the task that completes once if streaming call finishes with ok status and throws RpcException with given status otherwise.
+        /// </summary>
+        public Task StreamingCallFinishedTask
+        {
+            get
+            {
+                return streamingCallFinishedTcs.Task;
+            }
+        }
+
+        /// <summary>
+        /// Get the task that completes once response headers are received.
+        /// </summary>
+        public Task<Metadata> ResponseHeadersAsync
+        {
+            get
+            {
+                return responseHeadersTcs.Task;
+            }
+        }
+
+        /// <summary>
         /// Gets the resulting status if the call has already finished.
         /// Throws InvalidOperationException otherwise.
         /// </summary>
@@ -281,53 +317,33 @@
             }
         }
 
-        /// <summary>
-        /// On client-side, we only fire readCompletionDelegate once all messages have been read 
-        /// and status has been received.
-        /// </summary>
-        protected override void ProcessLastRead(AsyncCompletionDelegate<TResponse> completionDelegate)
+        protected override void OnAfterReleaseResources()
         {
-            if (completionDelegate != null && readingDone && finishedStatus.HasValue)
-            {
-                bool shouldComplete;
-                lock (myLock)
-                {
-                    shouldComplete = !readObserverCompleted;
-                    readObserverCompleted = true;
-                }
-
-                if (shouldComplete)
-                {
-                    var status = finishedStatus.Value.Status;
-                    if (status.StatusCode != StatusCode.OK)
-                    {
-                        FireCompletion(completionDelegate, default(TResponse), new RpcException(status));
-                    }
-                    else
-                    {
-                        FireCompletion(completionDelegate, default(TResponse), null);
-                    }
-                }
-            }
-        }
-
-        protected override void OnReleaseResources()
-        {
-            details.Channel.Environment.DebugStats.ActiveClientCalls.Decrement();
+            details.Channel.RemoveCallReference(this);
         }
 
         private void Initialize(CompletionQueueSafeHandle cq)
         {
-            var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance;
-
-            var call = details.Channel.Handle.CreateCall(details.Channel.Environment.CompletionRegistry,
-                parentCall, ContextPropagationToken.DefaultMask, cq,
-                details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value));
-            details.Channel.Environment.DebugStats.ActiveClientCalls.Increment();
+            var call = CreateNativeCall(cq);
+            details.Channel.AddCallReference(this);
             InitializeInternal(call);
             RegisterCancellationCallback();
         }
 
+        private INativeCall CreateNativeCall(CompletionQueueSafeHandle cq)
+        {
+            if (injectedNativeCall != null)
+            {
+                return injectedNativeCall;  // allows injecting a mock INativeCall in tests.
+            }
+
+            var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance;
+
+            return details.Channel.Handle.CreateCall(environment.CompletionRegistry,
+                parentCall, ContextPropagationToken.DefaultMask, cq,
+                details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value));
+        }
+
         // Make sure that once cancellationToken for this call is cancelled, Cancel() will be called.
         private void RegisterCancellationCallback()
         {
@@ -348,31 +364,31 @@
         }
 
         /// <summary>
+        /// Handles receive status completion for calls with streaming response.
+        /// </summary>
+        private void HandleReceivedResponseHeaders(bool success, Metadata responseHeaders)
+        {
+            responseHeadersTcs.SetResult(responseHeaders);
+        }
+
+        /// <summary>
         /// Handler for unary response completion.
         /// </summary>
-        private void HandleUnaryResponse(bool success, BatchContextSafeHandle ctx)
+        private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders)
         {
-            var fullStatus = ctx.GetReceivedStatusOnClient();
-
             lock (myLock)
             {
                 finished = true;
-                finishedStatus = fullStatus;
-
-                halfclosed = true;
+                finishedStatus = receivedStatus;
 
                 ReleaseResourcesIfPossible();
             }
 
-            if (!success)
-            {
-                unaryResponseTcs.SetException(new RpcException(new Status(StatusCode.Internal, "Internal error occured.")));
-                return;
-            }
+            responseHeadersTcs.SetResult(responseHeaders);
 
-            var status = fullStatus.Status;
+            var status = receivedStatus.Status;
 
-            if (status.StatusCode != StatusCode.OK)
+            if (!success || status.StatusCode != StatusCode.OK)
             {
                 unaryResponseTcs.SetException(new RpcException(status));
                 return;
@@ -380,7 +396,7 @@
 
             // TODO: handle deserialization error
             TResponse msg;
-            TryDeserialize(ctx.GetReceivedMessage(), out msg);
+            TryDeserialize(receivedMessage, out msg);
 
             unaryResponseTcs.SetResult(msg);
         }
@@ -388,22 +404,25 @@
         /// <summary>
         /// Handles receive status completion for calls with streaming response.
         /// </summary>
-        private void HandleFinished(bool success, BatchContextSafeHandle ctx)
+        private void HandleFinished(bool success, ClientSideStatus receivedStatus)
         {
-            var fullStatus = ctx.GetReceivedStatusOnClient();
-
-            AsyncCompletionDelegate<TResponse> origReadCompletionDelegate = null;
             lock (myLock)
             {
                 finished = true;
-                finishedStatus = fullStatus;
-
-                origReadCompletionDelegate = readCompletionDelegate;
+                finishedStatus = receivedStatus;
 
                 ReleaseResourcesIfPossible();
             }
 
-            ProcessLastRead(origReadCompletionDelegate);
+            var status = receivedStatus.Status;
+
+            if (!success || status.StatusCode != StatusCode.OK)
+            {
+                streamingCallFinishedTcs.SetException(new RpcException(status));
+                return;
+            }
+
+            streamingCallFinishedTcs.SetResult(null);
         }
     }
 }
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 6ca4bbd..4d20394 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -54,30 +54,30 @@
         readonly Func<TWrite, byte[]> serializer;
         readonly Func<byte[], TRead> deserializer;
 
+        protected readonly GrpcEnvironment environment;
         protected readonly object myLock = new object();
 
-        protected CallSafeHandle call;
+        protected INativeCall call;
         protected bool disposed;
 
         protected bool started;
-        protected bool errorOccured;
         protected bool cancelRequested;
 
         protected AsyncCompletionDelegate<object> sendCompletionDelegate;  // Completion of a pending send or sendclose if not null.
         protected AsyncCompletionDelegate<TRead> readCompletionDelegate;  // Completion of a pending send or sendclose if not null.
 
-        protected bool readingDone;
-        protected bool halfcloseRequested;
-        protected bool halfclosed;
+        protected bool readingDone;  // True if last read (i.e. read with null payload) was already received.
+        protected bool halfcloseRequested;  // True if send close have been initiated.
         protected bool finished;  // True if close has been received from the peer.
 
         protected bool initialMetadataSent;
-        protected long streamingWritesCounter;
+        protected long streamingWritesCounter;  // Number of streaming send operations started so far.
 
-        public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer)
+        public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer, GrpcEnvironment environment)
         {
             this.serializer = Preconditions.CheckNotNull(serializer);
             this.deserializer = Preconditions.CheckNotNull(deserializer);
+            this.environment = Preconditions.CheckNotNull(environment);
         }
 
         /// <summary>
@@ -114,7 +114,7 @@
             }
         }
 
-        protected void InitializeInternal(CallSafeHandle call)
+        protected void InitializeInternal(INativeCall call)
         {
             lock (myLock)
             {
@@ -159,16 +159,6 @@
             }
         }
 
-        // TODO(jtattermusch): find more fitting name for this method.
-        /// <summary>
-        /// Default behavior just completes the read observer, but more sofisticated behavior might be required
-        /// by subclasses.
-        /// </summary>
-        protected virtual void ProcessLastRead(AsyncCompletionDelegate<TRead> completionDelegate)
-        {
-            FireCompletion(completionDelegate, default(TRead), null);
-        }
-
         /// <summary>
         /// If there are no more pending actions and no new actions can be started, releases
         /// the underlying native resources.
@@ -177,7 +167,7 @@
         {
             if (!disposed && call != null)
             {
-                bool noMoreSendCompletions = halfclosed || (cancelRequested && sendCompletionDelegate == null);
+                bool noMoreSendCompletions = sendCompletionDelegate == null && (halfcloseRequested || cancelRequested || finished);
                 if (noMoreSendCompletions && readingDone && finished)
                 {
                     ReleaseResources();
@@ -189,34 +179,33 @@
 
         private void ReleaseResources()
         {
-            OnReleaseResources();
             if (call != null)
             {
                 call.Dispose();
             }
             disposed = true;
+            OnAfterReleaseResources();
         }
 
-        protected virtual void OnReleaseResources()
+        protected virtual void OnAfterReleaseResources()
         {
         }
 
         protected void CheckSendingAllowed()
         {
             Preconditions.CheckState(started);
-            Preconditions.CheckState(!errorOccured);
             CheckNotCancelled();
             Preconditions.CheckState(!disposed);
 
             Preconditions.CheckState(!halfcloseRequested, "Already halfclosed.");
+            Preconditions.CheckState(!finished, "Already finished.");
             Preconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time");
         }
 
-        protected void CheckReadingAllowed()
+        protected virtual void CheckReadingAllowed()
         {
             Preconditions.CheckState(started);
             Preconditions.CheckState(!disposed);
-            Preconditions.CheckState(!errorOccured);
 
             Preconditions.CheckState(!readingDone, "Stream has already been closed.");
             Preconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time");
@@ -280,7 +269,7 @@
         /// <summary>
         /// Handles send completion.
         /// </summary>
-        protected void HandleSendFinished(bool success, BatchContextSafeHandle ctx)
+        protected void HandleSendFinished(bool success)
         {
             AsyncCompletionDelegate<object> origCompletionDelegate = null;
             lock (myLock)
@@ -304,12 +293,11 @@
         /// <summary>
         /// Handles halfclose completion.
         /// </summary>
-        protected void HandleHalfclosed(bool success, BatchContextSafeHandle ctx)
+        protected void HandleHalfclosed(bool success)
         {
             AsyncCompletionDelegate<object> origCompletionDelegate = null;
             lock (myLock)
             {
-                halfclosed = true;
                 origCompletionDelegate = sendCompletionDelegate;
                 sendCompletionDelegate = null;
 
@@ -329,23 +317,17 @@
         /// <summary>
         /// Handles streaming read completion.
         /// </summary>
-        protected void HandleReadFinished(bool success, BatchContextSafeHandle ctx)
+        protected void HandleReadFinished(bool success, byte[] receivedMessage)
         {
-            var payload = ctx.GetReceivedMessage();
-
             AsyncCompletionDelegate<TRead> origCompletionDelegate = null;
             lock (myLock)
             {
                 origCompletionDelegate = readCompletionDelegate;
-                if (payload != null)
+                readCompletionDelegate = null;
+
+                if (receivedMessage == null)
                 {
-                    readCompletionDelegate = null;
-                }
-                else
-                {
-                    // This was the last read. Keeping the readCompletionDelegate
-                    // to be either fired by this handler or by client-side finished
-                    // handler.
+                    // This was the last read.
                     readingDone = true;
                 }
 
@@ -354,17 +336,17 @@
 
             // TODO: handle the case when error occured...
 
-            if (payload != null)
+            if (receivedMessage != null)
             {
                 // TODO: handle deserialization error
                 TRead msg;
-                TryDeserialize(payload, out msg);
+                TryDeserialize(receivedMessage, out msg);
 
                 FireCompletion(origCompletionDelegate, msg, null);
             }
             else
             {
-                ProcessLastRead(origCompletionDelegate);
+                FireCompletion(origCompletionDelegate, default(TRead), null);
             }
         }
     }
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 3710a65..5c47251 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -49,17 +49,18 @@
     {
         readonly TaskCompletionSource<object> finishedServersideTcs = new TaskCompletionSource<object>();
         readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
-        readonly GrpcEnvironment environment;
+        readonly Server server;
 
-        public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment) : base(serializer, deserializer)
+        public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment, Server server) : base(serializer, deserializer, environment)
         {
-            this.environment = Preconditions.CheckNotNull(environment);
+            this.server = Preconditions.CheckNotNull(server);
         }
 
         public void Initialize(CallSafeHandle call)
         {
             call.SetCompletionRegistry(environment.CompletionRegistry);
-            environment.DebugStats.ActiveServerCalls.Increment();
+
+            server.AddCallReference(this);
             InitializeInternal(call);
         }
 
@@ -168,18 +169,22 @@
             }
         }
 
-        protected override void OnReleaseResources()
+        protected override void CheckReadingAllowed()
         {
-            environment.DebugStats.ActiveServerCalls.Decrement();
+            base.CheckReadingAllowed();
+            Preconditions.CheckArgument(!cancelRequested);
+        }
+
+        protected override void OnAfterReleaseResources()
+        {
+            server.RemoveCallReference(this);
         }
 
         /// <summary>
         /// Handles the server side close completion.
         /// </summary>
-        private void HandleFinishedServerside(bool success, BatchContextSafeHandle ctx)
+        private void HandleFinishedServerside(bool success, bool cancelled)
         {
-            bool cancelled = ctx.GetReceivedCloseOnServerCancelled();
-
             lock (myLock)
             {
                 finished = true;
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 6a2add5..3a96414 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -134,7 +134,7 @@
         }
 
         // Gets data of server_rpc_new completion.
-        public ServerRpcNew GetServerRpcNew()
+        public ServerRpcNew GetServerRpcNew(Server server)
         {
             var call = grpcsharp_batch_context_server_rpc_new_call(this);
 
@@ -145,7 +145,7 @@
             IntPtr metadataArrayPtr = grpcsharp_batch_context_server_rpc_new_request_metadata(this);
             var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
 
-            return new ServerRpcNew(call, method, host, deadline, metadata);
+            return new ServerRpcNew(server, call, method, host, deadline, metadata);
         }
 
         // Gets data of receive_close_on_server completion.
@@ -198,14 +198,16 @@
     /// </summary>
     internal struct ServerRpcNew
     {
+        readonly Server server;
         readonly CallSafeHandle call;
         readonly string method;
         readonly string host;
         readonly Timespec deadline;
         readonly Metadata requestMetadata;
 
-        public ServerRpcNew(CallSafeHandle call, string method, string host, Timespec deadline, Metadata requestMetadata)
+        public ServerRpcNew(Server server, CallSafeHandle call, string method, string host, Timespec deadline, Metadata requestMetadata)
         {
+            this.server = server;
             this.call = call;
             this.method = method;
             this.host = host;
@@ -213,6 +215,14 @@
             this.requestMetadata = requestMetadata;
         }
 
+        public Server Server
+        {
+            get
+            {
+                return this.server;
+            }
+        }
+
         public CallSafeHandle Call
         {
             get
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 3cb01e2..0f18752 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -40,7 +40,7 @@
     /// <summary>
     /// grpc_call from <grpc/grpc.h>
     /// </summary>
-    internal class CallSafeHandle : SafeHandleZeroIsInvalid
+    internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall
     {
         public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
 
@@ -87,6 +87,10 @@
             BatchContextSafeHandle ctx);
 
         [DllImport("grpc_csharp_ext.dll")]
+        static extern GRPCCallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call,
+            BatchContextSafeHandle ctx);
+
+        [DllImport("grpc_csharp_ext.dll")]
         static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
             BatchContextSafeHandle ctx);
 
@@ -109,10 +113,10 @@
             this.completionRegistry = completionRegistry;
         }
 
-        public void StartUnary(BatchCompletionDelegate callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+        public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
             grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
                 .CheckOk();
         }
@@ -123,66 +127,73 @@
                 .CheckOk();
         }
 
-        public void StartClientStreaming(BatchCompletionDelegate callback, MetadataArraySafeHandle metadataArray)
+        public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
             grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk();
         }
 
-        public void StartServerStreaming(BatchCompletionDelegate callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+        public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
             grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk();
         }
 
-        public void StartDuplexStreaming(BatchCompletionDelegate callback, MetadataArraySafeHandle metadataArray)
+        public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
             grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk();
         }
 
-        public void StartSendMessage(BatchCompletionDelegate callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
+        public void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
             grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata).CheckOk();
         }
 
-        public void StartSendCloseFromClient(BatchCompletionDelegate callback)
+        public void StartSendCloseFromClient(SendCompletionHandler callback)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
             grpcsharp_call_send_close_from_client(this, ctx).CheckOk();
         }
 
-        public void StartSendStatusFromServer(BatchCompletionDelegate callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata)
+        public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
             grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata).CheckOk();
         }
 
-        public void StartReceiveMessage(BatchCompletionDelegate callback)
+        public void StartReceiveMessage(ReceivedMessageHandler callback)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage()));
             grpcsharp_call_recv_message(this, ctx).CheckOk();
         }
 
-        public void StartServerSide(BatchCompletionDelegate callback)
+        public void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata()));
+            grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk();
+        }
+
+        public void StartServerSide(ReceivedCloseOnServerHandler callback)
+        {
+            var ctx = BatchContextSafeHandle.Create();
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled()));
             grpcsharp_call_start_serverside(this, ctx).CheckOk();
         }
 
-        public void StartSendInitialMetadata(BatchCompletionDelegate callback, MetadataArraySafeHandle metadataArray)
+        public void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
             grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk();
         }
 
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index 7f03bf4..8cef566 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -68,11 +68,17 @@
 
         public static ChannelSafeHandle CreateInsecure(string target, ChannelArgsSafeHandle channelArgs)
         {
+            // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
+            // Doing so would make object finalizer crash if we end up abandoning the handle.
+            GrpcEnvironment.GrpcNativeInit();
             return grpcsharp_insecure_channel_create(target, channelArgs);
         }
 
         public static ChannelSafeHandle CreateSecure(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
         {
+            // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
+            // Doing so would make object finalizer crash if we end up abandoning the handle.
+            GrpcEnvironment.GrpcNativeInit();
             return grpcsharp_secure_channel_create(credentials, target, channelArgs);
         }
 
@@ -107,6 +113,7 @@
         protected override bool ReleaseHandle()
         {
             grpcsharp_channel_destroy(handle);
+            GrpcEnvironment.GrpcNativeShutdown();
             return true;
         }
     }
diff --git a/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs b/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs
index 6c44521..b4a7335 100644
--- a/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs
+++ b/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs
@@ -72,7 +72,13 @@
             call.StartReadMessage(taskSource.CompletionDelegate);
             var result = await taskSource.Task;
             this.current = result;
-            return result != null;
+
+            if (result == null)
+            {
+                await call.StreamingCallFinishedTask;
+                return false;
+            }
+            return true;
         }
 
         public void Dispose()
diff --git a/src/csharp/Grpc.Core/Internal/DebugStats.cs b/src/csharp/Grpc.Core/Internal/DebugStats.cs
index 8793450..1bea1ad 100644
--- a/src/csharp/Grpc.Core/Internal/DebugStats.cs
+++ b/src/csharp/Grpc.Core/Internal/DebugStats.cs
@@ -38,10 +38,6 @@
 {
     internal class DebugStats
     {
-        public readonly AtomicCounter ActiveClientCalls = new AtomicCounter();
-
-        public readonly AtomicCounter ActiveServerCalls = new AtomicCounter();
-
         public readonly AtomicCounter PendingBatchCompletions = new AtomicCounter();
 
         /// <summary>
@@ -49,16 +45,6 @@
         /// </summary>
         public void CheckOK()
         {
-            var remainingClientCalls = ActiveClientCalls.Count;
-            if (remainingClientCalls != 0)
-            {                
-                DebugWarning(string.Format("Detected {0} client calls that weren't disposed properly.", remainingClientCalls));
-            }
-            var remainingServerCalls = ActiveServerCalls.Count;
-            if (remainingServerCalls != 0)
-            {
-                DebugWarning(string.Format("Detected {0} server calls that weren't disposed properly.", remainingServerCalls));
-            }
             var pendingBatchCompletions = PendingBatchCompletions.Count;
             if (pendingBatchCompletions != 0)
             {
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index cb4c7c8..4b7124e 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -83,8 +83,6 @@
             lock (myLock)
             {
                 cq.Shutdown();
-
-                Logger.Info("Waiting for GRPC threads to finish.");
                 foreach (var thread in threads)
                 {
                     thread.Join();
@@ -136,7 +134,6 @@
                 }
             }
             while (ev.type != GRPCCompletionType.Shutdown);
-            Logger.Info("Completion queue has shutdown successfully, thread {0} exiting.", Thread.CurrentThread.Name);
         }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs
new file mode 100644
index 0000000..cbef599
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs
@@ -0,0 +1,85 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// 
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+
+namespace Grpc.Core.Internal
+{
+    internal delegate void UnaryResponseClientHandler(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders);
+
+    // Received status for streaming response calls.
+    internal delegate void ReceivedStatusOnClientHandler(bool success, ClientSideStatus receivedStatus);
+
+    internal delegate void ReceivedMessageHandler(bool success, byte[] receivedMessage);
+
+    internal delegate void ReceivedResponseHeadersHandler(bool success, Metadata responseHeaders);
+
+    internal delegate void SendCompletionHandler(bool success);
+
+    internal delegate void ReceivedCloseOnServerHandler(bool success, bool cancelled);
+
+    /// <summary>
+    /// Abstraction of a native call object.
+    /// </summary>
+    internal interface INativeCall : IDisposable
+    {
+        void Cancel();
+
+        void CancelWithStatus(Grpc.Core.Status status);
+
+        string GetPeer();
+
+        void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, Grpc.Core.WriteFlags writeFlags);
+
+        void StartUnary(BatchContextSafeHandle ctx, byte[] payload, MetadataArraySafeHandle metadataArray, Grpc.Core.WriteFlags writeFlags);
+
+        void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray);
+
+        void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, Grpc.Core.WriteFlags writeFlags);
+
+        void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray);
+
+        void StartReceiveMessage(ReceivedMessageHandler callback);
+
+        void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback);
+
+        void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray);
+
+        void StartSendMessage(SendCompletionHandler callback, byte[] payload, Grpc.Core.WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+
+        void StartSendCloseFromClient(SendCompletionHandler callback);
+
+        void StartSendStatusFromServer(SendCompletionHandler callback, Grpc.Core.Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
+
+        void StartServerSide(ReceivedCloseOnServerHandler callback);
+    }
+}
diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
index 427c16f..83994f6 100644
--- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
@@ -70,7 +70,8 @@
             var metadataArray = grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
             for (int i = 0; i < metadata.Count; i++)
             {
-                grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, metadata[i].ValueBytes, new UIntPtr((ulong)metadata[i].ValueBytes.Length));
+                var valueBytes = metadata[i].GetSerializedValueUnsafe();
+                grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
             }
             return metadataArray;
         }
@@ -94,7 +95,7 @@
                 string key = Marshal.PtrToStringAnsi(grpcsharp_metadata_array_get_key(metadataArray, index));
                 var bytes = new byte[grpcsharp_metadata_array_get_value_length(metadataArray, index).ToUInt64()];
                 Marshal.Copy(grpcsharp_metadata_array_get_value(metadataArray, index), bytes, 0, bytes.Length);
-                metadata.Add(new Metadata.Entry(key, bytes));
+                metadata.Add(Metadata.Entry.CreateUnsafe(key, bytes));
             }
             return metadata;
         }
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 688f9f6..59f4c57 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -67,7 +67,7 @@
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment);
+                environment, newRpc.Server);
 
             asyncCall.Initialize(newRpc.Call);
             var finishedTask = asyncCall.ServerSideCallAsync();
@@ -123,7 +123,7 @@
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment);
+                environment, newRpc.Server);
 
             asyncCall.Initialize(newRpc.Call);
             var finishedTask = asyncCall.ServerSideCallAsync();
@@ -179,7 +179,7 @@
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment);
+                environment, newRpc.Server);
 
             asyncCall.Initialize(newRpc.Call);
             var finishedTask = asyncCall.ServerSideCallAsync();
@@ -239,7 +239,7 @@
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment);
+                environment, newRpc.Server);
 
             asyncCall.Initialize(newRpc.Call);
             var finishedTask = asyncCall.ServerSideCallAsync();
@@ -278,7 +278,7 @@
         {
             // We don't care about the payload type here.
             var asyncCall = new AsyncCallServer<byte[], byte[]>(
-                (payload) => payload, (payload) => payload, environment);
+                (payload) => payload, (payload) => payload, environment, newRpc.Server);
             
             asyncCall.Initialize(newRpc.Call);
             var finishedTask = asyncCall.ServerSideCallAsync();
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index f9b44b1..5ee7ac1 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -74,6 +74,9 @@
 
         public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args)
         {
+            // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
+            // Doing so would make object finalizer crash if we end up abandoning the handle.
+            GrpcEnvironment.GrpcNativeInit();
             return grpcsharp_server_create(cq, args);
         }
 
@@ -109,6 +112,7 @@
         protected override bool ReleaseHandle()
         {
             grpcsharp_server_destroy(handle);
+            GrpcEnvironment.GrpcNativeShutdown();
             return true;
         }
             
diff --git a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
index 382481d..35561d2 100644
--- a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
+++ b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
@@ -51,7 +51,19 @@
         private ConsoleLogger(Type forType)
         {
             this.forType = forType;
-            this.forTypeString = forType != null ? forType.FullName + " " : "";
+            if (forType != null)
+            {
+                var namespaceStr = forType.Namespace ?? "";
+                if (namespaceStr.Length > 0)
+                {
+                     namespaceStr += ".";
+                }
+                this.forTypeString = namespaceStr + forType.Name + " ";
+            }
+            else
+            {
+                this.forTypeString = "";
+            }
         }
  
         /// <summary>
diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs
index 9db2abf..a589b50 100644
--- a/src/csharp/Grpc.Core/Metadata.cs
+++ b/src/csharp/Grpc.Core/Metadata.cs
@@ -46,6 +46,11 @@
     public sealed class Metadata : IList<Metadata.Entry>
     {
         /// <summary>
+        /// All binary headers should have this suffix.
+        /// </summary>
+        public const string BinaryHeaderSuffix = "-bin";
+
+        /// <summary>
         /// An read-only instance of metadata containing no entries.
         /// </summary>
         public static readonly Metadata Empty = new Metadata().Freeze();
@@ -181,23 +186,49 @@
             private static readonly Encoding Encoding = Encoding.ASCII;
 
             readonly string key;
-            string value;
-            byte[] valueBytes;
+            readonly string value;
+            readonly byte[] valueBytes;
 
-            public Entry(string key, byte[] valueBytes)
+            private Entry(string key, string value, byte[] valueBytes)
             {
-                this.key = Preconditions.CheckNotNull(key, "key");
-                this.value = null;
-                this.valueBytes = Preconditions.CheckNotNull(valueBytes, "valueBytes");
+                this.key = key;
+                this.value = value;
+                this.valueBytes = valueBytes;
             }
 
+            /// <summary>
+            /// Initializes a new instance of the <see cref="Grpc.Core.Metadata+Entry"/> struct with a binary value.
+            /// </summary>
+            /// <param name="key">Metadata key, needs to have suffix indicating a binary valued metadata entry.</param>
+            /// <param name="valueBytes">Value bytes.</param>
+            public Entry(string key, byte[] valueBytes)
+            {
+                this.key = NormalizeKey(key);
+                Preconditions.CheckArgument(this.key.EndsWith(BinaryHeaderSuffix),
+                    "Key for binary valued metadata entry needs to have suffix indicating binary value.");
+                this.value = null;
+                Preconditions.CheckNotNull(valueBytes, "valueBytes");
+                this.valueBytes = new byte[valueBytes.Length];
+                Buffer.BlockCopy(valueBytes, 0, this.valueBytes, 0, valueBytes.Length);  // defensive copy to guarantee immutability
+            }
+
+            /// <summary>
+            /// Initializes a new instance of the <see cref="Grpc.Core.Metadata+Entry"/> struct holding an ASCII value.
+            /// </summary>
+            /// <param name="key">Metadata key, must not use suffix indicating a binary valued metadata entry.</param>
+            /// <param name="value">Value string. Only ASCII characters are allowed.</param>
             public Entry(string key, string value)
             {
-                this.key = Preconditions.CheckNotNull(key, "key");
+                this.key = NormalizeKey(key);
+                Preconditions.CheckArgument(!this.key.EndsWith(BinaryHeaderSuffix),
+                    "Key for ASCII valued metadata entry cannot have suffix indicating binary value.");
                 this.value = Preconditions.CheckNotNull(value, "value");
                 this.valueBytes = null;
             }
 
+            /// <summary>
+            /// Gets the metadata entry key.
+            /// </summary>
             public string Key
             {
                 get
@@ -206,33 +237,86 @@
                 }
             }
 
+            /// <summary>
+            /// Gets the binary value of this metadata entry.
+            /// </summary>
             public byte[] ValueBytes
             {
                 get
                 {
                     if (valueBytes == null)
                     {
-                        valueBytes = Encoding.GetBytes(value);
+                        return Encoding.GetBytes(value);
                     }
-                    return valueBytes;
+
+                    // defensive copy to guarantee immutability
+                    var bytes = new byte[valueBytes.Length];
+                    Buffer.BlockCopy(valueBytes, 0, bytes, 0, valueBytes.Length);
+                    return bytes;
                 }
             }
 
+            /// <summary>
+            /// Gets the string value of this metadata entry.
+            /// </summary>
             public string Value
             {
                 get
                 {
-                    if (value == null)
-                    {
-                        value = Encoding.GetString(valueBytes);
-                    }
-                    return value;
+                    Preconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry");
+                    return value ?? Encoding.GetString(valueBytes);
                 }
             }
-                
+
+            /// <summary>
+            /// Returns <c>true</c> if this entry is a binary-value entry.
+            /// </summary>
+            public bool IsBinary
+            {
+                get
+                {
+                    return value == null;
+                }
+            }
+
+            /// <summary>
+            /// Returns a <see cref="System.String"/> that represents the current <see cref="Grpc.Core.Metadata+Entry"/>.
+            /// </summary>
             public override string ToString()
             {
-                return string.Format("[Entry: key={0}, value={1}]", Key, Value);
+                if (IsBinary)
+                {
+                    return string.Format("[Entry: key={0}, valueBytes={1}]", key, valueBytes);
+                }
+                
+                return string.Format("[Entry: key={0}, value={1}]", key, value);
+            }
+
+            /// <summary>
+            /// Gets the serialized value for this entry. For binary metadata entries, this leaks
+            /// the internal <c>valueBytes</c> byte array and caller must not change contents of it.
+            /// </summary>
+            internal byte[] GetSerializedValueUnsafe()
+            {
+                return valueBytes ?? Encoding.GetBytes(value);
+            }
+
+            /// <summary>
+            /// Creates a binary value or ascii value metadata entry from data received from the native layer.
+            /// We trust C core to give us well-formed data, so we don't perform any checks or defensive copying.
+            /// </summary>
+            internal static Entry CreateUnsafe(string key, byte[] valueBytes)
+            {
+                if (key.EndsWith(BinaryHeaderSuffix))
+                {
+                    return new Entry(key, null, valueBytes);
+                }
+                return new Entry(key, Encoding.GetString(valueBytes), null);
+            }
+
+            private static string NormalizeKey(string key)
+            {
+                return Preconditions.CheckNotNull(key, "key").ToLower();
             }
         }
     }
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index c76f126..28f1686 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -50,6 +50,8 @@
     {
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Server>();
 
+        readonly AtomicCounter activeCallCounter = new AtomicCounter();
+
         readonly ServiceDefinitionCollection serviceDefinitions;
         readonly ServerPortCollection ports;
         readonly GrpcEnvironment environment;
@@ -73,7 +75,7 @@
         {
             this.serviceDefinitions = new ServiceDefinitionCollection(this);
             this.ports = new ServerPortCollection(this);
-            this.environment = GrpcEnvironment.GetInstance();
+            this.environment = GrpcEnvironment.AddRef();
             this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
             using (var channelArgs = ChannelOptions.CreateChannelArgs(this.options))
             {
@@ -106,6 +108,17 @@
         }
 
         /// <summary>
+        /// To allow awaiting termination of the server.
+        /// </summary>
+        public Task ShutdownTask
+        {
+            get
+            {
+                return shutdownTcs.Task;
+            }
+        }
+
+        /// <summary>
         /// Starts the server.
         /// </summary>
         public void Start()
@@ -136,18 +149,9 @@
 
             handle.ShutdownAndNotify(HandleServerShutdown, environment);
             await shutdownTcs.Task;
-            handle.Dispose();
-        }
+            DisposeHandle();
 
-        /// <summary>
-        /// To allow awaiting termination of the server.
-        /// </summary>
-        public Task ShutdownTask
-        {
-            get
-            {
-                return shutdownTcs.Task;
-            }
+            await Task.Run(() => GrpcEnvironment.Release());
         }
 
         /// <summary>
@@ -166,7 +170,22 @@
             handle.ShutdownAndNotify(HandleServerShutdown, environment);
             handle.CancelAllCalls();
             await shutdownTcs.Task;
-            handle.Dispose();
+            DisposeHandle();
+        }
+
+        internal void AddCallReference(object call)
+        {
+            activeCallCounter.Increment();
+
+            bool success = false;
+            handle.DangerousAddRef(ref success);
+            Preconditions.CheckState(success);
+        }
+
+        internal void RemoveCallReference(object call)
+        {
+            handle.DangerousRelease();
+            activeCallCounter.Decrement();
         }
 
         /// <summary>
@@ -227,6 +246,16 @@
             }
         }
 
+        private void DisposeHandle()
+        {
+            var activeCallCount = activeCallCounter.Count;
+            if (activeCallCount > 0)
+            {
+                Logger.Warning("Server shutdown has finished but there are still {0} active calls for that server.", activeCallCount);
+            }
+            handle.Dispose();
+        }
+
         /// <summary>
         /// Selects corresponding handler for given call and handles the call.
         /// </summary>
@@ -254,7 +283,7 @@
         {
             if (success)
             {
-                ServerRpcNew newRpc = ctx.GetServerRpcNew();
+                ServerRpcNew newRpc = ctx.GetServerRpcNew(this);
 
                 // after server shutdown, the callback returns with null call
                 if (!newRpc.Call.IsInvalid)
diff --git a/src/csharp/Grpc.Examples.MathClient/MathClient.cs b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
index f9839d9..abd95cb 100644
--- a/src/csharp/Grpc.Examples.MathClient/MathClient.cs
+++ b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
@@ -39,23 +39,21 @@
     {
         public static void Main(string[] args)
         {
-            using (Channel channel = new Channel("127.0.0.1", 23456, Credentials.Insecure))
-            {
-                Math.IMathClient client = new Math.MathClient(channel);
-                MathExamples.DivExample(client);
+            var channel = new Channel("127.0.0.1", 23456, Credentials.Insecure);
+            Math.IMathClient client = new Math.MathClient(channel);
+            MathExamples.DivExample(client);
 
-                MathExamples.DivAsyncExample(client).Wait();
+            MathExamples.DivAsyncExample(client).Wait();
 
-                MathExamples.FibExample(client).Wait();
+            MathExamples.FibExample(client).Wait();
 
-                MathExamples.SumExample(client).Wait();
+            MathExamples.SumExample(client).Wait();
 
-                MathExamples.DivManyExample(client).Wait();
+            MathExamples.DivManyExample(client).Wait();
 
-                MathExamples.DependendRequestsExample(client).Wait();
-            }
+            MathExamples.DependendRequestsExample(client).Wait();
 
-            GrpcEnvironment.Shutdown();
+            channel.ShutdownAsync().Wait();
         }
     }
 }
diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
index 5f7e717..26bef64 100644
--- a/src/csharp/Grpc.Examples.MathServer/MathServer.cs
+++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
@@ -56,7 +56,6 @@
             Console.ReadKey();
 
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
     }
 }
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index fdef950..36c1c94 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -68,9 +68,8 @@
         [TestFixtureTearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
 
         [Test]
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index 024377e..80c35fb 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -71,10 +71,9 @@
         [TestFixtureTearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
 
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
 
         [Test]
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index f4b0a10..24c2227 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -37,13 +37,15 @@
 using System.Threading;
 using System.Threading.Tasks;
 
+using Google.Apis.Auth.OAuth2;
 using Google.ProtocolBuffers;
+
 using grpc.testing;
 using Grpc.Auth;
 using Grpc.Core;
 using Grpc.Core.Utils;
+
 using NUnit.Framework;
-using Google.Apis.Auth.OAuth2;
 
 namespace Grpc.IntegrationTesting
 {
@@ -118,12 +120,10 @@
                 };
             }
 
-            using (Channel channel = new Channel(options.serverHost, options.serverPort.Value, credentials, channelOptions))
-            {
-                TestService.TestServiceClient client = new TestService.TestServiceClient(channel);
-                await RunTestCaseAsync(options.testCase, client);
-            }
-            GrpcEnvironment.Shutdown();
+            var channel = new Channel(options.serverHost, options.serverPort.Value, credentials, channelOptions);
+            TestService.TestServiceClient client = new TestService.TestServiceClient(channel);
+            await RunTestCaseAsync(options.testCase, client);
+            channel.ShutdownAsync().Wait();
         }
 
         private async Task RunTestCaseAsync(string testCase, TestService.TestServiceClient client)
@@ -169,6 +169,9 @@
                 case "cancel_after_first_response":
                     await RunCancelAfterFirstResponseAsync(client);
                     break;
+                case "timeout_on_sleeping_server":
+                    await RunTimeoutOnSleepingServerAsync(client);
+                    break;
                 case "benchmark_empty_unary":
                     RunBenchmarkEmptyUnary(client);
                     break;
@@ -458,6 +461,29 @@
             Console.WriteLine("Passed!");
         }
 
+        public static async Task RunTimeoutOnSleepingServerAsync(TestService.ITestServiceClient client)
+        {
+            Console.WriteLine("running timeout_on_sleeping_server");
+
+            var deadline = DateTime.UtcNow.AddMilliseconds(1);
+            using (var call = client.FullDuplexCall(deadline: deadline))
+            {
+                try
+                {
+                    await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
+                        .SetPayload(CreateZerosPayload(27182)).Build());
+                }
+                catch (InvalidOperationException)
+                {
+                    // Deadline was reached before write has started. Eat the exception and continue.
+                }
+
+                var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.MoveNext());
+                Assert.AreEqual(StatusCode.DeadlineExceeded, ex.Status.StatusCode);
+            }
+            Console.WriteLine("Passed!");
+        }
+
         // This is not an official interop test, but it's useful.
         public static void RunBenchmarkEmptyUnary(TestService.ITestServiceClient client)
         {
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 6fa721b..f3158ae 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -75,9 +75,8 @@
         [TestFixtureTearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
 
         [Test]
@@ -127,5 +126,11 @@
         {
             await InteropClient.RunCancelAfterFirstResponseAsync(client);
         }
+
+        [Test]
+        public async Task TimeoutOnSleepingServerAsync()
+        {
+            await InteropClient.RunTimeoutOnSleepingServerAsync(client);
+        }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
index 504fd11..0cc8b2c 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -107,8 +107,6 @@
             server.Start();
 
             server.ShutdownTask.Wait();
-
-            GrpcEnvironment.Shutdown();
         }
 
         private static ServerOptions ParseArguments(string[] args)
diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
index 1c398eb..8427953 100644
--- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
@@ -85,9 +85,8 @@
         [TestFixtureTearDown]
         public void Cleanup()
         {
-            channel.Dispose();
+            channel.ShutdownAsync().Wait();
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Shutdown();
         }
 
         [Test]
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index fc9470f..489e219 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -595,7 +595,7 @@
     grpc_call *call, grpcsharp_batch_context *ctx, const char *send_buffer,
     size_t send_buffer_len, grpc_metadata_array *initial_metadata, gpr_uint32 write_flags) {
   /* TODO: don't use magic number */
-  grpc_op ops[5];
+  grpc_op ops[4];
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -615,23 +615,18 @@
   ops[2].flags = 0;
   ops[2].reserved = NULL;
 
-  ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
-  ops[3].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
-  ops[3].flags = 0;
-  ops[3].reserved = NULL;
-
-  ops[4].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
-  ops[4].data.recv_status_on_client.trailing_metadata =
+  ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[3].data.recv_status_on_client.trailing_metadata =
       &(ctx->recv_status_on_client.trailing_metadata);
-  ops[4].data.recv_status_on_client.status =
+  ops[3].data.recv_status_on_client.status =
       &(ctx->recv_status_on_client.status);
   /* not using preallocation for status_details */
-  ops[4].data.recv_status_on_client.status_details =
+  ops[3].data.recv_status_on_client.status_details =
       &(ctx->recv_status_on_client.status_details);
-  ops[4].data.recv_status_on_client.status_details_capacity =
+  ops[3].data.recv_status_on_client.status_details_capacity =
       &(ctx->recv_status_on_client.status_details_capacity);
-  ops[4].flags = 0;
-  ops[4].reserved = NULL;
+  ops[3].flags = 0;
+  ops[3].reserved = NULL;
 
   return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
                                NULL);
@@ -642,7 +637,7 @@
                                       grpcsharp_batch_context *ctx,
                                       grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
-  grpc_op ops[3];
+  grpc_op ops[2];
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -652,28 +647,36 @@
   ops[0].flags = 0;
   ops[0].reserved = NULL;
 
-  ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
-  ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
+  ops[1].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  ops[1].data.recv_status_on_client.trailing_metadata =
+      &(ctx->recv_status_on_client.trailing_metadata);
+  ops[1].data.recv_status_on_client.status =
+      &(ctx->recv_status_on_client.status);
+  /* not using preallocation for status_details */
+  ops[1].data.recv_status_on_client.status_details =
+      &(ctx->recv_status_on_client.status_details);
+  ops[1].data.recv_status_on_client.status_details_capacity =
+      &(ctx->recv_status_on_client.status_details_capacity);
   ops[1].flags = 0;
   ops[1].reserved = NULL;
 
-  ops[2].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
-  ops[2].data.recv_status_on_client.trailing_metadata =
-      &(ctx->recv_status_on_client.trailing_metadata);
-  ops[2].data.recv_status_on_client.status =
-      &(ctx->recv_status_on_client.status);
-  /* not using preallocation for status_details */
-  ops[2].data.recv_status_on_client.status_details =
-      &(ctx->recv_status_on_client.status_details);
-  ops[2].data.recv_status_on_client.status_details_capacity =
-      &(ctx->recv_status_on_client.status_details_capacity);
-  ops[2].flags = 0;
-  ops[2].reserved = NULL;
-
   return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
                                NULL);
 }
 
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
+	grpc_call *call, grpcsharp_batch_context *ctx) {
+	/* TODO: don't use magic number */
+	grpc_op ops[1];
+	ops[0].op = GRPC_OP_RECV_INITIAL_METADATA;
+	ops[0].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
+	ops[0].flags = 0;
+	ops[0].reserved = NULL;
+
+	return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
+		NULL);
+}
+
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
 grpcsharp_call_send_message(grpc_call *call, grpcsharp_batch_context *ctx,
                             const char *send_buffer, size_t send_buffer_len,
diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc
index 1b8e7b4..6e17197 100644
--- a/src/node/ext/server_credentials.cc
+++ b/src/node/ext/server_credentials.cc
@@ -41,6 +41,7 @@
 namespace grpc {
 namespace node {
 
+using v8::Array;
 using v8::Exception;
 using v8::External;
 using v8::Function;
@@ -52,6 +53,7 @@
 using v8::Object;
 using v8::ObjectTemplate;
 using v8::Persistent;
+using v8::String;
 using v8::Value;
 
 NanCallback *ServerCredentials::constructor;
@@ -122,25 +124,66 @@
   // TODO: have the node API support multiple key/cert pairs.
   NanScope();
   char *root_certs = NULL;
-  grpc_ssl_pem_key_cert_pair key_cert_pair;
   if (::node::Buffer::HasInstance(args[0])) {
     root_certs = ::node::Buffer::Data(args[0]);
   } else if (!(args[0]->IsNull() || args[0]->IsUndefined())) {
     return NanThrowTypeError(
         "createSSl's first argument must be a Buffer if provided");
   }
-  if (!::node::Buffer::HasInstance(args[1])) {
-    return NanThrowTypeError("createSsl's second argument must be a Buffer");
+  if (!args[1]->IsArray()) {
+    return NanThrowTypeError(
+        "createSsl's second argument must be a list of objects");
   }
-  key_cert_pair.private_key = ::node::Buffer::Data(args[1]);
-  if (!::node::Buffer::HasInstance(args[2])) {
-    return NanThrowTypeError("createSsl's third argument must be a Buffer");
+  int force_client_auth = 0;
+  if (args[2]->IsBoolean()) {
+    force_client_auth = (int)args[2]->BooleanValue();
+  } else if (!(args[2]->IsUndefined() || args[2]->IsNull())) {
+    return NanThrowTypeError(
+        "createSsl's third argument must be a boolean if provided");
   }
-  key_cert_pair.cert_chain = ::node::Buffer::Data(args[2]);
-  // TODO Add a force_client_auth parameter and pass it as the last parameter
-  // here.
+  Handle<Array> pair_list = Local<Array>::Cast(args[1]);
+  uint32_t key_cert_pair_count = pair_list->Length();
+  grpc_ssl_pem_key_cert_pair *key_cert_pairs = new grpc_ssl_pem_key_cert_pair[
+      key_cert_pair_count];
+
+  Handle<String> key_key = NanNew("private_key");
+  Handle<String> cert_key = NanNew("cert_chain");
+
+  for(uint32_t i = 0; i < key_cert_pair_count; i++) {
+    if (!pair_list->Get(i)->IsObject()) {
+      delete key_cert_pairs;
+      return NanThrowTypeError("Key/cert pairs must be objects");
+    }
+    Handle<Object> pair_obj = pair_list->Get(i)->ToObject();
+    if (!pair_obj->HasOwnProperty(key_key)) {
+      delete key_cert_pairs;
+      return NanThrowTypeError(
+          "Key/cert pairs must have a private_key and a cert_chain");
+    }
+    if (!pair_obj->HasOwnProperty(cert_key)) {
+      delete key_cert_pairs;
+      return NanThrowTypeError(
+          "Key/cert pairs must have a private_key and a cert_chain");
+    }
+    if (!::node::Buffer::HasInstance(pair_obj->Get(key_key))) {
+      delete key_cert_pairs;
+      return NanThrowTypeError("private_key must be a Buffer");
+    }
+    if (!::node::Buffer::HasInstance(pair_obj->Get(cert_key))) {
+      delete key_cert_pairs;
+      return NanThrowTypeError("cert_chain must be a Buffer");
+    }
+    key_cert_pairs[i].private_key = ::node::Buffer::Data(
+        pair_obj->Get(key_key));
+    key_cert_pairs[i].cert_chain = ::node::Buffer::Data(
+        pair_obj->Get(cert_key));
+  }
   grpc_server_credentials *creds =
-      grpc_ssl_server_credentials_create(root_certs, &key_cert_pair, 1, 0);
+      grpc_ssl_server_credentials_create(root_certs,
+                                         key_cert_pairs,
+                                         key_cert_pair_count,
+                                         force_client_auth);
+  delete key_cert_pairs;
   if (creds == NULL) {
     NanReturnNull();
   }
diff --git a/src/node/health_check/health.js b/src/node/health_check/health.js
index 87e0019..84d7e05 100644
--- a/src/node/health_check/health.js
+++ b/src/node/health_check/health.js
@@ -45,17 +45,13 @@
   this.statusMap = _.clone(statusMap);
 }
 
-HealthImplementation.prototype.setStatus = function(host, service, status) {
-  if (!this.statusMap[host]) {
-    this.statusMap[host] = {};
-  }
-  this.statusMap[host][service] = status;
+HealthImplementation.prototype.setStatus = function(service, status) {
+  this.statusMap[service] = status;
 };
 
 HealthImplementation.prototype.check = function(call, callback){
-  var host = call.request.host;
   var service = call.request.service;
-  var status = _.get(this.statusMap, [host, service], null);
+  var status = _.get(this.statusMap, service, null);
   if (status === null) {
     callback({code:grpc.status.NOT_FOUND});
   } else {
diff --git a/src/node/health_check/health.proto b/src/node/health_check/health.proto
index d31df1e..57f4aaa 100644
--- a/src/node/health_check/health.proto
+++ b/src/node/health_check/health.proto
@@ -32,8 +32,7 @@
 package grpc.health.v1alpha;
 
 message HealthCheckRequest {
-  string host = 1;
-  string service = 2;
+  string service = 1;
 }
 
 message HealthCheckResponse {
@@ -47,4 +46,4 @@
 
 service Health {
   rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
-}
\ No newline at end of file
+}
diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js
index 1242a0f..99155e9 100644
--- a/src/node/interop/interop_server.js
+++ b/src/node/interop/interop_server.js
@@ -169,8 +169,8 @@
     var key_data = fs.readFileSync(key_path);
     var pem_data = fs.readFileSync(pem_path);
     server_creds = grpc.ServerCredentials.createSsl(null,
-                                                    key_data,
-                                                    pem_data);
+                                                    [{private_key: key_data,
+                                                      cert_chain: pem_data}]);
   } else {
     server_creds = grpc.ServerCredentials.createInsecure();
   }
diff --git a/src/node/src/client.js b/src/node/src/client.js
index 48fe0dd..7b7eae5 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -280,7 +280,9 @@
       }
       var client_batch = {};
       var message = serialize(argument);
-      message.grpcWriteFlags = options.flags;
+      if (options) {
+        message.grpcWriteFlags = options.flags;
+      }
       client_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
       client_batch[grpc.opType.SEND_MESSAGE] = message;
       client_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
@@ -416,7 +418,9 @@
       }
       var start_batch = {};
       var message = serialize(argument);
-      message.grpcWriteFlags = options.flags;
+      if (options) {
+        message.grpcWriteFlags = options.flags;
+      }
       start_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata;
       start_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
       start_batch[grpc.opType.SEND_MESSAGE] = message;
diff --git a/src/node/test/health_test.js b/src/node/test/health_test.js
index be4ef1d..04959f5 100644
--- a/src/node/test/health_test.js
+++ b/src/node/test/health_test.js
@@ -41,13 +41,9 @@
 
 describe('Health Checking', function() {
   var statusMap = {
-    '': {
-      '': 'SERVING',
-      'grpc.test.TestService': 'NOT_SERVING',
-    },
-    virtual_host: {
-      'grpc.test.TestService': 'SERVING'
-    }
+    '': 'SERVING',
+    'grpc.test.TestServiceNotServing': 'NOT_SERVING',
+    'grpc.test.TestServiceServing': 'SERVING'
   };
   var healthServer = new grpc.Server();
   healthServer.addProtoService(health.service,
@@ -71,15 +67,15 @@
     });
   });
   it('should say that a disabled service is NOT_SERVING', function(done) {
-    healthClient.check({service: 'grpc.test.TestService'},
+    healthClient.check({service: 'grpc.test.TestServiceNotServing'},
                        function(err, response) {
                          assert.ifError(err);
                          assert.strictEqual(response.status, 'NOT_SERVING');
                          done();
                        });
   });
-  it('should say that a service on another host is SERVING', function(done) {
-    healthClient.check({host: 'virtual_host', service: 'grpc.test.TestService'},
+  it('should say that an enabled service is SERVING', function(done) {
+    healthClient.check({service: 'grpc.test.TestServiceServing'},
                        function(err, response) {
                          assert.ifError(err);
                          assert.strictEqual(response.status, 'SERVING');
@@ -93,12 +89,4 @@
       done();
     });
   });
-  it('should get NOT_FOUND if the host is not registered', function(done) {
-    healthClient.check({host: 'wrong_host', service: 'grpc.test.TestService'},
-                       function(err, response) {
-                         assert(err);
-                         assert.strictEqual(err.code, grpc.status.NOT_FOUND);
-                         done();
-                       });
-  });
 });
diff --git a/src/node/test/server_test.js b/src/node/test/server_test.js
index 20c9a07..78bac8d 100644
--- a/src/node/test/server_test.js
+++ b/src/node/test/server_test.js
@@ -70,7 +70,9 @@
       var pem_path = path.join(__dirname, '../test/data/server1.pem');
       var key_data = fs.readFileSync(key_path);
       var pem_data = fs.readFileSync(pem_path);
-      var creds = grpc.ServerCredentials.createSsl(null, key_data, pem_data);
+      var creds = grpc.ServerCredentials.createSsl(null,
+                                                   [{private_key: key_data,
+                                                     cert_chain: pem_data}]);
       assert.doesNotThrow(function() {
         port = server.addHttp2Port('0.0.0.0:0', creds);
       });
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 6009a8d..252623d 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -216,13 +216,18 @@
   char *method;
   int method_len;
   zval *deadline_obj;
-  /* "OsO" == 1 Object, 1 string, 1 Object */
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO", &channel_obj,
-                            grpc_ce_channel, &method, &method_len,
-                            &deadline_obj, grpc_ce_timeval) == FAILURE) {
+  char *host_override = NULL;
+  int host_override_len = 0;
+  /* "OsO|s" == 1 Object, 1 string, 1 Object, 1 optional string */
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s",
+                            &channel_obj, grpc_ce_channel,
+                            &method, &method_len,
+                            &deadline_obj, grpc_ce_timeval,
+                            &host_override, &host_override_len)
+      == FAILURE) {
     zend_throw_exception(
         spl_ce_InvalidArgumentException,
-        "Call expects a Channel, a String, and a Timeval",
+        "Call expects a Channel, a String, a Timeval and an optional String",
         1 TSRMLS_CC);
     return;
   }
@@ -241,7 +246,7 @@
           deadline_obj TSRMLS_CC);
   call->wrapped = grpc_channel_create_call(
       channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, completion_queue, method,
-      channel->target, deadline->wrapped, NULL);
+      host_override, deadline->wrapped, NULL);
 }
 
 /**
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index f8ce04d..7a98167 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -64,7 +64,6 @@
   if (channel->wrapped != NULL) {
     grpc_channel_destroy(channel->wrapped);
   }
-  efree(channel->target);
   efree(channel);
 }
 
@@ -141,9 +140,6 @@
   HashTable *array_hash;
   zval **creds_obj = NULL;
   wrapped_grpc_credentials *creds = NULL;
-  zval **override_obj;
-  char *override;
-  int override_len;
   /* "s|a" == 1 string, 1 optional array */
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &target,
                             &target_length, &args_array) == FAILURE) {
@@ -151,8 +147,6 @@
                          "Channel expects a string and an array", 1 TSRMLS_CC);
     return;
   }
-  override = target;
-  override_len = target_length;
   if (args_array == NULL) {
     channel->wrapped = grpc_insecure_channel_create(target, NULL, NULL);
   } else {
@@ -169,19 +163,6 @@
           *creds_obj TSRMLS_CC);
       zend_hash_del(array_hash, "credentials", 12);
     }
-    if (zend_hash_find(array_hash, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
-                       sizeof(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
-                       (void **)&override_obj) == SUCCESS) {
-      if (Z_TYPE_PP(override_obj) != IS_STRING) {
-        zend_throw_exception(spl_ce_InvalidArgumentException,
-                             GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
-                             " must be a string",
-                             1 TSRMLS_CC);
-        return;
-      }
-      override = Z_STRVAL_PP(override_obj);
-      override_len = Z_STRLEN_PP(override_obj);
-    }
     php_grpc_read_args_array(args_array, &args);
     if (creds == NULL) {
       channel->wrapped = grpc_insecure_channel_create(target, &args, NULL);
@@ -192,8 +173,6 @@
     }
     efree(args.args);
   }
-  channel->target = ecalloc(override_len + 1, sizeof(char));
-  memcpy(channel->target, override, override_len);
 }
 
 /**
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index c13fa4c..78a16ed 100755
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -53,7 +53,6 @@
   zend_object std;
 
   grpc_channel *wrapped;
-  char *target;
 } wrapped_grpc_channel;
 
 /* Initializes the Channel class */
diff --git a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
index 8b7e67f..287621d 100644
--- a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
+++ b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
@@ -39,6 +39,14 @@
   protected static $client;
   protected static $timeout;
 
+  public function testWaitForNotReady() {
+    $this->assertFalse(self::$client->waitForReady(1));
+  }
+
+  public function testWaitForReady() {
+    $this->assertTrue(self::$client->waitForReady(250000));
+  }
+
   public function testSimpleRequest() {
     $div_arg = new math\DivArgs();
     $div_arg->setDividend(7);
diff --git a/src/php/tests/generated_code/GeneratedCodeTest.php b/src/php/tests/generated_code/GeneratedCodeTest.php
index 1e4742f..a1a2ce8 100755
--- a/src/php/tests/generated_code/GeneratedCodeTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeTest.php
@@ -35,7 +35,7 @@
 
 class GeneratedCodeTest extends AbstractGeneratedCodeTest {
   public static function setUpBeforeClass() {
-    self::$client = new math\MathClient(new Grpc\BaseStub(
-        getenv('GRPC_TEST_HOST'), []));
+    self::$client = new math\MathClient(
+        getenv('GRPC_TEST_HOST'), []);
   }
 }
diff --git a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
index f8ec1e7..68f57d3 100644
--- a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
@@ -35,13 +35,13 @@
 
 class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest {
   public static function setUpBeforeClass() {
-    self::$client = new math\MathClient(new Grpc\BaseStub(
+    self::$client = new math\MathClient(
         getenv('GRPC_TEST_HOST'), ['update_metadata' =>
                                    function($a_hash,
                                             $client = array()) {
                                      $a_copy = $a_hash;
                                      $a_copy['foo'] = ['bar'];
                                      return $a_copy;
-                                   }]));
+                                   }]);
   }
 }
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index f91c006..60341b9 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -40,13 +40,15 @@
         file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
         file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
     $this->server = new Grpc\Server();
-    $port = $this->server->addSecureHttp2Port('0.0.0.0:0',
+    $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0',
                                               $server_credentials);
     $this->server->start();
+    $this->host_override = 'foo.test.google.fr';
     $this->channel = new Grpc\Channel(
-        'localhost:' . $port,
+        'localhost:' . $this->port,
         [
-            'grpc.ssl_target_name_override' => 'foo.test.google.fr',
+            'grpc.ssl_target_name_override' => $this->host_override,
+            'grpc.default_authority' => $this->host_override,
             'credentials' => $credentials
          ]);
   }
@@ -61,7 +63,8 @@
     $status_text = 'xyz';
     $call = new Grpc\Call($this->channel,
                           'dummy_method',
-                          $deadline);
+                          $deadline,
+                          $this->host_override);
 
     $event = $call->startBatch([
         Grpc\OP_SEND_INITIAL_METADATA => [],
@@ -112,7 +115,8 @@
 
     $call = new Grpc\Call($this->channel,
                           'dummy_method',
-                          $deadline);
+                          $deadline,
+                          $this->host_override);
 
     $event = $call->startBatch([
         Grpc\OP_SEND_INITIAL_METADATA => [],
diff --git a/src/python/grpcio/grpc/framework/core/__init__.py b/src/python/grpcio/grpc/framework/core/__init__.py
new file mode 100644
index 0000000..7086519
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/__init__.py
@@ -0,0 +1,30 @@
+# 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.
+
+
diff --git a/src/python/grpcio/grpc/framework/core/_constants.py b/src/python/grpcio/grpc/framework/core/_constants.py
new file mode 100644
index 0000000..d3be3a4
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_constants.py
@@ -0,0 +1,59 @@
+# 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.
+
+"""Private constants for the package."""
+
+from grpc.framework.interfaces.base import base
+from grpc.framework.interfaces.links import links
+
+TICKET_SUBSCRIPTION_FOR_BASE_SUBSCRIPTION_KIND = {
+    base.Subscription.Kind.NONE: links.Ticket.Subscription.NONE,
+    base.Subscription.Kind.TERMINATION_ONLY:
+        links.Ticket.Subscription.TERMINATION,
+    base.Subscription.Kind.FULL: links.Ticket.Subscription.FULL,
+    }
+
+# Mapping from abortive operation outcome to ticket termination to be
+# sent to the other side of the operation, or None to indicate that no
+# ticket should be sent to the other side in the event of such an
+# outcome.
+ABORTION_OUTCOME_TO_TICKET_TERMINATION = {
+    base.Outcome.CANCELLED: links.Ticket.Termination.CANCELLATION,
+    base.Outcome.EXPIRED: links.Ticket.Termination.EXPIRATION,
+    base.Outcome.LOCAL_SHUTDOWN: links.Ticket.Termination.SHUTDOWN,
+    base.Outcome.REMOTE_SHUTDOWN: None,
+    base.Outcome.RECEPTION_FAILURE: links.Ticket.Termination.RECEPTION_FAILURE,
+    base.Outcome.TRANSMISSION_FAILURE: None,
+    base.Outcome.LOCAL_FAILURE: links.Ticket.Termination.LOCAL_FAILURE,
+    base.Outcome.REMOTE_FAILURE: links.Ticket.Termination.REMOTE_FAILURE,
+}
+
+INTERNAL_ERROR_LOG_MESSAGE = ':-( RPC Framework (Core) internal error! )-:'
+TERMINATION_CALLBACK_EXCEPTION_LOG_MESSAGE = (
+    'Exception calling termination callback!')
diff --git a/src/python/grpcio/grpc/framework/core/_context.py b/src/python/grpcio/grpc/framework/core/_context.py
new file mode 100644
index 0000000..24a12b6
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_context.py
@@ -0,0 +1,92 @@
+# 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.
+
+"""State and behavior for operation context."""
+
+import time
+
+# _interfaces is referenced from specification in this module.
+from grpc.framework.core import _interfaces  # pylint: disable=unused-import
+from grpc.framework.interfaces.base import base
+
+
+class OperationContext(base.OperationContext):
+  """An implementation of interfaces.OperationContext."""
+
+  def __init__(
+      self, lock, termination_manager, transmission_manager,
+      expiration_manager):
+    """Constructor.
+
+    Args:
+      lock: The operation-wide lock.
+      termination_manager: The _interfaces.TerminationManager for the operation.
+      transmission_manager: The _interfaces.TransmissionManager for the
+        operation.
+      expiration_manager: The _interfaces.ExpirationManager for the operation.
+    """
+    self._lock = lock
+    self._termination_manager = termination_manager
+    self._transmission_manager = transmission_manager
+    self._expiration_manager = expiration_manager
+
+  def _abort(self, outcome):
+    with self._lock:
+      if self._termination_manager.outcome is None:
+        self._termination_manager.abort(outcome)
+        self._transmission_manager.abort(outcome)
+        self._expiration_manager.terminate()
+
+  def outcome(self):
+    """See base.OperationContext.outcome for specification."""
+    with self._lock:
+      return self._termination_manager.outcome
+
+  def add_termination_callback(self, callback):
+    """See base.OperationContext.add_termination_callback."""
+    with self._lock:
+      if self._termination_manager.outcome is None:
+        self._termination_manager.add_callback(callback)
+        return None
+      else:
+        return self._termination_manager.outcome
+
+  def time_remaining(self):
+    """See base.OperationContext.time_remaining for specification."""
+    with self._lock:
+      deadline = self._expiration_manager.deadline()
+    return max(0.0, deadline - time.time())
+
+  def cancel(self):
+    """See base.OperationContext.cancel for specification."""
+    self._abort(base.Outcome.CANCELLED)
+
+  def fail(self, exception):
+    """See base.OperationContext.fail for specification."""
+    self._abort(base.Outcome.LOCAL_FAILURE)
diff --git a/src/python/grpcio/grpc/framework/core/_emission.py b/src/python/grpcio/grpc/framework/core/_emission.py
new file mode 100644
index 0000000..7c702ab
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_emission.py
@@ -0,0 +1,97 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""State and behavior for handling emitted values."""
+
+from grpc.framework.core import _interfaces
+from grpc.framework.interfaces.base import base
+
+
+class EmissionManager(_interfaces.EmissionManager):
+  """An EmissionManager implementation."""
+
+  def __init__(
+      self, lock, termination_manager, transmission_manager,
+      expiration_manager):
+    """Constructor.
+
+    Args:
+      lock: The operation-wide lock.
+      termination_manager: The _interfaces.TerminationManager for the operation.
+      transmission_manager: The _interfaces.TransmissionManager for the
+        operation.
+      expiration_manager: The _interfaces.ExpirationManager for the operation.
+    """
+    self._lock = lock
+    self._termination_manager = termination_manager
+    self._transmission_manager = transmission_manager
+    self._expiration_manager = expiration_manager
+    self._ingestion_manager = None
+
+    self._initial_metadata_seen = False
+    self._payload_seen = False
+    self._completion_seen = False
+
+  def set_ingestion_manager(self, ingestion_manager):
+    """Sets the ingestion manager with which this manager will cooperate.
+
+    Args:
+      ingestion_manager: The _interfaces.IngestionManager for the operation.
+    """
+    self._ingestion_manager = ingestion_manager
+
+  def advance(
+      self, initial_metadata=None, payload=None, completion=None,
+      allowance=None):
+    initial_metadata_present = initial_metadata is not None
+    payload_present = payload is not None
+    completion_present = completion is not None
+    allowance_present = allowance is not None
+    with self._lock:
+      if self._termination_manager.outcome is None:
+        if (initial_metadata_present and (
+                self._initial_metadata_seen or self._payload_seen or
+                self._completion_seen) or
+            payload_present and self._completion_seen or
+            completion_present and self._completion_seen or
+            allowance_present and allowance <= 0):
+          self._termination_manager.abort(base.Outcome.LOCAL_FAILURE)
+          self._transmission_manager.abort(base.Outcome.LOCAL_FAILURE)
+          self._expiration_manager.terminate()
+        else:
+          self._initial_metadata_seen |= initial_metadata_present
+          self._payload_seen |= payload_present
+          self._completion_seen |= completion_present
+          if completion_present:
+            self._termination_manager.emission_complete()
+            self._ingestion_manager.local_emissions_done()
+          self._transmission_manager.advance(
+              initial_metadata, payload, completion, allowance)
+          if allowance_present:
+            self._ingestion_manager.add_local_allowance(allowance)
diff --git a/src/python/grpcio/grpc/framework/core/_end.py b/src/python/grpcio/grpc/framework/core/_end.py
new file mode 100644
index 0000000..fb2c532
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_end.py
@@ -0,0 +1,251 @@
+# 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.
+
+"""Implementation of base.End."""
+
+import abc
+import enum
+import threading
+import uuid
+
+from grpc.framework.core import _operation
+from grpc.framework.core import _utilities
+from grpc.framework.foundation import callable_util
+from grpc.framework.foundation import later
+from grpc.framework.foundation import logging_pool
+from grpc.framework.interfaces.base import base
+from grpc.framework.interfaces.links import links
+from grpc.framework.interfaces.links import utilities
+
+_IDLE_ACTION_EXCEPTION_LOG_MESSAGE = 'Exception calling idle action!'
+
+
+class End(base.End, links.Link):
+  """A bridge between base.End and links.Link.
+
+  Implementations of this interface translate arriving tickets into
+  calls on application objects implementing base interfaces and
+  translate calls from application objects implementing base interfaces
+  into tickets sent to a joined link.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class _Cycle(object):
+  """State for a single start-stop End lifecycle."""
+
+  def __init__(self, pool):
+    self.pool = pool
+    self.grace = False
+    self.futures = []
+    self.operations = {}
+    self.idle_actions = []
+
+
+def _abort(operations):
+  for operation in operations:
+    operation.abort(base.Outcome.LOCAL_SHUTDOWN)
+
+
+def _cancel_futures(futures):
+  for future in futures:
+    futures.cancel()
+
+
+def _future_shutdown(lock, cycle, event):
+  def in_future():
+    with lock:
+      _abort(cycle.operations.values())
+      _cancel_futures(cycle.futures)
+      pool = cycle.pool
+    cycle.pool.shutdown(wait=True)
+  return in_future
+
+
+def _termination_action(lock, stats, operation_id, cycle):
+  """Constructs the termination action for a single operation.
+
+  Args:
+    lock: A lock to hold during the termination action.
+    states: A mapping from base.Outcome values to integers to increment with
+      the outcome given to the termination action.
+    operation_id: The operation ID for the termination action.
+    cycle: A _Cycle value to be updated during the termination action.
+
+  Returns:
+    A callable that takes an operation outcome as its sole parameter and that
+      should be used as the termination action for the operation associated
+      with the given operation ID.
+  """
+  def termination_action(outcome):
+    with lock:
+      stats[outcome] += 1
+      cycle.operations.pop(operation_id, None)
+      if not cycle.operations:
+        for action in cycle.idle_actions:
+          cycle.pool.submit(action)
+        cycle.idle_actions = []
+        if cycle.grace:
+          _cancel_futures(cycle.futures)
+  return termination_action
+
+
+class _End(End):
+  """An End implementation."""
+
+  def __init__(self, servicer_package):
+    """Constructor.
+
+    Args:
+      servicer_package: A _ServicerPackage for servicing operations or None if
+        this end will not be used to service operations.
+    """
+    self._lock = threading.Condition()
+    self._servicer_package = servicer_package
+
+    self._stats = {outcome: 0 for outcome in base.Outcome}
+
+    self._mate = None
+
+    self._cycle = None
+
+  def start(self):
+    """See base.End.start for specification."""
+    with self._lock:
+      if self._cycle is not None:
+        raise ValueError('Tried to start a not-stopped End!')
+      else:
+        self._cycle = _Cycle(logging_pool.pool(1))
+
+  def stop(self, grace):
+    """See base.End.stop for specification."""
+    with self._lock:
+      if self._cycle is None:
+        event = threading.Event()
+        event.set()
+        return event
+      elif not self._cycle.operations:
+        event = threading.Event()
+        self._cycle.pool.submit(event.set)
+        self._cycle.pool.shutdown(wait=False)
+        self._cycle = None
+        return event
+      else:
+        self._cycle.grace = True
+        event = threading.Event()
+        self._cycle.idle_actions.append(event.set)
+        if 0 < grace:
+          future = later.later(
+              grace, _future_shutdown(self._lock, self._cycle, event))
+          self._cycle.futures.append(future)
+        else:
+          _abort(self._cycle.operations.values())
+        return event
+
+  def operate(
+      self, group, method, subscription, timeout, initial_metadata=None,
+      payload=None, completion=None):
+    """See base.End.operate for specification."""
+    operation_id = uuid.uuid4()
+    with self._lock:
+      if self._cycle is None or self._cycle.grace:
+        raise ValueError('Can\'t operate on stopped or stopping End!')
+      termination_action = _termination_action(
+          self._lock, self._stats, operation_id, self._cycle)
+      operation = _operation.invocation_operate(
+          operation_id, group, method, subscription, timeout, initial_metadata,
+          payload, completion, self._mate.accept_ticket, termination_action,
+          self._cycle.pool)
+      self._cycle.operations[operation_id] = operation
+      return operation.context, operation.operator
+
+  def operation_stats(self):
+    """See base.End.operation_stats for specification."""
+    with self._lock:
+      return dict(self._stats)
+
+  def add_idle_action(self, action):
+    """See base.End.add_idle_action for specification."""
+    with self._lock:
+      if self._cycle is None:
+        raise ValueError('Can\'t add idle action to stopped End!')
+      action_with_exceptions_logged = callable_util.with_exceptions_logged(
+          action, _IDLE_ACTION_EXCEPTION_LOG_MESSAGE)
+      if self._cycle.operations:
+        self._cycle.idle_actions.append(action_with_exceptions_logged)
+      else:
+        self._cycle.pool.submit(action_with_exceptions_logged)
+
+  def accept_ticket(self, ticket):
+    """See links.Link.accept_ticket for specification."""
+    with self._lock:
+      if self._cycle is not None and not self._cycle.grace:
+        operation = self._cycle.operations.get(ticket.operation_id)
+        if operation is not None:
+          operation.handle_ticket(ticket)
+        elif self._servicer_package is not None:
+          termination_action = _termination_action(
+              self._lock, self._stats, ticket.operation_id, self._cycle)
+          operation = _operation.service_operate(
+              self._servicer_package, ticket, self._mate.accept_ticket,
+              termination_action, self._cycle.pool)
+          if operation is not None:
+            self._cycle.operations[ticket.operation_id] = operation
+
+  def join_link(self, link):
+    """See links.Link.join_link for specification."""
+    with self._lock:
+      self._mate = utilities.NULL_LINK if link is None else link
+
+
+def serviceless_end_link():
+  """Constructs an End usable only for invoking operations.
+
+  Returns:
+    An End usable for translating operations into ticket exchange.
+  """
+  return _End(None)
+
+
+def serviceful_end_link(servicer, default_timeout, maximum_timeout):
+  """Constructs an End capable of servicing operations.
+
+  Args:
+    servicer: An interfaces.Servicer for servicing operations.
+    default_timeout: A length of time in seconds to be used as the default
+      time alloted for a single operation.
+    maximum_timeout: A length of time in seconds to be used as the maximum
+      time alloted for a single operation.
+
+  Returns:
+    An End capable of servicing the operations requested of it through ticket
+      exchange.
+  """
+  return _End(
+      _utilities.ServicerPackage(servicer, default_timeout, maximum_timeout))
diff --git a/src/python/grpcio/grpc/framework/core/_expiration.py b/src/python/grpcio/grpc/framework/core/_expiration.py
new file mode 100644
index 0000000..d94bdf2
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_expiration.py
@@ -0,0 +1,152 @@
+# 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.
+
+"""State and behavior for operation expiration."""
+
+import time
+
+from grpc.framework.core import _interfaces
+from grpc.framework.foundation import later
+from grpc.framework.interfaces.base import base
+
+
+class _ExpirationManager(_interfaces.ExpirationManager):
+  """An implementation of _interfaces.ExpirationManager."""
+
+  def __init__(
+      self, commencement, timeout, maximum_timeout, lock, termination_manager,
+      transmission_manager):
+    """Constructor.
+
+    Args:
+      commencement: The time in seconds since the epoch at which the operation
+        began.
+      timeout: A length of time in seconds to allow for the operation to run.
+      maximum_timeout: The maximum length of time in seconds to allow for the
+        operation to run despite what is requested via this object's
+        change_timout method.
+      lock: The operation-wide lock.
+      termination_manager: The _interfaces.TerminationManager for the operation.
+      transmission_manager: The _interfaces.TransmissionManager for the
+        operation.
+    """
+    self._lock = lock
+    self._termination_manager = termination_manager
+    self._transmission_manager = transmission_manager
+    self._commencement = commencement
+    self._maximum_timeout = maximum_timeout
+
+    self._timeout = timeout
+    self._deadline = commencement + timeout
+    self._index = None
+    self._future = None
+
+  def _expire(self, index):
+    def expire():
+      with self._lock:
+        if self._future is not None and index == self._index:
+          self._future = None
+          self._termination_manager.expire()
+          self._transmission_manager.abort(base.Outcome.EXPIRED)
+    return expire
+
+  def start(self):
+    self._index = 0
+    self._future = later.later(self._timeout, self._expire(0))
+
+  def change_timeout(self, timeout):
+    if self._future is not None and timeout != self._timeout:
+      self._future.cancel()
+      new_timeout = min(timeout, self._maximum_timeout)
+      new_index = self._index + 1
+      self._timeout = new_timeout
+      self._deadline = self._commencement + new_timeout
+      self._index = new_index
+      delay = self._deadline - time.time()
+      self._future = later.later(delay, self._expire(new_index))
+      if new_timeout != timeout:
+        self._transmission_manager.timeout(new_timeout)
+
+  def deadline(self):
+    return self._deadline
+
+  def terminate(self):
+    if self._future:
+      self._future.cancel()
+      self._future = None
+    self._deadline_index = None
+
+
+def invocation_expiration_manager(
+    timeout, lock, termination_manager, transmission_manager):
+  """Creates an _interfaces.ExpirationManager appropriate for front-side use.
+
+  Args:
+    timeout: A length of time in seconds to allow for the operation to run.
+    lock: The operation-wide lock.
+    termination_manager: The _interfaces.TerminationManager for the operation.
+    transmission_manager: The _interfaces.TransmissionManager for the
+      operation.
+
+  Returns:
+    An _interfaces.ExpirationManager appropriate for invocation-side use.
+  """
+  expiration_manager = _ExpirationManager(
+      time.time(), timeout, timeout, lock, termination_manager,
+      transmission_manager)
+  expiration_manager.start()
+  return expiration_manager
+
+
+def service_expiration_manager(
+    timeout, default_timeout, maximum_timeout, lock, termination_manager,
+    transmission_manager):
+  """Creates an _interfaces.ExpirationManager appropriate for back-side use.
+
+  Args:
+    timeout: A length of time in seconds to allow for the operation to run. May
+      be None in which case default_timeout will be used.
+    default_timeout: The default length of time in seconds to allow for the
+      operation to run if the front-side customer has not specified such a value
+      (or if the value they specified is not yet known).
+    maximum_timeout: The maximum length of time in seconds to allow for the
+      operation to run.
+    lock: The operation-wide lock.
+    termination_manager: The _interfaces.TerminationManager for the operation.
+    transmission_manager: The _interfaces.TransmissionManager for the
+      operation.
+
+  Returns:
+    An _interfaces.ExpirationManager appropriate for service-side use.
+  """
+  expiration_manager = _ExpirationManager(
+      time.time(), default_timeout if timeout is None else timeout,
+      maximum_timeout, lock, termination_manager, transmission_manager)
+  expiration_manager.start()
+  return expiration_manager
diff --git a/src/python/grpcio/grpc/framework/core/_ingestion.py b/src/python/grpcio/grpc/framework/core/_ingestion.py
new file mode 100644
index 0000000..59f7f8a
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_ingestion.py
@@ -0,0 +1,410 @@
+# 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.
+
+"""State and behavior for ingestion during an operation."""
+
+import abc
+import collections
+
+from grpc.framework.core import _constants
+from grpc.framework.core import _interfaces
+from grpc.framework.foundation import abandonment
+from grpc.framework.foundation import callable_util
+from grpc.framework.interfaces.base import base
+
+_CREATE_SUBSCRIPTION_EXCEPTION_LOG_MESSAGE = 'Exception initializing ingestion!'
+_INGESTION_EXCEPTION_LOG_MESSAGE = 'Exception during ingestion!'
+
+
+class _SubscriptionCreation(collections.namedtuple(
+    '_SubscriptionCreation', ('subscription', 'remote_error', 'abandoned'))):
+  """A sum type for the outcome of ingestion initialization.
+
+  Either subscription will be non-None, remote_error will be True, or abandoned
+  will be True.
+
+  Attributes:
+    subscription: A base.Subscription describing the customer's interest in
+      operation values from the other side.
+    remote_error: A boolean indicating that the subscription could not be
+      created due to an error on the remote side of the operation.
+    abandoned: A boolean indicating that subscription creation was abandoned.
+  """
+
+
+class _SubscriptionCreator(object):
+  """Common specification of subscription-creating behavior."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def create(self, group, method):
+    """Creates the base.Subscription of the local customer.
+
+    Any exceptions raised by this method should be attributed to and treated as
+    defects in the customer code called by this method.
+
+    Args:
+      group: The group identifier of the operation.
+      method: The method identifier of the operation.
+
+    Returns:
+      A _SubscriptionCreation describing the result of subscription creation.
+    """
+    raise NotImplementedError()
+
+
+class _ServiceSubscriptionCreator(_SubscriptionCreator):
+  """A _SubscriptionCreator appropriate for service-side use."""
+
+  def __init__(self, servicer, operation_context, output_operator):
+    """Constructor.
+
+    Args:
+      servicer: The base.Servicer that will service the operation.
+      operation_context: A base.OperationContext for the operation to be passed
+        to the customer.
+      output_operator: A base.Operator for the operation to be passed to the
+        customer and to be called by the customer to accept operation data
+        emitted by the customer.
+    """
+    self._servicer = servicer
+    self._operation_context = operation_context
+    self._output_operator = output_operator
+
+  def create(self, group, method):
+    try:
+      subscription = self._servicer.service(
+          group, method, self._operation_context, self._output_operator)
+    except base.NoSuchMethodError:
+      return _SubscriptionCreation(None, True, False)
+    except abandonment.Abandoned:
+      return _SubscriptionCreation(None, False, True)
+    else:
+      return _SubscriptionCreation(subscription, False, False)
+
+
+def _wrap(behavior):
+  def wrapped(*args, **kwargs):
+    try:
+      behavior(*args, **kwargs)
+    except abandonment.Abandoned:
+      return False
+    else:
+      return True
+  return wrapped
+
+
+class _IngestionManager(_interfaces.IngestionManager):
+  """An implementation of _interfaces.IngestionManager."""
+
+  def __init__(
+      self, lock, pool, subscription, subscription_creator, termination_manager,
+      transmission_manager, expiration_manager):
+    """Constructor.
+
+    Args:
+      lock: The operation-wide lock.
+      pool: A thread pool in which to execute customer code.
+      subscription: A base.Subscription describing the customer's interest in
+        operation values from the other side. May be None if
+        subscription_creator is not None.
+      subscription_creator: A _SubscriptionCreator wrapping the portion of
+        customer code that when called returns the base.Subscription describing
+        the customer's interest in operation values from the other side. May be
+        None if subscription is not None.
+      termination_manager: The _interfaces.TerminationManager for the operation.
+      transmission_manager: The _interfaces.TransmissionManager for the
+        operation.
+      expiration_manager: The _interfaces.ExpirationManager for the operation.
+    """
+    self._lock = lock
+    self._pool = pool
+    self._termination_manager = termination_manager
+    self._transmission_manager = transmission_manager
+    self._expiration_manager = expiration_manager
+
+    if subscription is None:
+      self._subscription_creator = subscription_creator
+      self._wrapped_operator = None
+    elif subscription.kind is base.Subscription.Kind.FULL:
+      self._subscription_creator = None
+      self._wrapped_operator = _wrap(subscription.operator.advance)
+    else:
+      # TODO(nathaniel): Support other subscriptions.
+      raise ValueError('Unsupported subscription "%s"!' % subscription.kind)
+    self._pending_initial_metadata = None
+    self._pending_payloads = []
+    self._pending_completion = None
+    self._local_allowance = 1
+    # A nonnegative integer or None, with None indicating that the local
+    # customer is done emitting anyway so there's no need to bother it by
+    # informing it that the remote customer has granted it further permission to
+    # emit.
+    self._remote_allowance = 0
+    self._processing = False
+
+  def _abort_internal_only(self):
+    self._subscription_creator = None
+    self._wrapped_operator = None
+    self._pending_initial_metadata = None
+    self._pending_payloads = None
+    self._pending_completion = None
+
+  def _abort_and_notify(self, outcome):
+    self._abort_internal_only()
+    self._termination_manager.abort(outcome)
+    self._transmission_manager.abort(outcome)
+    self._expiration_manager.terminate()
+
+  def _operator_next(self):
+    """Computes the next step for full-subscription ingestion.
+
+    Returns:
+      An initial_metadata, payload, completion, allowance, continue quintet
+        indicating what operation values (if any) are available to pass into
+        customer code and whether or not there is anything immediately
+        actionable to call customer code to do.
+    """
+    if self._wrapped_operator is None:
+      return None, None, None, None, False
+    else:
+      initial_metadata, payload, completion, allowance, action = [None] * 5
+      if self._pending_initial_metadata is not None:
+        initial_metadata = self._pending_initial_metadata
+        self._pending_initial_metadata = None
+        action = True
+      if self._pending_payloads and 0 < self._local_allowance:
+        payload = self._pending_payloads.pop(0)
+        self._local_allowance -= 1
+        action = True
+      if not self._pending_payloads and self._pending_completion is not None:
+        completion = self._pending_completion
+        self._pending_completion = None
+        action = True
+      if self._remote_allowance is not None and 0 < self._remote_allowance:
+        allowance = self._remote_allowance
+        self._remote_allowance = 0
+        action = True
+      return initial_metadata, payload, completion, allowance, bool(action)
+
+  def _operator_process(
+      self, wrapped_operator, initial_metadata, payload,
+      completion, allowance):
+    while True:
+      advance_outcome = callable_util.call_logging_exceptions(
+          wrapped_operator, _INGESTION_EXCEPTION_LOG_MESSAGE,
+          initial_metadata=initial_metadata, payload=payload,
+          completion=completion, allowance=allowance)
+      if advance_outcome.exception is None:
+        if advance_outcome.return_value:
+          with self._lock:
+            if self._termination_manager.outcome is not None:
+              return
+            if completion is not None:
+              self._termination_manager.ingestion_complete()
+            initial_metadata, payload, completion, allowance, moar = (
+                self._operator_next())
+            if not moar:
+              self._processing = False
+              return
+        else:
+          with self._lock:
+            if self._termination_manager.outcome is None:
+              self._abort_and_notify(base.Outcome.LOCAL_FAILURE)
+            return
+      else:
+        with self._lock:
+          if self._termination_manager.outcome is None:
+            self._abort_and_notify(base.Outcome.LOCAL_FAILURE)
+          return
+
+  def _operator_post_create(self, subscription):
+    wrapped_operator = _wrap(subscription.operator.advance)
+    with self._lock:
+      if self._termination_manager.outcome is not None:
+        return
+      self._wrapped_operator = wrapped_operator
+      self._subscription_creator = None
+      metadata, payload, completion, allowance, moar = self._operator_next()
+      if not moar:
+        self._processing = False
+        return
+    self._operator_process(
+        wrapped_operator, metadata, payload, completion, allowance)
+
+  def _create(self, subscription_creator, group, name):
+    outcome = callable_util.call_logging_exceptions(
+        subscription_creator.create, _CREATE_SUBSCRIPTION_EXCEPTION_LOG_MESSAGE,
+        group, name)
+    if outcome.return_value is None:
+      with self._lock:
+        if self._termination_manager.outcome is None:
+          self._abort_and_notify(base.Outcome.LOCAL_FAILURE)
+    elif outcome.return_value.abandoned:
+      with self._lock:
+        if self._termination_manager.outcome is None:
+          self._abort_and_notify(base.Outcome.LOCAL_FAILURE)
+    elif outcome.return_value.remote_error:
+      with self._lock:
+        if self._termination_manager.outcome is None:
+          self._abort_and_notify(base.Outcome.REMOTE_FAILURE)
+    elif outcome.return_value.subscription.kind is base.Subscription.Kind.FULL:
+      self._operator_post_create(outcome.return_value.subscription)
+    else:
+      # TODO(nathaniel): Support other subscriptions.
+      raise ValueError(
+          'Unsupported "%s"!' % outcome.return_value.subscription.kind)
+
+  def _store_advance(self, initial_metadata, payload, completion, allowance):
+    if initial_metadata is not None:
+      self._pending_initial_metadata = initial_metadata
+    if payload is not None:
+      self._pending_payloads.append(payload)
+    if completion is not None:
+      self._pending_completion = completion
+    if allowance is not None and self._remote_allowance is not None:
+      self._remote_allowance += allowance
+
+  def _operator_advance(self, initial_metadata, payload, completion, allowance):
+    if self._processing:
+      self._store_advance(initial_metadata, payload, completion, allowance)
+    else:
+      action = False
+      if initial_metadata is not None:
+        action = True
+      if payload is not None:
+        if 0 < self._local_allowance:
+          self._local_allowance -= 1
+          action = True
+        else:
+          self._pending_payloads.append(payload)
+          payload = False
+      if completion is not None:
+        if self._pending_payloads:
+          self._pending_completion = completion
+        else:
+          action = True
+      if allowance is not None and self._remote_allowance is not None:
+        allowance += self._remote_allowance
+        self._remote_allowance = 0
+        action = True
+      if action:
+        self._pool.submit(
+            callable_util.with_exceptions_logged(
+                self._operator_process, _constants.INTERNAL_ERROR_LOG_MESSAGE),
+            self._wrapped_operator, initial_metadata, payload, completion,
+            allowance)
+
+  def set_group_and_method(self, group, method):
+    """See _interfaces.IngestionManager.set_group_and_method for spec."""
+    if self._subscription_creator is not None and not self._processing:
+      self._pool.submit(
+          callable_util.with_exceptions_logged(
+              self._create, _constants.INTERNAL_ERROR_LOG_MESSAGE),
+          self._subscription_creator, group, method)
+      self._processing = True
+
+  def add_local_allowance(self, allowance):
+    """See _interfaces.IngestionManager.add_local_allowance for spec."""
+    if any((self._subscription_creator, self._wrapped_operator,)):
+      self._local_allowance += allowance
+      if not self._processing:
+        initial_metadata, payload, completion, allowance, moar = (
+            self._operator_next())
+        if moar:
+          self._pool.submit(
+              callable_util.with_exceptions_logged(
+                  self._operator_process,
+                  _constants.INTERNAL_ERROR_LOG_MESSAGE),
+              initial_metadata, payload, completion, allowance)
+
+  def local_emissions_done(self):
+    self._remote_allowance = None
+
+  def advance(self, initial_metadata, payload, completion, allowance):
+    """See _interfaces.IngestionManager.advance for specification."""
+    if self._subscription_creator is not None:
+      self._store_advance(initial_metadata, payload, completion, allowance)
+    elif self._wrapped_operator is not None:
+      self._operator_advance(initial_metadata, payload, completion, allowance)
+
+
+def invocation_ingestion_manager(
+    subscription, lock, pool, termination_manager, transmission_manager,
+    expiration_manager):
+  """Creates an IngestionManager appropriate for invocation-side use.
+
+  Args:
+    subscription: A base.Subscription indicating the customer's interest in the
+      data and results from the service-side of the operation.
+    lock: The operation-wide lock.
+    pool: A thread pool in which to execute customer code.
+    termination_manager: The _interfaces.TerminationManager for the operation.
+    transmission_manager: The _interfaces.TransmissionManager for the
+      operation.
+    expiration_manager: The _interfaces.ExpirationManager for the operation.
+
+  Returns:
+    An IngestionManager appropriate for invocation-side use.
+  """
+  return _IngestionManager(
+      lock, pool, subscription, None, termination_manager, transmission_manager,
+      expiration_manager)
+
+
+def service_ingestion_manager(
+    servicer, operation_context, output_operator, lock, pool,
+    termination_manager, transmission_manager, expiration_manager):
+  """Creates an IngestionManager appropriate for service-side use.
+
+  The returned IngestionManager will require its set_group_and_name method to be
+  called before its advance method may be called.
+
+  Args:
+    servicer: A base.Servicer for servicing the operation.
+    operation_context: A base.OperationContext for the operation to be passed to
+      the customer.
+    output_operator: A base.Operator for the operation to be passed to the
+      customer and to be called by the customer to accept operation data output
+      by the customer.
+    lock: The operation-wide lock.
+    pool: A thread pool in which to execute customer code.
+    termination_manager: The _interfaces.TerminationManager for the operation.
+    transmission_manager: The _interfaces.TransmissionManager for the
+      operation.
+    expiration_manager: The _interfaces.ExpirationManager for the operation.
+
+  Returns:
+    An IngestionManager appropriate for service-side use.
+  """
+  subscription_creator = _ServiceSubscriptionCreator(
+      servicer, operation_context, output_operator)
+  return _IngestionManager(
+      lock, pool, None, subscription_creator, termination_manager,
+      transmission_manager, expiration_manager)
diff --git a/src/python/grpcio/grpc/framework/core/_interfaces.py b/src/python/grpcio/grpc/framework/core/_interfaces.py
new file mode 100644
index 0000000..a626b9f
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_interfaces.py
@@ -0,0 +1,308 @@
+# 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.
+
+"""Package-internal interfaces."""
+
+import abc
+
+from grpc.framework.interfaces.base import base
+
+
+class TerminationManager(object):
+  """An object responsible for handling the termination of an operation.
+
+  Attributes:
+    outcome: None if the operation is active or a base.Outcome value if it has
+      terminated.
+  """
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def add_callback(self, callback):
+    """Registers a callback to be called on operation termination.
+
+    If the operation has already terminated the callback will not be called.
+
+    Args:
+      callback: A callable that will be passed an interfaces.Outcome value.
+
+    Returns:
+      None if the operation has not yet terminated and the passed callback will
+        be called when it does, or a base.Outcome value describing the operation
+        termination if the operation has terminated and the callback will not be
+        called as a result of this method call.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def emission_complete(self):
+    """Indicates that emissions from customer code have completed."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def transmission_complete(self):
+    """Indicates that transmissions to the remote end are complete.
+
+    Returns:
+      True if the operation has terminated or False if the operation remains
+        ongoing.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def reception_complete(self):
+    """Indicates that reception from the other side is complete."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def ingestion_complete(self):
+    """Indicates that customer code ingestion of received values is complete."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def expire(self):
+    """Indicates that the operation must abort because it has taken too long."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def abort(self, outcome):
+    """Indicates that the operation must abort for the indicated reason.
+
+    Args:
+      outcome: An interfaces.Outcome indicating operation abortion.
+    """
+    raise NotImplementedError()
+
+
+class TransmissionManager(object):
+  """A manager responsible for transmitting to the other end of an operation."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def kick_off(
+      self, group, method, timeout, initial_metadata, payload, completion,
+      allowance):
+    """Transmits the values associated with operation invocation."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def advance(self, initial_metadata, payload, completion, allowance):
+    """Accepts values for transmission to the other end of the operation.
+
+    Args:
+      initial_metadata: An initial metadata value to be transmitted to the other
+        side of the operation. May only ever be non-None once.
+      payload: A payload value.
+      completion: A base.Completion value. May only ever be non-None in the last
+        transmission to be made to the other side.
+      allowance: A positive integer communicating the number of additional
+        payloads allowed to be transmitted from the other side to this side of
+        the operation, or None if no additional allowance is being granted in
+        this call.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def timeout(self, timeout):
+    """Accepts for transmission to the other side a new timeout value.
+
+    Args:
+      timeout: A positive float used as the new timeout value for the operation
+        to be transmitted to the other side.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def allowance(self, allowance):
+    """Indicates to this manager that the remote customer is allowing payloads.
+
+    Args:
+      allowance: A positive integer indicating the number of additional payloads
+        the remote customer is allowing to be transmitted from this side of the
+        operation.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def remote_complete(self):
+    """Indicates to this manager that data from the remote side is complete."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def abort(self, outcome):
+    """Indicates that the operation has aborted.
+
+    Args:
+      outcome: An interfaces.Outcome for the operation. If None, indicates that
+        the operation abortion should not be communicated to the other side of
+        the operation.
+    """
+    raise NotImplementedError()
+
+
+class ExpirationManager(object):
+  """A manager responsible for aborting the operation if it runs out of time."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def change_timeout(self, timeout):
+    """Changes the timeout allotted for the operation.
+
+    Operation duration is always measure from the beginning of the operation;
+    calling this method changes the operation's allotted time to timeout total
+    seconds, not timeout seconds from the time of this method call.
+
+    Args:
+      timeout: A length of time in seconds to allow for the operation.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def deadline(self):
+    """Returns the time until which the operation is allowed to run.
+
+    Returns:
+      The time (seconds since the epoch) at which the operation will expire.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def terminate(self):
+    """Indicates to this manager that the operation has terminated."""
+    raise NotImplementedError()
+
+
+class EmissionManager(base.Operator):
+  """A manager of values emitted by customer code."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def advance(
+      self, initial_metadata=None, payload=None, completion=None,
+      allowance=None):
+    """Accepts a value emitted by customer code.
+
+    This method should only be called by customer code.
+
+    Args:
+      initial_metadata: An initial metadata value emitted by the local customer
+        to be sent to the other side of the operation.
+      payload: A payload value emitted by the local customer to be sent to the
+        other side of the operation.
+      completion: A Completion value emitted by the local customer to be sent to
+        the other side of the operation.
+      allowance: A positive integer indicating an additional number of payloads
+        that the local customer is willing to accept from the other side of the
+        operation.
+    """
+    raise NotImplementedError()
+
+
+class IngestionManager(object):
+  """A manager responsible for executing customer code.
+
+  This name of this manager comes from its responsibility to pass successive
+  values from the other side of the operation into the code of the local
+  customer.
+  """
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def set_group_and_method(self, group, method):
+    """Communicates to this IngestionManager the operation group and method.
+
+    Args:
+      group: The group identifier of the operation.
+      method: The method identifier of the operation.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_local_allowance(self, allowance):
+    """Communicates to this IngestionManager that more payloads may be ingested.
+
+    Args:
+      allowance: A positive integer indicating an additional number of payloads
+        that the local customer is willing to ingest.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def local_emissions_done(self):
+    """Indicates to this manager that local emissions are done."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def advance(self, initial_metadata, payload, completion, allowance):
+    """Advances the operation by passing values to the local customer."""
+    raise NotImplementedError()
+
+
+class ReceptionManager(object):
+  """A manager responsible for receiving tickets from the other end."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def receive_ticket(self, ticket):
+    """Handle a ticket from the other side of the operation.
+
+    Args:
+      ticket: An interfaces.BackToFrontTicket or interfaces.FrontToBackTicket
+        appropriate to this end of the operation and this object.
+    """
+    raise NotImplementedError()
+
+
+class Operation(object):
+  """An ongoing operation.
+
+  Attributes:
+    context: A base.OperationContext object for the operation.
+    operator: A base.Operator object for the operation for use by the customer
+      of the operation.
+  """
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def handle_ticket(self, ticket):
+    """Handle a ticket from the other side of the operation.
+
+    Args:
+      ticket: A links.Ticket from the other side of the operation.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def abort(self, outcome):
+    """Aborts the operation.
+
+    Args:
+      outcome: A base.Outcome value indicating operation abortion.
+    """
+    raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/core/_operation.py b/src/python/grpcio/grpc/framework/core/_operation.py
new file mode 100644
index 0000000..d20e40a
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_operation.py
@@ -0,0 +1,192 @@
+# 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.
+
+"""Implementation of operations."""
+
+import threading
+
+# _utilities is referenced from specification in this module.
+from grpc.framework.core import _context
+from grpc.framework.core import _emission
+from grpc.framework.core import _expiration
+from grpc.framework.core import _ingestion
+from grpc.framework.core import _interfaces
+from grpc.framework.core import _reception
+from grpc.framework.core import _termination
+from grpc.framework.core import _transmission
+from grpc.framework.core import _utilities  # pylint: disable=unused-import
+
+
+class _EasyOperation(_interfaces.Operation):
+  """A trivial implementation of interfaces.Operation."""
+
+  def __init__(
+      self, lock, termination_manager, transmission_manager, expiration_manager,
+      context, operator, reception_manager):
+    """Constructor.
+
+    Args:
+      lock: The operation-wide lock.
+      termination_manager: The _interfaces.TerminationManager for the operation.
+      transmission_manager: The _interfaces.TransmissionManager for the
+        operation.
+      expiration_manager: The _interfaces.ExpirationManager for the operation.
+      context: A base.OperationContext for use by the customer during the
+        operation.
+      operator: A base.Operator for use by the customer during the operation.
+      reception_manager: The _interfaces.ReceptionManager for the operation.
+    """
+    self._lock = lock
+    self._termination_manager = termination_manager
+    self._transmission_manager = transmission_manager
+    self._expiration_manager = expiration_manager
+    self._reception_manager = reception_manager
+
+    self.context = context
+    self.operator = operator
+
+  def handle_ticket(self, ticket):
+    with self._lock:
+      self._reception_manager.receive_ticket(ticket)
+
+  def abort(self, outcome):
+    with self._lock:
+      if self._termination_manager.outcome is None:
+        self._termination_manager.abort(outcome)
+        self._transmission_manager.abort(outcome)
+        self._expiration_manager.terminate()
+
+
+def invocation_operate(
+    operation_id, group, method, subscription, timeout, initial_metadata,
+    payload, completion, ticket_sink, termination_action, pool):
+  """Constructs objects necessary for front-side operation management.
+
+  Args:
+    operation_id: An object identifying the operation.
+    group: The group identifier of the operation.
+    method: The method identifier of the operation.
+    subscription: A base.Subscription describing the customer's interest in the
+      results of the operation.
+    timeout: A length of time in seconds to allow for the operation.
+    initial_metadata: An initial metadata value to be sent to the other side of
+      the operation. May be None if the initial metadata will be passed later or
+      if there will be no initial metadata passed at all.
+    payload: The first payload value to be transmitted to the other side. May be
+      None if there is no such value or if the customer chose not to pass it at
+      operation invocation.
+    completion: A base.Completion value indicating the end of values passed to
+      the other side of the operation.
+    ticket_sink: A callable that accepts links.Tickets and delivers them to the
+      other side of the operation.
+    termination_action: A callable that accepts the outcome of the operation as
+      a base.Outcome value to be called on operation completion.
+    pool: A thread pool with which to do the work of the operation.
+
+  Returns:
+    An _interfaces.Operation for the operation.
+  """
+  lock = threading.Lock()
+  with lock:
+    termination_manager = _termination.invocation_termination_manager(
+        termination_action, pool)
+    transmission_manager = _transmission.TransmissionManager(
+        operation_id, ticket_sink, lock, pool, termination_manager)
+    expiration_manager = _expiration.invocation_expiration_manager(
+        timeout, lock, termination_manager, transmission_manager)
+    operation_context = _context.OperationContext(
+        lock, termination_manager, transmission_manager, expiration_manager)
+    emission_manager = _emission.EmissionManager(
+        lock, termination_manager, transmission_manager, expiration_manager)
+    ingestion_manager = _ingestion.invocation_ingestion_manager(
+        subscription, lock, pool, termination_manager, transmission_manager,
+        expiration_manager)
+    reception_manager = _reception.ReceptionManager(
+        termination_manager, transmission_manager, expiration_manager,
+        ingestion_manager)
+
+    termination_manager.set_expiration_manager(expiration_manager)
+    transmission_manager.set_expiration_manager(expiration_manager)
+    emission_manager.set_ingestion_manager(ingestion_manager)
+
+    transmission_manager.kick_off(
+        group, method, timeout, initial_metadata, payload, completion, None)
+
+  return _EasyOperation(
+      lock, termination_manager, transmission_manager, expiration_manager,
+      operation_context, emission_manager, reception_manager)
+
+
+def service_operate(
+    servicer_package, ticket, ticket_sink, termination_action, pool):
+  """Constructs an Operation for service of an operation.
+
+  Args:
+    servicer_package: A _utilities.ServicerPackage to be used servicing the
+      operation.
+    ticket: The first links.Ticket received for the operation.
+    ticket_sink: A callable that accepts links.Tickets and delivers them to the
+      other side of the operation.
+    termination_action: A callable that accepts the outcome of the operation as
+      a base.Outcome value to be called on operation completion.
+    pool: A thread pool with which to do the work of the operation.
+
+  Returns:
+    An _interfaces.Operation for the operation.
+  """
+  lock = threading.Lock()
+  with lock:
+    termination_manager = _termination.service_termination_manager(
+        termination_action, pool)
+    transmission_manager = _transmission.TransmissionManager(
+        ticket.operation_id, ticket_sink, lock, pool, termination_manager)
+    expiration_manager = _expiration.service_expiration_manager(
+        ticket.timeout, servicer_package.default_timeout,
+        servicer_package.maximum_timeout, lock, termination_manager,
+        transmission_manager)
+    operation_context = _context.OperationContext(
+        lock, termination_manager, transmission_manager, expiration_manager)
+    emission_manager = _emission.EmissionManager(
+        lock, termination_manager, transmission_manager, expiration_manager)
+    ingestion_manager = _ingestion.service_ingestion_manager(
+        servicer_package.servicer, operation_context, emission_manager, lock,
+        pool, termination_manager, transmission_manager, expiration_manager)
+    reception_manager = _reception.ReceptionManager(
+        termination_manager, transmission_manager, expiration_manager,
+        ingestion_manager)
+
+    termination_manager.set_expiration_manager(expiration_manager)
+    transmission_manager.set_expiration_manager(expiration_manager)
+    emission_manager.set_ingestion_manager(ingestion_manager)
+
+    reception_manager.receive_ticket(ticket)
+
+  return _EasyOperation(
+      lock, termination_manager, transmission_manager, expiration_manager,
+      operation_context, emission_manager, reception_manager)
diff --git a/src/python/grpcio/grpc/framework/core/_reception.py b/src/python/grpcio/grpc/framework/core/_reception.py
new file mode 100644
index 0000000..b64faf8
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_reception.py
@@ -0,0 +1,137 @@
+# 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.
+
+"""State and behavior for ticket reception."""
+
+from grpc.framework.core import _interfaces
+from grpc.framework.interfaces.base import base
+from grpc.framework.interfaces.base import utilities
+from grpc.framework.interfaces.links import links
+
+_REMOTE_TICKET_TERMINATION_TO_LOCAL_OUTCOME = {
+    links.Ticket.Termination.CANCELLATION: base.Outcome.CANCELLED,
+    links.Ticket.Termination.EXPIRATION: base.Outcome.EXPIRED,
+    links.Ticket.Termination.SHUTDOWN: base.Outcome.REMOTE_SHUTDOWN,
+    links.Ticket.Termination.RECEPTION_FAILURE: base.Outcome.RECEPTION_FAILURE,
+    links.Ticket.Termination.TRANSMISSION_FAILURE:
+        base.Outcome.TRANSMISSION_FAILURE,
+    links.Ticket.Termination.LOCAL_FAILURE: base.Outcome.REMOTE_FAILURE,
+}
+
+
+class ReceptionManager(_interfaces.ReceptionManager):
+  """A ReceptionManager based around a _Receiver passed to it."""
+
+  def __init__(
+      self, termination_manager, transmission_manager, expiration_manager,
+      ingestion_manager):
+    """Constructor.
+
+    Args:
+      termination_manager: The operation's _interfaces.TerminationManager.
+      transmission_manager: The operation's _interfaces.TransmissionManager.
+      expiration_manager: The operation's _interfaces.ExpirationManager.
+      ingestion_manager: The operation's _interfaces.IngestionManager.
+    """
+    self._termination_manager = termination_manager
+    self._transmission_manager = transmission_manager
+    self._expiration_manager = expiration_manager
+    self._ingestion_manager = ingestion_manager
+
+    self._lowest_unseen_sequence_number = 0
+    self._out_of_sequence_tickets = {}
+    self._aborted = False
+
+  def _abort(self, outcome):
+    self._aborted = True
+    self._termination_manager.abort(outcome)
+    self._transmission_manager.abort(outcome)
+    self._expiration_manager.terminate()
+
+  def _sequence_failure(self, ticket):
+    """Determines a just-arrived ticket's sequential legitimacy.
+
+    Args:
+      ticket: A just-arrived ticket.
+
+    Returns:
+      True if the ticket is sequentially legitimate; False otherwise.
+    """
+    if ticket.sequence_number < self._lowest_unseen_sequence_number:
+      return True
+    elif ticket.sequence_number in self._out_of_sequence_tickets:
+      return True
+    else:
+      return False
+
+  def _process_one(self, ticket):
+    if ticket.sequence_number == 0:
+      self._ingestion_manager.set_group_and_method(ticket.group, ticket.method)
+    if ticket.timeout is not None:
+      self._expiration_manager.change_timeout(ticket.timeout)
+    if ticket.termination is None:
+      completion = None
+    else:
+      completion = utilities.completion(
+          ticket.terminal_metadata, ticket.code, ticket.message)
+    self._ingestion_manager.advance(
+        ticket.initial_metadata, ticket.payload, completion, ticket.allowance)
+    if ticket.allowance is not None:
+      self._transmission_manager.allowance(ticket.allowance)
+
+  def _process(self, ticket):
+    """Process those tickets ready to be processed.
+
+    Args:
+      ticket: A just-arrived ticket the sequence number of which matches this
+        _ReceptionManager's _lowest_unseen_sequence_number field.
+    """
+    while True:
+      self._process_one(ticket)
+      next_ticket = self._out_of_sequence_tickets.pop(
+          ticket.sequence_number + 1, None)
+      if next_ticket is None:
+        self._lowest_unseen_sequence_number = ticket.sequence_number + 1
+        return
+      else:
+        ticket = next_ticket
+
+  def receive_ticket(self, ticket):
+    """See _interfaces.ReceptionManager.receive_ticket for specification."""
+    if self._aborted:
+      return
+    elif self._sequence_failure(ticket):
+      self._abort(base.Outcome.RECEPTION_FAILURE)
+    elif ticket.termination not in (None, links.Ticket.Termination.COMPLETION):
+      outcome = _REMOTE_TICKET_TERMINATION_TO_LOCAL_OUTCOME[ticket.termination]
+      self._abort(outcome)
+    elif ticket.sequence_number == self._lowest_unseen_sequence_number:
+      self._process(ticket)
+    else:
+      self._out_of_sequence_tickets[ticket.sequence_number] = ticket
diff --git a/src/python/grpcio/grpc/framework/core/_termination.py b/src/python/grpcio/grpc/framework/core/_termination.py
new file mode 100644
index 0000000..ad9f612
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_termination.py
@@ -0,0 +1,212 @@
+# 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.
+
+"""State and behavior for operation termination."""
+
+import abc
+
+from grpc.framework.core import _constants
+from grpc.framework.core import _interfaces
+from grpc.framework.foundation import callable_util
+from grpc.framework.interfaces.base import base
+
+
+def _invocation_completion_predicate(
+    unused_emission_complete, unused_transmission_complete,
+    unused_reception_complete, ingestion_complete):
+  return ingestion_complete
+
+
+def _service_completion_predicate(
+    unused_emission_complete, transmission_complete, unused_reception_complete,
+    unused_ingestion_complete):
+  return transmission_complete
+
+
+class TerminationManager(_interfaces.TerminationManager):
+  """A _interfaces.TransmissionManager on which another manager may be set."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def set_expiration_manager(self, expiration_manager):
+    """Sets the expiration manager with which this manager will interact.
+
+    Args:
+      expiration_manager: The _interfaces.ExpirationManager associated with the
+        current operation.
+    """
+    raise NotImplementedError()
+
+
+class _TerminationManager(TerminationManager):
+  """An implementation of TerminationManager."""
+
+  def __init__(self, predicate, action, pool):
+    """Constructor.
+
+    Args:
+      predicate: One of _invocation_completion_predicate or
+        _service_completion_predicate to be used to determine when the operation
+        has completed.
+      action: A behavior to pass the operation outcome on operation termination.
+      pool: A thread pool.
+    """
+    self._predicate = predicate
+    self._action = action
+    self._pool = pool
+    self._expiration_manager = None
+
+    self.outcome = None
+    self._callbacks = []
+
+    self._emission_complete = False
+    self._transmission_complete = False
+    self._reception_complete = False
+    self._ingestion_complete = False
+
+  def set_expiration_manager(self, expiration_manager):
+    self._expiration_manager = expiration_manager
+
+  def _terminate_internal_only(self, outcome):
+    """Terminates the operation.
+
+    Args:
+      outcome: A base.Outcome describing the outcome of the operation.
+    """
+    self.outcome = outcome
+    callbacks = list(self._callbacks)
+    self._callbacks = None
+
+    act = callable_util.with_exceptions_logged(
+        self._action, _constants.INTERNAL_ERROR_LOG_MESSAGE)
+
+    if outcome is base.Outcome.LOCAL_FAILURE:
+      self._pool.submit(act, outcome)
+    else:
+      def call_callbacks_and_act(callbacks, outcome):
+        for callback in callbacks:
+          callback_outcome = callable_util.call_logging_exceptions(
+              callback, _constants.TERMINATION_CALLBACK_EXCEPTION_LOG_MESSAGE,
+              outcome)
+          if callback_outcome.exception is not None:
+            outcome = base.Outcome.LOCAL_FAILURE
+            break
+        act(outcome)
+
+      self._pool.submit(
+          callable_util.with_exceptions_logged(
+              call_callbacks_and_act, _constants.INTERNAL_ERROR_LOG_MESSAGE),
+          callbacks, outcome)
+
+  def _terminate_and_notify(self, outcome):
+    self._terminate_internal_only(outcome)
+    self._expiration_manager.terminate()
+
+  def _perhaps_complete(self):
+    if self._predicate(
+        self._emission_complete, self._transmission_complete,
+        self._reception_complete, self._ingestion_complete):
+      self._terminate_and_notify(base.Outcome.COMPLETED)
+      return True
+    else:
+      return False
+
+  def is_active(self):
+    """See _interfaces.TerminationManager.is_active for specification."""
+    return self.outcome is None
+
+  def add_callback(self, callback):
+    """See _interfaces.TerminationManager.add_callback for specification."""
+    if self.outcome is None:
+      self._callbacks.append(callback)
+      return None
+    else:
+      return self.outcome
+
+  def emission_complete(self):
+    """See superclass method for specification."""
+    if self.outcome is None:
+      self._emission_complete = True
+      self._perhaps_complete()
+
+  def transmission_complete(self):
+    """See superclass method for specification."""
+    if self.outcome is None:
+      self._transmission_complete = True
+      return self._perhaps_complete()
+    else:
+      return False
+
+  def reception_complete(self):
+    """See superclass method for specification."""
+    if self.outcome is None:
+      self._reception_complete = True
+      self._perhaps_complete()
+
+  def ingestion_complete(self):
+    """See superclass method for specification."""
+    if self.outcome is None:
+      self._ingestion_complete = True
+      self._perhaps_complete()
+
+  def expire(self):
+    """See _interfaces.TerminationManager.expire for specification."""
+    self._terminate_internal_only(base.Outcome.EXPIRED)
+
+  def abort(self, outcome):
+    """See _interfaces.TerminationManager.abort for specification."""
+    self._terminate_and_notify(outcome)
+
+
+def invocation_termination_manager(action, pool):
+  """Creates a TerminationManager appropriate for invocation-side use.
+
+  Args:
+    action: An action to call on operation termination.
+    pool: A thread pool in which to execute the passed action and any
+      termination callbacks that are registered during the operation.
+
+  Returns:
+    A TerminationManager appropriate for invocation-side use.
+  """
+  return _TerminationManager(_invocation_completion_predicate, action, pool)
+
+
+def service_termination_manager(action, pool):
+  """Creates a TerminationManager appropriate for service-side use.
+
+  Args:
+    action: An action to call on operation termination.
+    pool: A thread pool in which to execute the passed action and any
+      termination callbacks that are registered during the operation.
+
+  Returns:
+    A TerminationManager appropriate for service-side use.
+  """
+  return _TerminationManager(_service_completion_predicate, action, pool)
diff --git a/src/python/grpcio/grpc/framework/core/_transmission.py b/src/python/grpcio/grpc/framework/core/_transmission.py
new file mode 100644
index 0000000..01894d3
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_transmission.py
@@ -0,0 +1,294 @@
+# 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.
+
+"""State and behavior for ticket transmission during an operation."""
+
+from grpc.framework.core import _constants
+from grpc.framework.core import _interfaces
+from grpc.framework.foundation import callable_util
+from grpc.framework.interfaces.base import base
+from grpc.framework.interfaces.links import links
+
+_TRANSMISSION_EXCEPTION_LOG_MESSAGE = 'Exception during transmission!'
+
+
+def _explode_completion(completion):
+  if completion is None:
+    return None, None, None, None
+  else:
+    return (
+        completion.terminal_metadata, completion.code, completion.message,
+        links.Ticket.Termination.COMPLETION)
+
+
+class TransmissionManager(_interfaces.TransmissionManager):
+  """An _interfaces.TransmissionManager that sends links.Tickets."""
+
+  def __init__(
+      self, operation_id, ticket_sink, lock, pool, termination_manager):
+    """Constructor.
+
+    Args:
+      operation_id: The operation's ID.
+      ticket_sink: A callable that accepts tickets and sends them to the other
+        side of the operation.
+      lock: The operation-servicing-wide lock object.
+      pool: A thread pool in which the work of transmitting tickets will be
+        performed.
+      termination_manager: The _interfaces.TerminationManager associated with
+        this operation.
+    """
+    self._lock = lock
+    self._pool = pool
+    self._ticket_sink = ticket_sink
+    self._operation_id = operation_id
+    self._termination_manager = termination_manager
+    self._expiration_manager = None
+
+    self._lowest_unused_sequence_number = 0
+    self._remote_allowance = 1
+    self._remote_complete = False
+    self._timeout = None
+    self._local_allowance = 0
+    self._initial_metadata = None
+    self._payloads = []
+    self._completion = None
+    self._aborted = False
+    self._abortion_outcome = None
+    self._transmitting = False
+
+  def set_expiration_manager(self, expiration_manager):
+    """Sets the ExpirationManager with which this manager will cooperate."""
+    self._expiration_manager = expiration_manager
+
+  def _next_ticket(self):
+    """Creates the next ticket to be transmitted.
+
+    Returns:
+      A links.Ticket to be sent to the other side of the operation or None if
+        there is nothing to be sent at this time.
+    """
+    if self._aborted:
+      if self._abortion_outcome is None:
+        return None
+      else:
+        termination = _constants.ABORTION_OUTCOME_TO_TICKET_TERMINATION[
+            self._abortion_outcome]
+        if termination is None:
+          return None
+        else:
+          self._abortion_outcome = None
+          return links.Ticket(
+              self._operation_id, self._lowest_unused_sequence_number, None,
+              None, None, None, None, None, None, None, None, None,
+              termination)
+
+    action = False
+    # TODO(nathaniel): Support other subscriptions.
+    local_subscription = links.Ticket.Subscription.FULL
+    timeout = self._timeout
+    if timeout is not None:
+      self._timeout = None
+      action = True
+    if self._local_allowance <= 0:
+      allowance = None
+    else:
+      allowance = self._local_allowance
+      self._local_allowance = 0
+      action = True
+    initial_metadata = self._initial_metadata
+    if initial_metadata is not None:
+      self._initial_metadata = None
+      action = True
+    if not self._payloads or self._remote_allowance <= 0:
+      payload = None
+    else:
+      payload = self._payloads.pop(0)
+      self._remote_allowance -= 1
+      action = True
+    if self._completion is None or self._payloads:
+      terminal_metadata, code, message, termination = None, None, None, None
+    else:
+      terminal_metadata, code, message, termination = _explode_completion(
+          self._completion)
+      self._completion = None
+      action = True
+
+    if action:
+      ticket = links.Ticket(
+          self._operation_id, self._lowest_unused_sequence_number, None, None,
+          local_subscription, timeout, allowance, initial_metadata, payload,
+          terminal_metadata, code, message, termination)
+      self._lowest_unused_sequence_number += 1
+      return ticket
+    else:
+      return None
+
+  def _transmit(self, ticket):
+    """Commences the transmission loop sending tickets.
+
+    Args:
+      ticket: A links.Ticket to be sent to the other side of the operation.
+    """
+    def transmit(ticket):
+      while True:
+        transmission_outcome = callable_util.call_logging_exceptions(
+            self._ticket_sink, _TRANSMISSION_EXCEPTION_LOG_MESSAGE, ticket)
+        if transmission_outcome.exception is None:
+          with self._lock:
+            if ticket.termination is links.Ticket.Termination.COMPLETION:
+              self._termination_manager.transmission_complete()
+            ticket = self._next_ticket()
+            if ticket is None:
+              self._transmitting = False
+              return
+        else:
+          with self._lock:
+            if self._termination_manager.outcome is None:
+              self._termination_manager.abort(base.Outcome.TRANSMISSION_FAILURE)
+              self._expiration_manager.terminate()
+            return
+
+    self._pool.submit(callable_util.with_exceptions_logged(
+        transmit, _constants.INTERNAL_ERROR_LOG_MESSAGE), ticket)
+    self._transmitting = True
+
+  def kick_off(
+      self, group, method, timeout, initial_metadata, payload, completion,
+      allowance):
+    """See _interfaces.TransmissionManager.kickoff for specification."""
+    # TODO(nathaniel): Support other subscriptions.
+    subscription = links.Ticket.Subscription.FULL
+    terminal_metadata, code, message, termination = _explode_completion(
+        completion)
+    self._remote_allowance = 1 if payload is None else 0
+    ticket = links.Ticket(
+        self._operation_id, 0, group, method, subscription, timeout, allowance,
+        initial_metadata, payload, terminal_metadata, code, message,
+        termination)
+    self._lowest_unused_sequence_number = 1
+    self._transmit(ticket)
+
+  def advance(self, initial_metadata, payload, completion, allowance):
+    """See _interfaces.TransmissionManager.advance for specification."""
+    effective_initial_metadata = initial_metadata
+    effective_payload = payload
+    effective_completion = completion
+    if allowance is not None and not self._remote_complete:
+      effective_allowance = allowance
+    else:
+      effective_allowance = None
+    if self._transmitting:
+      if effective_initial_metadata is not None:
+        self._initial_metadata = effective_initial_metadata
+      if effective_payload is not None:
+        self._payloads.append(effective_payload)
+      if effective_completion is not None:
+        self._completion = effective_completion
+      if effective_allowance is not None:
+        self._local_allowance += effective_allowance
+    else:
+      if effective_payload is not None:
+        if 0 < self._remote_allowance:
+          ticket_payload = effective_payload
+          self._remote_allowance -= 1
+        else:
+          self._payloads.append(effective_payload)
+          ticket_payload = None
+      else:
+        ticket_payload = None
+      if effective_completion is not None and not self._payloads:
+        ticket_completion = effective_completion
+      else:
+        self._completion = effective_completion
+        ticket_completion = None
+      if any(
+          (effective_initial_metadata, ticket_payload, ticket_completion,
+           effective_allowance)):
+        terminal_metadata, code, message, termination = _explode_completion(
+            completion)
+        ticket = links.Ticket(
+            self._operation_id, self._lowest_unused_sequence_number, None, None,
+            None, None, allowance, effective_initial_metadata, ticket_payload,
+            terminal_metadata, code, message, termination)
+        self._lowest_unused_sequence_number += 1
+        self._transmit(ticket)
+
+  def timeout(self, timeout):
+    """See _interfaces.TransmissionManager.timeout for specification."""
+    if self._transmitting:
+      self._timeout = timeout
+    else:
+      ticket = links.Ticket(
+          self._operation_id, self._lowest_unused_sequence_number, None, None,
+          None, timeout, None, None, None, None, None, None, None)
+      self._lowest_unused_sequence_number += 1
+      self._transmit(ticket)
+
+  def allowance(self, allowance):
+    """See _interfaces.TransmissionManager.allowance for specification."""
+    if self._transmitting or not self._payloads:
+      self._remote_allowance += allowance
+    else:
+      self._remote_allowance += allowance - 1
+      payload = self._payloads.pop(0)
+      if self._payloads:
+        completion = None
+      else:
+        completion = self._completion
+        self._completion = None
+      terminal_metadata, code, message, termination = _explode_completion(
+          completion)
+      ticket = links.Ticket(
+          self._operation_id, self._lowest_unused_sequence_number, None, None,
+          None, None, None, None, payload, terminal_metadata, code, message,
+          termination)
+      self._lowest_unused_sequence_number += 1
+      self._transmit(ticket)
+
+  def remote_complete(self):
+    """See _interfaces.TransmissionManager.remote_complete for specification."""
+    self._remote_complete = True
+    self._local_allowance = 0
+
+  def abort(self, outcome):
+    """See _interfaces.TransmissionManager.abort for specification."""
+    if self._transmitting:
+      self._aborted, self._abortion_outcome = True, outcome
+    else:
+      self._aborted = True
+      if outcome is not None:
+        termination = _constants.ABORTION_OUTCOME_TO_TICKET_TERMINATION[
+            outcome]
+        if termination is not None:
+          ticket = links.Ticket(
+              self._operation_id, self._lowest_unused_sequence_number, None,
+              None, None, None, None, None, None, None, None, None,
+              termination)
+          self._transmit(ticket)
diff --git a/src/python/grpcio/grpc/framework/core/_utilities.py b/src/python/grpcio/grpc/framework/core/_utilities.py
new file mode 100644
index 0000000..5b0d798
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/_utilities.py
@@ -0,0 +1,46 @@
+# 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.
+
+"""Package-internal utilities."""
+
+import collections
+
+
+class ServicerPackage(
+    collections.namedtuple(
+        'ServicerPackage', ('servicer', 'default_timeout', 'maximum_timeout'))):
+  """A trivial bundle class.
+
+  Attributes:
+    servicer: A base.Servicer.
+    default_timeout: A float indicating the length of time in seconds to allow
+      for an operation invoked without a timeout.
+    maximum_timeout: A float indicating the maximum length of time in seconds to
+      allow for an operation.
+  """
diff --git a/src/python/grpcio/grpc/framework/core/implementations.py b/src/python/grpcio/grpc/framework/core/implementations.py
new file mode 100644
index 0000000..364a7fa
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/core/implementations.py
@@ -0,0 +1,62 @@
+# 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.
+
+"""Entry points into the ticket-exchange-based base layer implementation."""
+
+# base and links are referenced from specification in this module.
+from grpc.framework.core import _end
+from grpc.framework.interfaces.base import base  # pylint: disable=unused-import
+from grpc.framework.interfaces.links import links  # pylint: disable=unused-import
+
+
+def invocation_end_link():
+  """Creates a base.End-links.Link suitable for operation invocation.
+
+  Returns:
+    An object that is both a base.End and a links.Link, that supports operation
+      invocation, and that translates operation invocation into ticket exchange.
+  """
+  return _end.serviceless_end_link()
+
+
+def service_end_link(servicer, default_timeout, maximum_timeout):
+  """Creates a base.End-links.Link suitable for operation service.
+
+  Args:
+    servicer: A base.Servicer for servicing operations.
+    default_timeout: A length of time in seconds to be used as the default
+      time alloted for a single operation.
+    maximum_timeout: A length of time in seconds to be used as the maximum
+      time alloted for a single operation.
+
+  Returns:
+    An object that is both a base.End and a links.Link and that services
+      operations that arrive at it through ticket exchange.
+  """
+  return _end.serviceful_end_link(servicer, default_timeout, maximum_timeout)
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/base.py b/src/python/grpcio/grpc/framework/interfaces/base/base.py
index 9d1651d..76e0a5b 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/base.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/base.py
@@ -27,10 +27,20 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""The base interface of RPC Framework."""
+"""The base interface of RPC Framework.
 
+Implementations of this interface support the conduct of "operations":
+exchanges between two distinct ends of an arbitrary number of data payloads
+and metadata such as a name for the operation, initial and terminal metadata
+in each direction, and flow control. These operations may be used for transfers
+of data, remote procedure calls, status indication, or anything else
+applications choose.
+"""
+
+# threading is referenced from specification in this module.
 import abc
 import enum
+import threading
 
 # abandonment is referenced from specification in this module.
 from grpc.framework.foundation import abandonment  # pylint: disable=unused-import
@@ -208,19 +218,26 @@
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def stop_gracefully(self):
-    """Gracefully stops this object's service of operations.
+  def stop(self, grace):
+    """Stops this object's service of operations.
 
-    Operations in progress will be allowed to complete, and this method blocks
-    until all of them have.
-    """
-    raise NotImplementedError()
+    This object will refuse service of new operations as soon as this method is
+    called but operations under way at the time of the call may be given a
+    grace period during which they are allowed to finish.
 
-  @abc.abstractmethod
-  def stop_immediately(self):
-    """Immediately stops this object's service of operations.
+    Args:
+      grace: A duration of time in seconds to allow ongoing operations to
+        terminate before being forcefully terminated by the stopping of this
+        End. May be zero to terminate all ongoing operations and immediately
+        stop.
 
-    Operations in progress will not be allowed to complete.
+    Returns:
+      A threading.Event that will be set to indicate all operations having
+        terminated and this End having completely stopped. The returned event
+        may not be set until after the full grace period (if some ongoing
+        operation continues for the full length of the period) or it may be set
+        much sooner (if for example this End had no operations in progress at
+        the time its stop method was called).
     """
     raise NotImplementedError()
 
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/__init__.py b/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
new file mode 100644
index 0000000..7086519
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
@@ -0,0 +1,30 @@
+# 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.
+
+
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py
new file mode 100644
index 0000000..948e750
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py
@@ -0,0 +1,933 @@
+# 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.
+
+"""Interfaces defining the Face layer of RPC Framework."""
+
+import abc
+import collections
+import enum
+
+# cardinality, style, abandonment, future, and stream are
+# referenced from specification in this module.
+from grpc.framework.common import cardinality  # pylint: disable=unused-import
+from grpc.framework.common import style  # pylint: disable=unused-import
+from grpc.framework.foundation import abandonment  # pylint: disable=unused-import
+from grpc.framework.foundation import future  # pylint: disable=unused-import
+from grpc.framework.foundation import stream  # pylint: disable=unused-import
+
+
+class NoSuchMethodError(Exception):
+  """Raised by customer code to indicate an unrecognized method.
+
+  Attributes:
+    group: The group of the unrecognized method.
+    name: The name of the unrecognized method.
+  """
+
+  def __init__(self, group, method):
+    """Constructor.
+
+    Args:
+      group: The group identifier of the unrecognized RPC name.
+      method: The method identifier of the unrecognized RPC name.
+    """
+    super(NoSuchMethodError, self).__init__()
+    self.group = group
+    self.method = method
+
+  def __repr__(self):
+    return 'face.NoSuchMethodError(%s, %s)' % (self.group, self.method,)
+
+
+class Abortion(
+    collections.namedtuple(
+        'Abortion',
+        ('kind', 'initial_metadata', 'terminal_metadata', 'code', 'details',))):
+  """A value describing RPC abortion.
+
+  Attributes:
+    kind: A Kind value identifying how the RPC failed.
+    initial_metadata: The initial metadata from the other side of the RPC or
+      None if no initial metadata value was received.
+    terminal_metadata: The terminal metadata from the other side of the RPC or
+      None if no terminal metadata value was received.
+    code: The code value from the other side of the RPC or None if no code value
+      was received.
+    details: The details value from the other side of the RPC or None if no
+      details value was received.
+  """
+
+  @enum.unique
+  class Kind(enum.Enum):
+    """Types of RPC abortion."""
+
+    CANCELLED = 'cancelled'
+    EXPIRED = 'expired'
+    LOCAL_SHUTDOWN = 'local shutdown'
+    REMOTE_SHUTDOWN = 'remote shutdown'
+    NETWORK_FAILURE = 'network failure'
+    LOCAL_FAILURE = 'local failure'
+    REMOTE_FAILURE = 'remote failure'
+
+
+class AbortionError(Exception):
+  """Common super type for exceptions indicating RPC abortion.
+
+    initial_metadata: The initial metadata from the other side of the RPC or
+      None if no initial metadata value was received.
+    terminal_metadata: The terminal metadata from the other side of the RPC or
+      None if no terminal metadata value was received.
+    code: The code value from the other side of the RPC or None if no code value
+      was received.
+    details: The details value from the other side of the RPC or None if no
+      details value was received.
+  """
+  __metaclass__ = abc.ABCMeta
+
+  def __init__(self, initial_metadata, terminal_metadata, code, details):
+    super(AbortionError, self).__init__()
+    self.initial_metadata = initial_metadata
+    self.terminal_metadata = terminal_metadata
+    self.code = code
+    self.details = details
+
+
+class CancellationError(AbortionError):
+  """Indicates that an RPC has been cancelled."""
+
+
+class ExpirationError(AbortionError):
+  """Indicates that an RPC has expired ("timed out")."""
+
+
+class LocalShutdownError(AbortionError):
+  """Indicates that an RPC has terminated due to local shutdown of RPCs."""
+
+
+class RemoteShutdownError(AbortionError):
+  """Indicates that an RPC has terminated due to remote shutdown of RPCs."""
+
+
+class NetworkError(AbortionError):
+  """Indicates that some error occurred on the network."""
+
+
+class LocalError(AbortionError):
+  """Indicates that an RPC has terminated due to a local defect."""
+
+
+class RemoteError(AbortionError):
+  """Indicates that an RPC has terminated due to a remote defect."""
+
+
+class RpcContext(object):
+  """Provides RPC-related information and action."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def is_active(self):
+    """Describes whether the RPC is active or has terminated."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def time_remaining(self):
+    """Describes the length of allowed time remaining for the RPC.
+
+    Returns:
+      A nonnegative float indicating the length of allowed time in seconds
+      remaining for the RPC to complete before it is considered to have timed
+      out.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_abortion_callback(self, abortion_callback):
+    """Registers a callback to be called if the RPC is aborted.
+
+    Args:
+      abortion_callback: A callable to be called and passed an Abortion value
+        in the event of RPC abortion.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def cancel(self):
+    """Cancels the RPC.
+
+    Idempotent and has no effect if the RPC has already terminated.
+    """
+    raise NotImplementedError()
+
+
+class Call(RpcContext):
+  """Invocation-side utility object for an RPC."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def initial_metadata(self):
+    """Accesses the initial metadata from the service-side of the RPC.
+
+    This method blocks until the value is available or is known not to have been
+    emitted from the service-side of the RPC.
+
+    Returns:
+      The initial metadata object emitted by the service-side of the RPC, or
+        None if there was no such value.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def terminal_metadata(self):
+    """Accesses the terminal metadata from the service-side of the RPC.
+
+    This method blocks until the value is available or is known not to have been
+    emitted from the service-side of the RPC.
+
+    Returns:
+      The terminal metadata object emitted by the service-side of the RPC, or
+        None if there was no such value.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def code(self):
+    """Accesses the code emitted by the service-side of the RPC.
+
+    This method blocks until the value is available or is known not to have been
+    emitted from the service-side of the RPC.
+
+    Returns:
+      The code object emitted by the service-side of the RPC, or None if there
+        was no such value.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def details(self):
+    """Accesses the details value emitted by the service-side of the RPC.
+
+    This method blocks until the value is available or is known not to have been
+    emitted from the service-side of the RPC.
+
+    Returns:
+      The details value emitted by the service-side of the RPC, or None if there
+        was no such value.
+    """
+    raise NotImplementedError()
+
+
+class ServicerContext(RpcContext):
+  """A context object passed to method implementations."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def invocation_metadata(self):
+    """Accesses the metadata from the invocation-side of the RPC.
+
+    This method blocks until the value is available or is known not to have been
+    emitted from the invocation-side of the RPC.
+
+    Returns:
+      The metadata object emitted by the invocation-side of the RPC, or None if
+        there was no such value.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def initial_metadata(self, initial_metadata):
+    """Accepts the service-side initial metadata value of the RPC.
+
+    This method need not be called by method implementations if they have no
+    service-side initial metadata to transmit.
+
+    Args:
+      initial_metadata: The service-side initial metadata value of the RPC to
+        be transmitted to the invocation side of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def terminal_metadata(self, terminal_metadata):
+    """Accepts the service-side terminal metadata value of the RPC.
+
+    This method need not be called by method implementations if they have no
+    service-side terminal metadata to transmit.
+
+    Args:
+      terminal_metadata: The service-side terminal metadata value of the RPC to
+        be transmitted to the invocation side of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def code(self, code):
+    """Accepts the service-side code of the RPC.
+
+    This method need not be called by method implementations if they have no
+    code to transmit.
+
+    Args:
+      code: The code of the RPC to be transmitted to the invocation side of the
+        RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def details(self, details):
+    """Accepts the service-side details of the RPC.
+
+    This method need not be called by method implementations if they have no
+    service-side details to transmit.
+
+    Args:
+      details: The service-side details value of the RPC to be transmitted to
+        the invocation side of the RPC.
+    """
+    raise NotImplementedError()
+
+
+class ResponseReceiver(object):
+  """Invocation-side object used to accept the output of an RPC."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def initial_metadata(self, initial_metadata):
+    """Receives the initial metadata from the service-side of the RPC.
+
+    Args:
+      initial_metadata: The initial metadata object emitted from the
+        service-side of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def response(self, response):
+    """Receives a response from the service-side of the RPC.
+
+    Args:
+      response: A response object emitted from the service-side of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def complete(self, terminal_metadata, code, details):
+    """Receives the completion values emitted from the service-side of the RPC.
+
+    Args:
+      terminal_metadata: The terminal metadata object emitted from the
+        service-side of the RPC.
+      code: The code object emitted from the service-side of the RPC.
+      details: The details object emitted from the service-side of the RPC.
+    """
+    raise NotImplementedError()
+
+
+class UnaryUnaryMultiCallable(object):
+  """Affords invoking a unary-unary RPC in any call style."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(
+      self, request, timeout, metadata=None, with_call=False):
+    """Synchronously invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+      with_call: Whether or not to include return a Call for the RPC in addition
+        to the reponse.
+
+    Returns:
+      The response value for the RPC, and a Call for the RPC if with_call was
+        set to True at invocation.
+
+    Raises:
+      AbortionError: Indicating that the RPC was aborted.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def future(self, request, timeout, metadata=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and a future.Future. In the
+        event of RPC completion, the return Future's result value will be the
+        response value of the RPC. In the event of RPC abortion, the returned
+        Future's exception value will be an AbortionError.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event(
+      self, request, receiver, abortion_callback, timeout,
+      metadata=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      A Call for the RPC.
+    """
+    raise NotImplementedError()
+
+
+class UnaryStreamMultiCallable(object):
+  """Affords invoking a unary-stream RPC in any call style."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(self, request, timeout, metadata=None):
+    """Invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and an iterator of response
+        values. Drawing response values from the returned iterator may raise
+        AbortionError indicating abortion of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event(
+      self, request, receiver, abortion_callback, timeout,
+      metadata=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      A Call object for the RPC.
+    """
+    raise NotImplementedError()
+
+
+class StreamUnaryMultiCallable(object):
+  """Affords invoking a stream-unary RPC in any call style."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(
+      self, request_iterator, timeout, metadata=None,
+      with_call=False):
+    """Synchronously invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+      with_call: Whether or not to include return a Call for the RPC in addition
+        to the reponse.
+
+    Returns:
+      The response value for the RPC, and a Call for the RPC if with_call was
+        set to True at invocation.
+
+    Raises:
+      AbortionError: Indicating that the RPC was aborted.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def future(self, request_iterator, timeout, metadata=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and a future.Future. In the
+        event of RPC completion, the return Future's result value will be the
+        response value of the RPC. In the event of RPC abortion, the returned
+        Future's exception value will be an AbortionError.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event(
+      self, receiver, abortion_callback, timeout, metadata=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      A single object that is both a Call object for the RPC and a
+        stream.Consumer to which the request values of the RPC should be passed.
+    """
+    raise NotImplementedError()
+
+
+class StreamStreamMultiCallable(object):
+  """Affords invoking a stream-stream RPC in any call style."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(self, request_iterator, timeout, metadata=None):
+    """Invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and an iterator of response
+        values. Drawing response values from the returned iterator may raise
+        AbortionError indicating abortion of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event(
+      self, receiver, abortion_callback, timeout, metadata=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of
+        the RPC.
+
+    Returns:
+      A single object that is both a Call object for the RPC and a
+        stream.Consumer to which the request values of the RPC should be passed.
+    """
+    raise NotImplementedError()
+
+
+class MethodImplementation(object):
+  """A sum type that describes a method implementation.
+
+  Attributes:
+    cardinality: A cardinality.Cardinality value.
+    style: A style.Service value.
+    unary_unary_inline: The implementation of the method as a callable value
+      that takes a request value and a ServicerContext object and returns a
+      response value. Only non-None if cardinality is
+      cardinality.Cardinality.UNARY_UNARY and style is style.Service.INLINE.
+    unary_stream_inline: The implementation of the method as a callable value
+      that takes a request value and a ServicerContext object and returns an
+      iterator of response values. Only non-None if cardinality is
+      cardinality.Cardinality.UNARY_STREAM and style is style.Service.INLINE.
+    stream_unary_inline: The implementation of the method as a callable value
+      that takes an iterator of request values and a ServicerContext object and
+      returns a response value. Only non-None if cardinality is
+      cardinality.Cardinality.STREAM_UNARY and style is style.Service.INLINE.
+    stream_stream_inline: The implementation of the method as a callable value
+      that takes an iterator of request values and a ServicerContext object and
+      returns an iterator of response values. Only non-None if cardinality is
+      cardinality.Cardinality.STREAM_STREAM and style is style.Service.INLINE.
+    unary_unary_event: The implementation of the method as a callable value that
+      takes a request value, a response callback to which to pass the response
+      value of the RPC, and a ServicerContext. Only non-None if cardinality is
+      cardinality.Cardinality.UNARY_UNARY and style is style.Service.EVENT.
+    unary_stream_event: The implementation of the method as a callable value
+      that takes a request value, a stream.Consumer to which to pass the
+      response values of the RPC, and a ServicerContext. Only non-None if
+      cardinality is cardinality.Cardinality.UNARY_STREAM and style is
+      style.Service.EVENT.
+    stream_unary_event: The implementation of the method as a callable value
+      that takes a response callback to which to pass the response value of the
+      RPC and a ServicerContext and returns a stream.Consumer to which the
+      request values of the RPC should be passed. Only non-None if cardinality
+      is cardinality.Cardinality.STREAM_UNARY and style is style.Service.EVENT.
+    stream_stream_event: The implementation of the method as a callable value
+      that takes a stream.Consumer to which to pass the response values of the
+      RPC and a ServicerContext and returns a stream.Consumer to which the
+      request values of the RPC should be passed. Only non-None if cardinality
+      is cardinality.Cardinality.STREAM_STREAM and style is
+      style.Service.EVENT.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class MultiMethodImplementation(object):
+  """A general type able to service many methods."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def service(self, group, method, response_consumer, context):
+    """Services an RPC.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      response_consumer: A stream.Consumer to be called to accept the response
+        values of the RPC.
+      context: a ServicerContext object.
+
+    Returns:
+      A stream.Consumer with which to accept the request values of the RPC. The
+        consumer returned from this method may or may not be invoked to
+        completion: in the case of RPC abortion, RPC Framework will simply stop
+        passing values to this object. Implementations must not assume that this
+        object will be called to completion of the request stream or even called
+        at all.
+
+    Raises:
+      abandonment.Abandoned: May or may not be raised when the RPC has been
+        aborted.
+      NoSuchMethodError: If this MultiMethod does not recognize the given group
+        and name for the RPC and is not able to service the RPC.
+    """
+    raise NotImplementedError()
+
+
+class GenericStub(object):
+  """Affords RPC invocation via generic methods."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def blocking_unary_unary(
+      self, group, method, request, timeout, metadata=None,
+      with_call=False):
+    """Invokes a unary-request-unary-response method.
+
+    This method blocks until either returning the response value of the RPC
+    (in the event of RPC completion) or raising an exception (in the event of
+    RPC abortion).
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+      with_call: Whether or not to include return a Call for the RPC in addition
+        to the reponse.
+
+    Returns:
+      The response value for the RPC, and a Call for the RPC if with_call was
+        set to True at invocation.
+
+    Raises:
+      AbortionError: Indicating that the RPC was aborted.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def future_unary_unary(
+      self, group, method, request, timeout, metadata=None):
+    """Invokes a unary-request-unary-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and a future.Future. In the
+        event of RPC completion, the return Future's result value will be the
+        response value of the RPC. In the event of RPC abortion, the returned
+        Future's exception value will be an AbortionError.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def inline_unary_stream(
+      self, group, method, request, timeout, metadata=None):
+    """Invokes a unary-request-stream-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and an iterator of response
+        values. Drawing response values from the returned iterator may raise
+        AbortionError indicating abortion of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def blocking_stream_unary(
+      self, group, method, request_iterator, timeout, metadata=None,
+      with_call=False):
+    """Invokes a stream-request-unary-response method.
+
+    This method blocks until either returning the response value of the RPC
+    (in the event of RPC completion) or raising an exception (in the event of
+    RPC abortion).
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+      with_call: Whether or not to include return a Call for the RPC in addition
+        to the reponse.
+
+    Returns:
+      The response value for the RPC, and a Call for the RPC if with_call was
+        set to True at invocation.
+
+    Raises:
+      AbortionError: Indicating that the RPC was aborted.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def future_stream_unary(
+      self, group, method, request_iterator, timeout, metadata=None):
+    """Invokes a stream-request-unary-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and a future.Future. In the
+        event of RPC completion, the return Future's result value will be the
+        response value of the RPC. In the event of RPC abortion, the returned
+        Future's exception value will be an AbortionError.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def inline_stream_stream(
+      self, group, method, request_iterator, timeout, metadata=None):
+    """Invokes a stream-request-stream-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and an iterator of response
+        values. Drawing response values from the returned iterator may raise
+        AbortionError indicating abortion of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event_unary_unary(
+      self, group, method, request, receiver, abortion_callback, timeout,
+      metadata=None):
+    """Event-driven invocation of a unary-request-unary-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request: The request value for the RPC.
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      A Call for the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event_unary_stream(
+      self, group, method, request, receiver, abortion_callback, timeout,
+      metadata=None):
+    """Event-driven invocation of a unary-request-stream-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      request: The request value for the RPC.
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      A Call for the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event_stream_unary(
+      self, group, method, receiver, abortion_callback, timeout,
+      metadata=None):
+    """Event-driven invocation of a unary-request-unary-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      A pair of a Call object for the RPC and a stream.Consumer to which the
+        request values of the RPC should be passed.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def event_stream_stream(
+      self, group, method, receiver, abortion_callback, timeout,
+      metadata=None):
+    """Event-driven invocation of a unary-request-stream-response method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+      receiver: A ResponseReceiver to be passed the response data of the RPC.
+      abortion_callback: A callback to be called and passed an Abortion value
+        in the event of RPC abortion.
+      timeout: A duration of time in seconds to allow for the RPC.
+      metadata: A metadata value to be passed to the service-side of the RPC.
+
+    Returns:
+      A pair of a Call object for the RPC and a stream.Consumer to which the
+        request values of the RPC should be passed.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def unary_unary(self, group, method):
+    """Creates a UnaryUnaryMultiCallable for a unary-unary method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+
+    Returns:
+      A UnaryUnaryMultiCallable value for the named unary-unary method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def unary_stream(self, group, method):
+    """Creates a UnaryStreamMultiCallable for a unary-stream method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+
+    Returns:
+      A UnaryStreamMultiCallable value for the name unary-stream method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def stream_unary(self, group, method):
+    """Creates a StreamUnaryMultiCallable for a stream-unary method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+
+    Returns:
+      A StreamUnaryMultiCallable value for the named stream-unary method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def stream_stream(self, group, method):
+    """Creates a StreamStreamMultiCallable for a stream-stream method.
+
+    Args:
+      group: The group identifier of the RPC.
+      method: The method identifier of the RPC.
+
+    Returns:
+      A StreamStreamMultiCallable value for the named stream-stream method.
+    """
+    raise NotImplementedError()
+
+
+class DynamicStub(object):
+  """Affords RPC invocation via attributes corresponding to afforded methods.
+
+  Instances of this type may be scoped to a single group so that attribute
+  access is unambiguous.
+
+  Instances of this type respond to attribute access as follows: if the
+  requested attribute is the name of a unary-unary method, the value of the
+  attribute will be a UnaryUnaryMultiCallable with which to invoke an RPC; if
+  the requested attribute is the name of a unary-stream method, the value of the
+  attribute will be a UnaryStreamMultiCallable with which to invoke an RPC; if
+  the requested attribute is the name of a stream-unary method, the value of the
+  attribute will be a StreamUnaryMultiCallable with which to invoke an RPC; and
+  if the requested attribute is the name of a stream-stream method, the value of
+  the attribute will be a StreamStreamMultiCallable with which to invoke an RPC.
+  """
+  __metaclass__ = abc.ABCMeta
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/utilities.py b/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
new file mode 100644
index 0000000..db2ec6e
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
@@ -0,0 +1,178 @@
+# 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.
+
+"""Utilities for RPC Framework's Face interface."""
+
+import collections
+
+# stream is referenced from specification in this module.
+from grpc.framework.common import cardinality
+from grpc.framework.common import style
+from grpc.framework.foundation import stream  # pylint: disable=unused-import
+from grpc.framework.interfaces.face import face
+
+
+class _MethodImplementation(
+    face.MethodImplementation,
+    collections.namedtuple(
+        '_MethodImplementation',
+        ['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline',
+         'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event',
+         'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])):
+  pass
+
+
+def unary_unary_inline(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a unary-unary RPC method as a callable value
+      that takes a request value and an face.ServicerContext object and
+      returns a response value.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior,
+      None, None, None, None, None, None, None)
+
+
+def unary_stream_inline(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a unary-stream RPC method as a callable
+      value that takes a request value and an face.ServicerContext object and
+      returns an iterator of response values.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None,
+      behavior, None, None, None, None, None, None)
+
+
+def stream_unary_inline(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a stream-unary RPC method as a callable
+      value that takes an iterator of request values and an
+      face.ServicerContext object and returns a response value.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None,
+      behavior, None, None, None, None, None)
+
+
+def stream_stream_inline(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a stream-stream RPC method as a callable
+      value that takes an iterator of request values and an
+      face.ServicerContext object and returns an iterator of response values.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None,
+      None, behavior, None, None, None, None)
+
+
+def unary_unary_event(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a unary-unary RPC method as a callable
+      value that takes a request value, a response callback to which to pass
+      the response value of the RPC, and an face.ServicerContext.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None,
+      None, None, behavior, None, None, None)
+
+
+def unary_stream_event(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a unary-stream RPC method as a callable
+      value that takes a request value, a stream.Consumer to which to pass the
+      the response values of the RPC, and an face.ServicerContext.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None,
+      None, None, None, behavior, None, None)
+
+
+def stream_unary_event(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a stream-unary RPC method as a callable
+      value that takes a response callback to which to pass the response value
+      of the RPC and an face.ServicerContext and returns a stream.Consumer to
+      which the request values of the RPC should be passed.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None,
+      None, None, None, None, behavior, None)
+
+
+def stream_stream_event(behavior):
+  """Creates an face.MethodImplementation for the given behavior.
+
+  Args:
+    behavior: The implementation of a stream-stream RPC method as a callable
+      value that takes a stream.Consumer to which to pass the response values
+      of the RPC and an face.ServicerContext and returns a stream.Consumer to
+      which the request values of the RPC should be passed.
+
+  Returns:
+    An face.MethodImplementation derived from the given behavior.
+  """
+  return _MethodImplementation(
+      cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None,
+      None, None, None, None, None, behavior)
diff --git a/src/python/grpcio/grpc/framework/interfaces/links/links.py b/src/python/grpcio/grpc/framework/interfaces/links/links.py
index 5ebbac8..069ff02 100644
--- a/src/python/grpcio/grpc/framework/interfaces/links/links.py
+++ b/src/python/grpcio/grpc/framework/interfaces/links/links.py
@@ -98,7 +98,7 @@
     COMPLETION = 'completion'
     CANCELLATION = 'cancellation'
     EXPIRATION = 'expiration'
-    LOCAL_SHUTDOWN = 'local shutdown'
+    SHUTDOWN = 'shutdown'
     RECEPTION_FAILURE = 'reception failure'
     TRANSMISSION_FAILURE = 'transmission failure'
     LOCAL_FAILURE = 'local failure'
diff --git a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py
new file mode 100644
index 0000000..72b1ae5
--- /dev/null
+++ b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py
@@ -0,0 +1,165 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests the RPC Framework Core's implementation of the Base interface."""
+
+import collections
+import logging
+import random
+import time
+import unittest
+
+from grpc._adapter import _intermediary_low
+from grpc._links import invocation
+from grpc._links import service
+from grpc.framework.core import implementations
+from grpc.framework.interfaces.base import utilities
+from grpc_test import test_common as grpc_test_common
+from grpc_test.framework.common import test_constants
+from grpc_test.framework.interfaces.base import test_cases
+from grpc_test.framework.interfaces.base import test_interfaces
+
+_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'),)
+_CODE = _intermediary_low.Code.OK
+_MESSAGE = b'test message'
+
+
+class _SerializationBehaviors(
+    collections.namedtuple(
+        '_SerializationBehaviors',
+        ('request_serializers', 'request_deserializers', 'response_serializers',
+         'response_deserializers',))):
+  pass
+
+
+class _Links(
+    collections.namedtuple(
+        '_Links',
+        ('invocation_end_link', 'invocation_grpc_link', 'service_grpc_link',
+         'service_end_link'))):
+  pass
+
+
+def _serialization_behaviors_from_serializations(serializations):
+  request_serializers = {}
+  request_deserializers = {}
+  response_serializers = {}
+  response_deserializers = {}
+  for (group, method), serialization in serializations.iteritems():
+    request_serializers[group, method] = serialization.serialize_request
+    request_deserializers[group, method] = serialization.deserialize_request
+    response_serializers[group, method] = serialization.serialize_response
+    response_deserializers[group, method] = serialization.deserialize_response
+  return _SerializationBehaviors(
+      request_serializers, request_deserializers, response_serializers,
+      response_deserializers)
+
+
+class _Implementation(test_interfaces.Implementation):
+
+  def instantiate(self, serializations, servicer):
+    serialization_behaviors = _serialization_behaviors_from_serializations(
+        serializations)
+    invocation_end_link = implementations.invocation_end_link()
+    service_end_link = implementations.service_end_link(
+        servicer, test_constants.DEFAULT_TIMEOUT,
+        test_constants.MAXIMUM_TIMEOUT)
+    service_grpc_link = service.service_link(
+        serialization_behaviors.request_deserializers,
+        serialization_behaviors.response_serializers)
+    port = service_grpc_link.add_port(0, None)
+    channel = _intermediary_low.Channel('localhost:%d' % port, None)
+    invocation_grpc_link = invocation.invocation_link(
+        channel, b'localhost',
+        serialization_behaviors.request_serializers,
+        serialization_behaviors.response_deserializers)
+
+    invocation_end_link.join_link(invocation_grpc_link)
+    invocation_grpc_link.join_link(invocation_end_link)
+    service_end_link.join_link(service_grpc_link)
+    service_grpc_link.join_link(service_end_link)
+    invocation_grpc_link.start()
+    service_grpc_link.start()
+    return invocation_end_link, service_end_link, (
+        invocation_grpc_link, service_grpc_link)
+
+  def destantiate(self, memo):
+    invocation_grpc_link, service_grpc_link = memo
+    invocation_grpc_link.stop()
+    service_grpc_link.stop_gracefully()
+
+  def invocation_initial_metadata(self):
+    return _INVOCATION_INITIAL_METADATA
+
+  def service_initial_metadata(self):
+    return _SERVICE_INITIAL_METADATA
+
+  def invocation_completion(self):
+    return utilities.completion(None, None, None)
+
+  def service_completion(self):
+    return utilities.completion(_SERVICE_TERMINAL_METADATA, _CODE, _MESSAGE)
+
+  def metadata_transmitted(self, original_metadata, transmitted_metadata):
+    return original_metadata is None or grpc_test_common.metadata_transmitted(
+        original_metadata, transmitted_metadata)
+
+  def completion_transmitted(self, original_completion, transmitted_completion):
+    if (original_completion.terminal_metadata is not None and
+        not grpc_test_common.metadata_transmitted(
+            original_completion.terminal_metadata,
+            transmitted_completion.terminal_metadata)):
+        return False
+    elif original_completion.code is not transmitted_completion.code:
+      return False
+    elif original_completion.message != transmitted_completion.message:
+      return False
+    else:
+      return True
+
+
+def setUpModule():
+  logging.warn('setUpModule!')
+
+
+def tearDownModule():
+  logging.warn('tearDownModule!')
+
+
+def load_tests(loader, tests, pattern):
+  return unittest.TestSuite(
+      tests=tuple(
+          loader.loadTestsFromTestCase(test_case_class)
+          for test_case_class in test_cases.test_cases(_Implementation())))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/core/__init__.py b/src/python/grpcio_test/grpc_test/framework/core/__init__.py
new file mode 100644
index 0000000..7086519
--- /dev/null
+++ b/src/python/grpcio_test/grpc_test/framework/core/__init__.py
@@ -0,0 +1,30 @@
+# 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.
+
+
diff --git a/src/python/grpcio_test/grpc_test/framework/core/_base_interface_test.py b/src/python/grpcio_test/grpc_test/framework/core/_base_interface_test.py
new file mode 100644
index 0000000..8d72f13
--- /dev/null
+++ b/src/python/grpcio_test/grpc_test/framework/core/_base_interface_test.py
@@ -0,0 +1,96 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests the RPC Framework Core's implementation of the Base interface."""
+
+import logging
+import random
+import time
+import unittest
+
+from grpc.framework.core import implementations
+from grpc.framework.interfaces.base import utilities
+from grpc_test.framework.common import test_constants
+from grpc_test.framework.interfaces.base import test_cases
+from grpc_test.framework.interfaces.base import test_interfaces
+
+
+class _Implementation(test_interfaces.Implementation):
+
+  def __init__(self):
+    self._invocation_initial_metadata = object()
+    self._service_initial_metadata = object()
+    self._invocation_terminal_metadata = object()
+    self._service_terminal_metadata = object()
+
+  def instantiate(self, serializations, servicer):
+    invocation = implementations.invocation_end_link()
+    service = implementations.service_end_link(
+        servicer, test_constants.DEFAULT_TIMEOUT,
+        test_constants.MAXIMUM_TIMEOUT)
+    invocation.join_link(service)
+    service.join_link(invocation)
+    return invocation, service, None
+
+  def destantiate(self, memo):
+    pass
+
+  def invocation_initial_metadata(self):
+    return self._invocation_initial_metadata
+
+  def service_initial_metadata(self):
+    return self._service_initial_metadata
+
+  def invocation_completion(self):
+    return utilities.completion(self._invocation_terminal_metadata, None, None)
+
+  def service_completion(self):
+    return utilities.completion(self._service_terminal_metadata, None, None)
+
+  def metadata_transmitted(self, original_metadata, transmitted_metadata):
+    return transmitted_metadata is original_metadata
+
+  def completion_transmitted(self, original_completion, transmitted_completion):
+    return (
+        (original_completion.terminal_metadata is
+         transmitted_completion.terminal_metadata) and
+        original_completion.code is transmitted_completion.code and
+        original_completion.message is transmitted_completion.message
+    )
+
+
+def load_tests(loader, tests, pattern):
+  return unittest.TestSuite(
+      tests=tuple(
+          loader.loadTestsFromTestCase(test_case_class)
+          for test_case_class in test_cases.test_cases(_Implementation())))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio_test/grpc_test/framework/interfaces/base/test_cases.py b/src/python/grpcio_test/grpc_test/framework/interfaces/base/test_cases.py
index dd332fe..5c8b176 100644
--- a/src/python/grpcio_test/grpc_test/framework/interfaces/base/test_cases.py
+++ b/src/python/grpcio_test/grpc_test/framework/interfaces/base/test_cases.py
@@ -211,8 +211,10 @@
       elif instruction.kind is _control.Instruction.Kind.CONCLUDE:
         break
 
-    invocation_end.stop_gracefully()
-    service_end.stop_gracefully()
+    invocation_stop_event = invocation_end.stop(0)
+    service_stop_event = service_end.stop(0)
+    invocation_stop_event.wait()
+    service_stop_event.wait()
     invocation_stats = invocation_end.operation_stats()
     service_stats = service_end.operation_stats()
 
diff --git a/src/python/grpcio_test/grpc_test/framework/interfaces/links/test_utilities.py b/src/python/grpcio_test/grpc_test/framework/interfaces/links/test_utilities.py
index 6c2e334..a2bd710 100644
--- a/src/python/grpcio_test/grpc_test/framework/interfaces/links/test_utilities.py
+++ b/src/python/grpcio_test/grpc_test/framework/interfaces/links/test_utilities.py
@@ -29,9 +29,42 @@
 
 """State and behavior appropriate for use in tests."""
 
+import logging
 import threading
+import time
 
 from grpc.framework.interfaces.links import links
+from grpc.framework.interfaces.links import utilities
+
+# A more-or-less arbitrary limit on the length of raw data values to be logged.
+_UNCOMFORTABLY_LONG = 48
+
+
+def _safe_for_log_ticket(ticket):
+  """Creates a safe-for-printing-to-the-log ticket for a given ticket.
+
+  Args:
+    ticket: Any links.Ticket.
+
+  Returns:
+    A links.Ticket that is as much as can be equal to the given ticket but
+      possibly features values like the string "<payload of length 972321>" in
+      place of the actual values of the given ticket.
+  """
+  if isinstance(ticket.payload, (basestring,)):
+    payload_length = len(ticket.payload)
+  else:
+    payload_length = -1
+  if payload_length < _UNCOMFORTABLY_LONG:
+    return ticket
+  else:
+    return links.Ticket(
+        ticket.operation_id, ticket.sequence_number,
+        ticket.group, ticket.method, ticket.subscription, ticket.timeout,
+        ticket.allowance, ticket.initial_metadata,
+        '<payload of length {}>'.format(payload_length),
+        ticket.terminal_metadata, ticket.code, ticket.message,
+        ticket.termination)
 
 
 class RecordingLink(links.Link):
@@ -64,3 +97,71 @@
     """Returns a copy of the list of all tickets received by this Link."""
     with self._condition:
       return tuple(self._tickets)
+
+
+class _Pipe(object):
+  """A conduit that logs all tickets passed through it."""
+
+  def __init__(self, name):
+    self._lock = threading.Lock()
+    self._name = name
+    self._left_mate = utilities.NULL_LINK
+    self._right_mate = utilities.NULL_LINK
+
+  def accept_left_to_right_ticket(self, ticket):
+    with self._lock:
+      logging.warning(
+          '%s: moving left to right through %s: %s', time.time(), self._name,
+          _safe_for_log_ticket(ticket))
+      try:
+        self._right_mate.accept_ticket(ticket)
+      except Exception as e:  # pylint: disable=broad-except
+        logging.exception(e)
+
+  def accept_right_to_left_ticket(self, ticket):
+    with self._lock:
+      logging.warning(
+          '%s: moving right to left through %s: %s', time.time(), self._name,
+          _safe_for_log_ticket(ticket))
+      try:
+        self._left_mate.accept_ticket(ticket)
+      except Exception as e:  # pylint: disable=broad-except
+        logging.exception(e)
+
+  def join_left_mate(self, left_mate):
+    with self._lock:
+      self._left_mate = utilities.NULL_LINK if left_mate is None else left_mate
+
+  def join_right_mate(self, right_mate):
+    with self._lock:
+      self._right_mate = (
+          utilities.NULL_LINK if right_mate is None else right_mate)
+
+
+class _Facade(links.Link):
+
+  def __init__(self, accept, join):
+    self._accept = accept
+    self._join = join
+
+  def accept_ticket(self, ticket):
+    self._accept(ticket)
+
+  def join_link(self, link):
+    self._join(link)
+
+
+def logging_links(name):
+  """Creates a conduit that logs all tickets passed through it.
+
+  Args:
+    name: A name to use for the conduit to identify itself in logging output.
+
+  Returns:
+    Two links.Links, the first of which is the "left" side of the conduit
+      and the second of which is the "right" side of the conduit.
+  """
+  pipe = _Pipe(name)
+  left_facade = _Facade(pipe.accept_left_to_right_ticket, pipe.join_left_mate)
+  right_facade = _Facade(pipe.accept_right_to_left_ticket, pipe.join_right_mate)
+  return left_facade, right_facade
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 36c6818..6b5beb6 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -82,6 +82,10 @@
  * received by the call and subsequently saved on it. */
 static ID id_status;
 
+/* id_write_flag is name of the attribute used to access the write_flag
+ * saved on the call. */
+static ID id_write_flag;
+
 /* sym_* are the symbol for attributes of grpc_rb_sBatchResult. */
 static VALUE sym_send_message;
 static VALUE sym_send_metadata;
@@ -240,6 +244,30 @@
   return rb_ivar_set(self, id_metadata, metadata);
 }
 
+/*
+  call-seq:
+  write_flag = call.write_flag
+
+  Gets the write_flag value saved the call.  */
+static VALUE grpc_rb_call_get_write_flag(VALUE self) {
+  return rb_ivar_get(self, id_write_flag);
+}
+
+/*
+  call-seq:
+  call.write_flag = write_flag
+
+  Saves the write_flag on the call.  */
+static VALUE grpc_rb_call_set_write_flag(VALUE self, VALUE write_flag) {
+  if (!NIL_P(write_flag) && TYPE(write_flag) != T_FIXNUM) {
+    rb_raise(rb_eTypeError, "bad write_flag: got:<%s> want: <Fixnum>",
+             rb_obj_classname(write_flag));
+    return Qnil;
+  }
+
+  return rb_ivar_set(self, id_write_flag, write_flag);
+}
+
 /* grpc_rb_md_ary_fill_hash_cb is the hash iteration callback used
    to fill grpc_metadata_array.
 
@@ -437,17 +465,19 @@
   grpc_status_code recv_status;
   char *recv_status_details;
   size_t recv_status_details_capacity;
+  uint write_flag;
 } run_batch_stack;
 
 /* grpc_run_batch_stack_init ensures the run_batch_stack is properly
  * initialized */
-static void grpc_run_batch_stack_init(run_batch_stack *st) {
+static void grpc_run_batch_stack_init(run_batch_stack *st, uint write_flag) {
   MEMZERO(st, run_batch_stack, 1);
   grpc_metadata_array_init(&st->send_metadata);
   grpc_metadata_array_init(&st->send_trailing_metadata);
   grpc_metadata_array_init(&st->recv_metadata);
   grpc_metadata_array_init(&st->recv_trailing_metadata);
   st->op_num = 0;
+  st->write_flag = write_flag;
 }
 
 /* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly
@@ -477,6 +507,7 @@
   for (i = 0; i < (size_t)RARRAY_LEN(ops_ary); i++) {
     this_op = rb_ary_entry(ops_ary, i);
     this_value = rb_hash_aref(ops_hash, this_op);
+    st->ops[st->op_num].flags = 0;
     switch (NUM2INT(this_op)) {
       case GRPC_OP_SEND_INITIAL_METADATA:
         /* N.B. later there is no need to explicitly delete the metadata keys
@@ -490,6 +521,7 @@
       case GRPC_OP_SEND_MESSAGE:
         st->ops[st->op_num].data.send_message = grpc_rb_s_to_byte_buffer(
             RSTRING_PTR(this_value), RSTRING_LEN(this_value));
+        st->ops[st->op_num].flags = st->write_flag;
         break;
       case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
         break;
@@ -525,7 +557,6 @@
                  NUM2INT(this_op));
     };
     st->ops[st->op_num].op = (grpc_op_type)NUM2INT(this_op);
-    st->ops[st->op_num].flags = 0;
     st->ops[st->op_num].reserved = NULL;
     st->op_num++;
   }
@@ -604,6 +635,8 @@
   grpc_event ev;
   grpc_call_error err;
   VALUE result = Qnil;
+  VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
+  uint write_flag = 0;
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
 
   /* Validate the ops args, adding them to a ruby array */
@@ -611,7 +644,10 @@
     rb_raise(rb_eTypeError, "call#run_batch: ops hash should be a hash");
     return Qnil;
   }
-  grpc_run_batch_stack_init(&st);
+  if (rb_write_flag != Qnil) {
+    write_flag = NUM2UINT(rb_write_flag);
+  }
+  grpc_run_batch_stack_init(&st, write_flag);
   grpc_run_batch_stack_fill_ops(&st, ops_hash);
 
   /* call grpc_call_start_batch, then wait for it to complete using
@@ -638,6 +674,16 @@
   return result;
 }
 
+static void Init_grpc_write_flags() {
+  /* Constants representing the write flags in grpc.h */
+  VALUE grpc_rb_mWriteFlags =
+      rb_define_module_under(grpc_rb_mGrpcCore, "WriteFlags");
+  rb_define_const(grpc_rb_mWriteFlags, "BUFFER_HINT",
+                  UINT2NUM(GRPC_WRITE_BUFFER_HINT));
+  rb_define_const(grpc_rb_mWriteFlags, "NO_COMPRESS",
+                  UINT2NUM(GRPC_WRITE_NO_COMPRESS));
+}
+
 static void Init_grpc_error_codes() {
   /* Constants representing the error codes of grpc_call_error in grpc.h */
   VALUE grpc_rb_mRpcErrors =
@@ -735,10 +781,14 @@
   rb_define_method(grpc_rb_cCall, "status=", grpc_rb_call_set_status, 1);
   rb_define_method(grpc_rb_cCall, "metadata", grpc_rb_call_get_metadata, 0);
   rb_define_method(grpc_rb_cCall, "metadata=", grpc_rb_call_set_metadata, 1);
+  rb_define_method(grpc_rb_cCall, "write_flag", grpc_rb_call_get_write_flag, 0);
+  rb_define_method(grpc_rb_cCall, "write_flag=", grpc_rb_call_set_write_flag,
+                   1);
 
   /* Ids used to support call attributes */
   id_metadata = rb_intern("metadata");
   id_status = rb_intern("status");
+  id_write_flag = rb_intern("write_flag");
 
   /* Ids used by the c wrapping internals. */
   id_cq = rb_intern("__cq");
@@ -766,6 +816,7 @@
 
   Init_grpc_error_codes();
   Init_grpc_op_codes();
+  Init_grpc_write_flags();
 }
 
 /* Gets the call from the ruby object */
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index 17da401..d9cb924 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -59,7 +59,7 @@
     include Core::CallOps
     extend Forwardable
     attr_reader(:deadline)
-    def_delegators :@call, :cancel, :metadata
+    def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=
 
     # client_invoke begins a client invocation.
     #
@@ -484,6 +484,7 @@
     # Operation limits access to an ActiveCall's methods for use as
     # a Operation on the client.
     Operation = view_class(:cancel, :cancelled, :deadline, :execute,
-                           :metadata, :status, :start_call, :wait)
+                           :metadata, :status, :start_call, :wait, :write_flag,
+                           :write_flag=)
   end
 end
diff --git a/src/ruby/spec/call_spec.rb b/src/ruby/spec/call_spec.rb
index 3c5d33f..dd3c45f 100644
--- a/src/ruby/spec/call_spec.rb
+++ b/src/ruby/spec/call_spec.rb
@@ -31,6 +31,14 @@
 
 include GRPC::Core::StatusCodes
 
+describe GRPC::Core::WriteFlags do
+  it 'should define the known write flag values' do
+    m = GRPC::Core::WriteFlags
+    expect(m.const_get(:BUFFER_HINT)).to_not be_nil
+    expect(m.const_get(:NO_COMPRESS)).to_not be_nil
+  end
+end
+
 describe GRPC::Core::RpcErrors do
   before(:each) do
     @known_types = {
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index 26208b7..fcd7bd0 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -35,6 +35,7 @@
   ActiveCall = GRPC::ActiveCall
   Call = GRPC::Core::Call
   CallOps = GRPC::Core::CallOps
+  WriteFlags = GRPC::Core::WriteFlags
 
   before(:each) do
     @pass_through = proc { |x| x }
@@ -129,6 +130,31 @@
                                    @pass_through, deadline)
       expect(server_call.remote_read).to eq('marshalled:' + msg)
     end
+
+    TEST_WRITE_FLAGS = [WriteFlags::BUFFER_HINT, WriteFlags::NO_COMPRESS]
+    TEST_WRITE_FLAGS.each do |f|
+      it "successfully makes calls with write_flag set to #{f}" do
+        call = make_test_call
+        ActiveCall.client_invoke(call, @client_queue)
+        marshal = proc { |x| 'marshalled:' + x }
+        client_call = ActiveCall.new(call, @client_queue, marshal,
+                                     @pass_through, deadline)
+        msg = 'message is a string'
+        client_call.write_flag = f
+        client_call.remote_send(msg)
+
+        # confirm that the message was marshalled
+        recvd_rpc =  @server.request_call(@server_queue, @server_tag, deadline)
+        recvd_call = recvd_rpc.call
+        server_ops = {
+          CallOps::SEND_INITIAL_METADATA => nil
+        }
+        recvd_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
+        server_call = ActiveCall.new(recvd_call, @server_queue, @pass_through,
+                                     @pass_through, deadline)
+        expect(server_call.remote_read).to eq('marshalled:' + msg)
+      end
+    end
   end
 
   describe '#client_invoke' do
@@ -261,7 +287,7 @@
       client_call.writes_done(false)
       server_call = expect_server_to_receive(msg)
       e = client_call.each_remote_read
-      n = 3  # arbitrary value > 1
+      n = 3 # arbitrary value > 1
       n.times do
         server_call.remote_send(reply)
         expect(e.next).to eq(reply)
diff --git a/templates/tools/run_tests/tests.json.template b/templates/tools/run_tests/tests.json.template
index ffbf843..6304673 100644
--- a/templates/tools/run_tests/tests.json.template
+++ b/templates/tools/run_tests/tests.json.template
@@ -6,6 +6,7 @@
                "language": tgt.language,
                "platforms": tgt.platforms,
                "ci_platforms": tgt.ci_platforms,
+	       "exclude_configs": tgt.get("exclude_configs", []),
                "flaky": tgt.flaky}
               for tgt in targets
               if tgt.get('run', True) and tgt.build == 'test'],
diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc
new file mode 100644
index 0000000..fccbb13
--- /dev/null
+++ b/test/cpp/end2end/shutdown_test.cc
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/util/test_config.h"
+
+#include <thread>
+
+#include "test/core/util/port.h"
+#include "test/cpp/util/echo.grpc.pb.h"
+#include "src/core/support/env.h"
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include <gtest/gtest.h>
+#include <grpc/grpc.h>
+#include <grpc/support/sync.h>
+
+using grpc::cpp::test::util::EchoRequest;
+using grpc::cpp::test::util::EchoResponse;
+
+namespace grpc {
+namespace testing {
+
+class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
+ public:
+  explicit TestServiceImpl(gpr_event* ev) : ev_(ev) {}
+
+  Status Echo(ServerContext* context, const EchoRequest* request,
+              EchoResponse* response) GRPC_OVERRIDE {
+    gpr_event_set(ev_, (void*)1);
+    while (!context->IsCancelled()) {
+    }
+    return Status::OK;
+  }
+
+ private:
+  gpr_event* ev_;
+};
+
+class ShutdownTest : public ::testing::Test {
+ public:
+  ShutdownTest() : shutdown_(false), service_(&ev_) { gpr_event_init(&ev_); }
+
+  void SetUp() GRPC_OVERRIDE {
+    port_ = grpc_pick_unused_port_or_die();
+    server_ = SetUpServer(port_);
+  }
+
+  std::unique_ptr<Server> SetUpServer(const int port) {
+    grpc::string server_address = "localhost:" + to_string(port);
+
+    ServerBuilder builder;
+    builder.AddListeningPort(server_address, InsecureServerCredentials());
+    builder.RegisterService(&service_);
+    std::unique_ptr<Server> server = builder.BuildAndStart();
+    return server;
+  }
+
+  void TearDown() GRPC_OVERRIDE { GPR_ASSERT(shutdown_); }
+
+  void ResetStub() {
+    string target = "dns:localhost:" + to_string(port_);
+    channel_ = CreateChannel(target, InsecureCredentials(), ChannelArguments());
+    stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel_));
+  }
+
+  string to_string(const int number) {
+    std::stringstream strs;
+    strs << number;
+    return strs.str();
+  }
+
+  void SendRequest() {
+    EchoRequest request;
+    EchoResponse response;
+    request.set_message("Hello");
+    ClientContext context;
+    GPR_ASSERT(!shutdown_);
+    Status s = stub_->Echo(&context, request, &response);
+    GPR_ASSERT(shutdown_);
+  }
+
+ protected:
+  std::shared_ptr<ChannelInterface> channel_;
+  std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
+  std::unique_ptr<Server> server_;
+  bool shutdown_;
+  int port_;
+  gpr_event ev_;
+  TestServiceImpl service_;
+};
+
+// Tests zookeeper state change between two RPCs
+// TODO(ctiller): leaked objects in this test
+TEST_F(ShutdownTest, ShutdownTest) {
+  ResetStub();
+
+  // send the request in a background thread
+  std::thread thr(std::bind(&ShutdownTest::SendRequest, this));
+
+  // wait for the server to get the event
+  gpr_event_wait(&ev_, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+
+  shutdown_ = true;
+
+  // shutdown should trigger cancellation causing everything to shutdown
+  auto deadline =
+      std::chrono::system_clock::now() + std::chrono::microseconds(100);
+  server_->Shutdown(deadline);
+  EXPECT_GE(std::chrono::system_clock::now(), deadline);
+
+  thr.join();
+}
+
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index b8a222c..da5627d 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -52,7 +52,6 @@
 #include "test/core/security/oauth2_utils.h"
 #include "test/cpp/util/create_test_channel.h"
 
-#include "src/core/surface/call.h"
 #include "src/cpp/client/secure_credentials.h"
 
 DECLARE_bool(enable_ssl);
@@ -141,18 +140,5 @@
   }
 }
 
-InteropClientContextInspector::InteropClientContextInspector(
-    const ::grpc::ClientContext& context)
-    : context_(context) {}
-
-grpc_compression_algorithm
-InteropClientContextInspector::GetCallCompressionAlgorithm() const {
-  return grpc_call_get_compression_algorithm(context_.call_);
-}
-
-gpr_uint32 InteropClientContextInspector::GetMessageFlags() const {
-  return grpc_call_get_message_flags(context_.call_);
-}
-
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h
index 000374a..edc69e9 100644
--- a/test/cpp/interop/client_helper.h
+++ b/test/cpp/interop/client_helper.h
@@ -39,6 +39,8 @@
 #include <grpc++/config.h>
 #include <grpc++/channel_interface.h>
 
+#include "src/core/surface/call.h"
+
 namespace grpc {
 namespace testing {
 
@@ -51,11 +53,17 @@
 
 class InteropClientContextInspector {
  public:
-  InteropClientContextInspector(const ::grpc::ClientContext& context);
+  InteropClientContextInspector(const ::grpc::ClientContext& context)
+    : context_(context) {}
 
   // Inspector methods, able to peek inside ClientContext, follow.
-  grpc_compression_algorithm GetCallCompressionAlgorithm() const;
-  gpr_uint32 GetMessageFlags() const;
+  grpc_compression_algorithm GetCallCompressionAlgorithm() const {
+    return grpc_call_get_compression_algorithm(context_.call_);
+  }
+
+  gpr_uint32 GetMessageFlags() const {
+    return grpc_call_get_message_flags(context_.call_);
+  }
 
  private:
   const ::grpc::ClientContext& context_;
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index 6f80219..6fdca93 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -39,4 +39,12 @@
 export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG
 export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
 source "python"$PYVER"_virtual_environment"/bin/activate
+
+# TODO(atash): These tests don't currently run under py.test and thus don't
+# appear under the coverage report. Find a way to get these tests to work with
+# py.test (or find another tool or *something*) that's acceptable to the rest of
+# the team...
+"python"$PYVER -m grpc_test._core_over_links_base_interface_test
+"python"$PYVER -m grpc_test.framework.core._base_interface_test
+
 "python"$PYVER $GRPCIO_TEST/setup.py test -a "-n8 --cov=grpc --junitxml=./report.xml"
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index eaba699..beb4343 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -123,20 +123,19 @@
   def __init__(self, make_target, test_lang):
     self.make_target = make_target
     self.platform = platform_string()
-    with open('tools/run_tests/tests.json') as f:
-      js = json.load(f)
-      self.binaries = [tgt
-                       for tgt in js
-                       if tgt['language'] == test_lang and
-                          platform_string() in tgt['platforms']]
-      self.ci_binaries = [tgt
-                         for tgt in js
-                         if tgt['language'] == test_lang and
-                            platform_string() in tgt['ci_platforms']]
+    self.test_lang = test_lang
 
   def test_specs(self, config, travis):
     out = []
-    for target in (self.ci_binaries if travis else self.binaries):
+    with open('tools/run_tests/tests.json') as f:
+      js = json.load(f)
+      platforms_str = 'ci_platforms' if travis else 'platforms'
+      binaries = [tgt
+                  for tgt in js
+                  if tgt['language'] == self.test_lang and
+                      config.build_config not in tgt['exclude_configs'] and
+                      platform_string() in tgt[platforms_str]]
+    for target in binaries:
       if travis and target['flaky']:
         continue
       if self.platform == 'windows':
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 72e6c41..50f0785 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1626,6 +1626,23 @@
       "gpr_test_util", 
       "grpc", 
       "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util", 
+      "grpc_zookeeper"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "shutdown_test", 
+    "src": [
+      "test/cpp/end2end/shutdown_test.cc"
+    ]
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
       "grpc_test_util"
     ], 
     "headers": [], 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index c25c0f3..127b1df 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -8,6 +8,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "alarm_heap_test", 
@@ -25,6 +26,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "alarm_list_test", 
@@ -42,6 +44,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "alarm_test", 
@@ -59,6 +62,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "alpn_test", 
@@ -76,6 +80,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "bin_encoder_test", 
@@ -93,6 +98,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_status_conversion_test", 
@@ -110,6 +116,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_stream_encoder_test", 
@@ -127,6 +134,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_stream_map_test", 
@@ -144,6 +152,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "compression_test", 
@@ -160,6 +169,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "dualstack_socket_test", 
@@ -175,6 +185,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "fd_conservation_posix_test", 
@@ -190,6 +201,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "fd_posix_test", 
@@ -205,6 +217,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "fling_stream_test", 
@@ -220,6 +233,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "fling_test", 
@@ -236,6 +250,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_cmdline_test", 
@@ -253,6 +268,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_env_test", 
@@ -270,6 +286,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_file_test", 
@@ -287,6 +304,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_histogram_test", 
@@ -304,6 +322,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_host_port_test", 
@@ -321,6 +340,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_log_test", 
@@ -338,6 +358,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_slice_buffer_test", 
@@ -355,6 +376,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_slice_test", 
@@ -372,6 +394,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_stack_lockfree_test", 
@@ -389,6 +412,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_string_test", 
@@ -406,6 +430,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_sync_test", 
@@ -423,6 +448,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_thd_test", 
@@ -440,6 +466,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_time_test", 
@@ -457,6 +484,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_tls_test", 
@@ -474,6 +502,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "gpr_useful_test", 
@@ -491,6 +520,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_auth_context_test", 
@@ -508,6 +538,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_base64_test", 
@@ -525,6 +556,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_byte_buffer_reader_test", 
@@ -542,6 +574,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_channel_stack_test", 
@@ -559,6 +592,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_completion_queue_test", 
@@ -576,6 +610,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_credentials_test", 
@@ -593,6 +628,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_json_token_test", 
@@ -610,6 +646,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_jwt_verifier_test", 
@@ -627,6 +664,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_security_connector_test", 
@@ -644,6 +682,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "grpc_stream_op_test", 
@@ -661,6 +700,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "hpack_parser_test", 
@@ -678,6 +718,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "hpack_table_test", 
@@ -695,6 +736,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "httpcli_format_request_test", 
@@ -712,6 +754,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "httpcli_parser_test", 
@@ -728,6 +771,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "httpcli_test", 
@@ -744,6 +788,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "json_rewrite_test", 
@@ -761,6 +806,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "json_test", 
@@ -778,6 +824,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "lame_client_test", 
@@ -795,6 +842,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "message_compress_test", 
@@ -812,6 +860,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "multi_init_test", 
@@ -829,6 +878,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "multiple_server_queues_test", 
@@ -846,6 +896,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "murmur_hash_test", 
@@ -863,6 +914,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "no_server_test", 
@@ -880,6 +932,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "resolve_address_test", 
@@ -897,6 +950,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "secure_endpoint_test", 
@@ -914,6 +968,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "sockaddr_utils_test", 
@@ -930,6 +985,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "tcp_client_posix_test", 
@@ -945,6 +1001,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "tcp_posix_test", 
@@ -960,6 +1017,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "tcp_server_posix_test", 
@@ -976,6 +1034,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "time_averaged_stats_test", 
@@ -993,6 +1052,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "timeout_encoding_test", 
@@ -1010,6 +1070,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "timers_test", 
@@ -1027,6 +1088,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "transport_metadata_test", 
@@ -1044,6 +1106,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "transport_security_test", 
@@ -1058,6 +1121,7 @@
     "ci_platforms": [
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "udp_server_test", 
@@ -1072,6 +1136,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "uri_parser_test", 
@@ -1089,6 +1154,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "async_end2end_test", 
@@ -1105,6 +1171,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "async_streaming_ping_pong_test", 
@@ -1120,6 +1187,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "async_unary_ping_pong_test", 
@@ -1136,6 +1204,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "auth_property_iterator_test", 
@@ -1153,6 +1222,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "channel_arguments_test", 
@@ -1170,6 +1240,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "cli_call_test", 
@@ -1186,6 +1257,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "client_crash_test", 
@@ -1202,6 +1274,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "credentials_test", 
@@ -1219,6 +1292,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "cxx_byte_buffer_test", 
@@ -1236,6 +1310,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "cxx_slice_test", 
@@ -1253,6 +1328,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "cxx_time_test", 
@@ -1270,6 +1346,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "dynamic_thread_pool_test", 
@@ -1287,6 +1364,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "end2end_test", 
@@ -1304,6 +1382,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "fixed_size_thread_pool_test", 
@@ -1321,6 +1400,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "generic_end2end_test", 
@@ -1337,6 +1417,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "interop_test", 
@@ -1353,6 +1434,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "mock_test", 
@@ -1369,6 +1451,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "qps_openloop_test", 
@@ -1384,6 +1467,9 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [
+      "tsan"
+    ], 
     "flaky": false, 
     "language": "c++", 
     "name": "qps_test", 
@@ -1400,6 +1486,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "secure_auth_context_test", 
@@ -1416,6 +1503,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "server_crash_test", 
@@ -1432,6 +1520,25 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "shutdown_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "status_test", 
@@ -1448,6 +1555,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "sync_streaming_ping_pong_test", 
@@ -1463,6 +1571,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "sync_unary_ping_pong_test", 
@@ -1479,6 +1588,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "thread_stress_test", 
@@ -1496,6 +1606,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c++", 
     "name": "zookeeper_test", 
@@ -1512,6 +1623,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_bad_hostname_test", 
@@ -1528,6 +1640,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_accept_test", 
@@ -1544,6 +1657,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_accept_and_writes_closed_test", 
@@ -1560,6 +1674,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_invoke_test", 
@@ -1576,6 +1691,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_before_invoke_test", 
@@ -1592,6 +1708,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_in_a_vacuum_test", 
@@ -1608,6 +1725,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_census_simple_request_test", 
@@ -1624,6 +1742,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_channel_connectivity_test", 
@@ -1640,6 +1759,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_default_host_test", 
@@ -1656,6 +1776,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_disappearing_server_test", 
@@ -1672,6 +1793,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test", 
@@ -1688,6 +1810,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_early_server_shutdown_finishes_tags_test", 
@@ -1704,6 +1827,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_empty_batch_test", 
@@ -1720,6 +1844,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_graceful_server_shutdown_test", 
@@ -1736,6 +1861,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_invoke_large_request_test", 
@@ -1752,6 +1878,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_max_concurrent_streams_test", 
@@ -1768,6 +1895,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_max_message_length_test", 
@@ -1784,6 +1912,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_no_op_test", 
@@ -1800,6 +1929,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_ping_pong_streaming_test", 
@@ -1816,6 +1946,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_registered_call_test", 
@@ -1832,6 +1963,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_binary_metadata_and_payload_test", 
@@ -1848,6 +1980,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_metadata_and_payload_test", 
@@ -1864,6 +1997,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_payload_test", 
@@ -1880,6 +2014,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_payload_and_call_creds_test", 
@@ -1896,6 +2031,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test", 
@@ -1912,6 +2048,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_compressed_payload_test", 
@@ -1928,6 +2065,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_flags_test", 
@@ -1944,6 +2082,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_large_metadata_test", 
@@ -1960,6 +2099,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_payload_test", 
@@ -1976,6 +2116,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_server_finishes_request_test", 
@@ -1992,6 +2133,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_delayed_request_test", 
@@ -2008,6 +2150,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_request_test", 
@@ -2024,6 +2167,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_request_with_high_initial_sequence_number_test", 
@@ -2041,6 +2185,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_bad_hostname_test", 
@@ -2058,6 +2203,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_test", 
@@ -2075,6 +2221,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_and_writes_closed_test", 
@@ -2092,6 +2239,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_invoke_test", 
@@ -2109,6 +2257,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_before_invoke_test", 
@@ -2126,6 +2275,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_in_a_vacuum_test", 
@@ -2143,6 +2293,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_census_simple_request_test", 
@@ -2160,6 +2311,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_channel_connectivity_test", 
@@ -2177,6 +2329,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_default_host_test", 
@@ -2194,6 +2347,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_disappearing_server_test", 
@@ -2211,6 +2365,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test", 
@@ -2228,6 +2383,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_tags_test", 
@@ -2245,6 +2401,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_empty_batch_test", 
@@ -2262,6 +2419,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_graceful_server_shutdown_test", 
@@ -2279,6 +2437,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_invoke_large_request_test", 
@@ -2296,6 +2455,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_max_concurrent_streams_test", 
@@ -2313,6 +2473,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_max_message_length_test", 
@@ -2330,6 +2491,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_no_op_test", 
@@ -2347,6 +2509,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_ping_pong_streaming_test", 
@@ -2364,6 +2527,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_registered_call_test", 
@@ -2381,6 +2545,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_binary_metadata_and_payload_test", 
@@ -2398,6 +2563,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_metadata_and_payload_test", 
@@ -2415,6 +2581,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_payload_test", 
@@ -2432,6 +2599,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_payload_and_call_creds_test", 
@@ -2449,6 +2617,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test", 
@@ -2466,6 +2635,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_compressed_payload_test", 
@@ -2483,6 +2653,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_flags_test", 
@@ -2500,6 +2671,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_large_metadata_test", 
@@ -2517,6 +2689,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_payload_test", 
@@ -2534,6 +2707,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_server_finishes_request_test", 
@@ -2551,6 +2725,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_delayed_request_test", 
@@ -2568,6 +2743,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_request_test", 
@@ -2585,6 +2761,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_request_with_high_initial_sequence_number_test", 
@@ -2602,6 +2779,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_bad_hostname_test", 
@@ -2619,6 +2797,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_after_accept_test", 
@@ -2636,6 +2815,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_after_accept_and_writes_closed_test", 
@@ -2653,6 +2833,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_after_invoke_test", 
@@ -2670,6 +2851,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_before_invoke_test", 
@@ -2687,6 +2869,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_in_a_vacuum_test", 
@@ -2704,6 +2887,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_census_simple_request_test", 
@@ -2721,6 +2905,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_channel_connectivity_test", 
@@ -2738,6 +2923,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_default_host_test", 
@@ -2755,6 +2941,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_disappearing_server_test", 
@@ -2772,6 +2959,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_early_server_shutdown_finishes_inflight_calls_test", 
@@ -2789,6 +2977,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_early_server_shutdown_finishes_tags_test", 
@@ -2806,6 +2995,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_empty_batch_test", 
@@ -2823,6 +3013,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_graceful_server_shutdown_test", 
@@ -2840,6 +3031,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_invoke_large_request_test", 
@@ -2857,6 +3049,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_max_concurrent_streams_test", 
@@ -2874,6 +3067,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_max_message_length_test", 
@@ -2891,6 +3085,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_no_op_test", 
@@ -2908,6 +3103,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_ping_pong_streaming_test", 
@@ -2925,6 +3121,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_registered_call_test", 
@@ -2942,6 +3139,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_binary_metadata_and_payload_test", 
@@ -2959,6 +3157,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_metadata_and_payload_test", 
@@ -2976,6 +3175,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_payload_test", 
@@ -2993,6 +3193,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_payload_and_call_creds_test", 
@@ -3010,6 +3211,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_trailing_metadata_and_payload_test", 
@@ -3027,6 +3229,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_compressed_payload_test", 
@@ -3044,6 +3247,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_flags_test", 
@@ -3061,6 +3265,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_large_metadata_test", 
@@ -3078,6 +3283,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_payload_test", 
@@ -3095,6 +3301,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_server_finishes_request_test", 
@@ -3112,6 +3319,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_simple_delayed_request_test", 
@@ -3129,6 +3337,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_simple_request_test", 
@@ -3146,6 +3355,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_simple_request_with_high_initial_sequence_number_test", 
@@ -3162,6 +3372,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_bad_hostname_test", 
@@ -3177,6 +3388,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_after_accept_test", 
@@ -3192,6 +3404,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_test", 
@@ -3207,6 +3420,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_after_invoke_test", 
@@ -3222,6 +3436,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_before_invoke_test", 
@@ -3237,6 +3452,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_in_a_vacuum_test", 
@@ -3252,6 +3468,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_census_simple_request_test", 
@@ -3267,6 +3484,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_channel_connectivity_test", 
@@ -3282,6 +3500,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_disappearing_server_test", 
@@ -3297,6 +3516,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_test", 
@@ -3312,6 +3532,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_test", 
@@ -3327,6 +3548,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_empty_batch_test", 
@@ -3342,6 +3564,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_graceful_server_shutdown_test", 
@@ -3357,6 +3580,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_invoke_large_request_test", 
@@ -3372,6 +3596,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_max_concurrent_streams_test", 
@@ -3387,6 +3612,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_max_message_length_test", 
@@ -3402,6 +3628,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_no_op_test", 
@@ -3417,6 +3644,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_ping_pong_streaming_test", 
@@ -3432,6 +3660,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_registered_call_test", 
@@ -3447,6 +3676,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_test", 
@@ -3462,6 +3692,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_test", 
@@ -3477,6 +3708,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_payload_test", 
@@ -3492,6 +3724,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_payload_and_call_creds_test", 
@@ -3507,6 +3740,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_test", 
@@ -3522,6 +3756,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_compressed_payload_test", 
@@ -3537,6 +3772,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_flags_test", 
@@ -3552,6 +3788,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_large_metadata_test", 
@@ -3567,6 +3804,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_payload_test", 
@@ -3582,6 +3820,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_server_finishes_request_test", 
@@ -3597,6 +3836,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_simple_delayed_request_test", 
@@ -3612,6 +3852,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_simple_request_test", 
@@ -3627,6 +3868,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_test", 
@@ -3640,6 +3882,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_bad_hostname_test", 
@@ -3651,6 +3894,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_test", 
@@ -3662,6 +3906,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_and_writes_closed_test", 
@@ -3673,6 +3918,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_after_invoke_test", 
@@ -3684,6 +3930,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_before_invoke_test", 
@@ -3695,6 +3942,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_in_a_vacuum_test", 
@@ -3706,6 +3954,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_census_simple_request_test", 
@@ -3717,6 +3966,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_channel_connectivity_test", 
@@ -3728,6 +3978,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_disappearing_server_test", 
@@ -3739,6 +3990,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_inflight_calls_test", 
@@ -3750,6 +4002,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_tags_test", 
@@ -3761,6 +4014,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_empty_batch_test", 
@@ -3772,6 +4026,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_graceful_server_shutdown_test", 
@@ -3783,6 +4038,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_invoke_large_request_test", 
@@ -3794,6 +4050,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_max_concurrent_streams_test", 
@@ -3805,6 +4062,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_max_message_length_test", 
@@ -3816,6 +4074,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_no_op_test", 
@@ -3827,6 +4086,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_ping_pong_streaming_test", 
@@ -3838,6 +4098,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_registered_call_test", 
@@ -3849,6 +4110,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_binary_metadata_and_payload_test", 
@@ -3860,6 +4122,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_metadata_and_payload_test", 
@@ -3871,6 +4134,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_payload_test", 
@@ -3882,6 +4146,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_payload_and_call_creds_test", 
@@ -3893,6 +4158,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_trailing_metadata_and_payload_test", 
@@ -3904,6 +4170,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_compressed_payload_test", 
@@ -3915,6 +4182,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_flags_test", 
@@ -3926,6 +4194,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_large_metadata_test", 
@@ -3937,6 +4206,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_payload_test", 
@@ -3948,6 +4218,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_server_finishes_request_test", 
@@ -3959,6 +4230,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_simple_delayed_request_test", 
@@ -3970,6 +4242,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_simple_request_test", 
@@ -3981,6 +4254,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_simple_request_with_high_initial_sequence_number_test", 
@@ -3992,6 +4266,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_bad_hostname_test", 
@@ -4003,6 +4278,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_after_accept_test", 
@@ -4014,6 +4290,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_test", 
@@ -4025,6 +4302,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_after_invoke_test", 
@@ -4036,6 +4314,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_before_invoke_test", 
@@ -4047,6 +4326,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_in_a_vacuum_test", 
@@ -4058,6 +4338,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_census_simple_request_test", 
@@ -4069,6 +4350,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_channel_connectivity_test", 
@@ -4080,6 +4362,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_default_host_test", 
@@ -4091,6 +4374,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_disappearing_server_test", 
@@ -4102,6 +4386,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test", 
@@ -4113,6 +4398,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_test", 
@@ -4124,6 +4410,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_empty_batch_test", 
@@ -4135,6 +4422,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_graceful_server_shutdown_test", 
@@ -4146,6 +4434,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_invoke_large_request_test", 
@@ -4157,6 +4446,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_max_concurrent_streams_test", 
@@ -4168,6 +4458,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_max_message_length_test", 
@@ -4179,6 +4470,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_no_op_test", 
@@ -4190,6 +4482,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_ping_pong_streaming_test", 
@@ -4201,6 +4494,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_registered_call_test", 
@@ -4212,6 +4506,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test", 
@@ -4223,6 +4518,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_test", 
@@ -4234,6 +4530,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_payload_test", 
@@ -4245,6 +4542,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_payload_and_call_creds_test", 
@@ -4256,6 +4554,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test", 
@@ -4267,6 +4566,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_compressed_payload_test", 
@@ -4278,6 +4578,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_flags_test", 
@@ -4289,6 +4590,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_large_metadata_test", 
@@ -4300,6 +4602,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_payload_test", 
@@ -4311,6 +4614,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_server_finishes_request_test", 
@@ -4322,6 +4626,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_simple_delayed_request_test", 
@@ -4333,6 +4638,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_simple_request_test", 
@@ -4344,6 +4650,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_simple_request_with_high_initial_sequence_number_test", 
@@ -4357,6 +4664,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_bad_hostname_test", 
@@ -4373,6 +4681,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_after_accept_test", 
@@ -4389,6 +4698,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_after_accept_and_writes_closed_test", 
@@ -4405,6 +4715,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_after_invoke_test", 
@@ -4421,6 +4732,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_before_invoke_test", 
@@ -4437,6 +4749,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_in_a_vacuum_test", 
@@ -4453,6 +4766,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_census_simple_request_test", 
@@ -4469,6 +4783,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_default_host_test", 
@@ -4485,6 +4800,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_disappearing_server_test", 
@@ -4501,6 +4817,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_early_server_shutdown_finishes_inflight_calls_test", 
@@ -4517,6 +4834,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_early_server_shutdown_finishes_tags_test", 
@@ -4533,6 +4851,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_empty_batch_test", 
@@ -4549,6 +4868,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_graceful_server_shutdown_test", 
@@ -4565,6 +4885,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_invoke_large_request_test", 
@@ -4581,6 +4902,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_max_message_length_test", 
@@ -4597,6 +4919,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_no_op_test", 
@@ -4613,6 +4936,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_ping_pong_streaming_test", 
@@ -4629,6 +4953,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_registered_call_test", 
@@ -4645,6 +4970,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_binary_metadata_and_payload_test", 
@@ -4661,6 +4987,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_metadata_and_payload_test", 
@@ -4677,6 +5004,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_payload_test", 
@@ -4693,6 +5021,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_payload_and_call_creds_test", 
@@ -4709,6 +5038,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_trailing_metadata_and_payload_test", 
@@ -4725,6 +5055,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_with_large_metadata_test", 
@@ -4741,6 +5072,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_with_payload_test", 
@@ -4757,6 +5089,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_server_finishes_request_test", 
@@ -4773,6 +5106,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_simple_delayed_request_test", 
@@ -4789,6 +5123,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_simple_request_test", 
@@ -4805,6 +5140,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_simple_request_with_high_initial_sequence_number_test", 
@@ -4822,6 +5158,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_bad_hostname_test", 
@@ -4839,6 +5176,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_test", 
@@ -4856,6 +5194,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test", 
@@ -4873,6 +5212,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_invoke_test", 
@@ -4890,6 +5230,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_before_invoke_test", 
@@ -4907,6 +5248,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test", 
@@ -4924,6 +5266,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_census_simple_request_test", 
@@ -4941,6 +5284,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_channel_connectivity_test", 
@@ -4958,6 +5302,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_default_host_test", 
@@ -4975,6 +5320,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_disappearing_server_test", 
@@ -4992,6 +5338,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test", 
@@ -5009,6 +5356,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test", 
@@ -5026,6 +5374,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_empty_batch_test", 
@@ -5043,6 +5392,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_graceful_server_shutdown_test", 
@@ -5060,6 +5410,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_invoke_large_request_test", 
@@ -5077,6 +5428,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_max_concurrent_streams_test", 
@@ -5094,6 +5446,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_max_message_length_test", 
@@ -5111,6 +5464,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_no_op_test", 
@@ -5128,6 +5482,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_ping_pong_streaming_test", 
@@ -5145,6 +5500,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_registered_call_test", 
@@ -5162,6 +5518,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test", 
@@ -5179,6 +5536,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test", 
@@ -5196,6 +5554,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_payload_test", 
@@ -5213,6 +5572,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_payload_and_call_creds_test", 
@@ -5230,6 +5590,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test", 
@@ -5247,6 +5608,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_compressed_payload_test", 
@@ -5264,6 +5626,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_flags_test", 
@@ -5281,6 +5644,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_large_metadata_test", 
@@ -5298,6 +5662,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_payload_test", 
@@ -5315,6 +5680,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_server_finishes_request_test", 
@@ -5332,6 +5698,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_delayed_request_test", 
@@ -5349,6 +5716,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_request_test", 
@@ -5366,6 +5734,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_request_with_high_initial_sequence_number_test", 
@@ -5380,6 +5749,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_bad_hostname_test", 
@@ -5391,6 +5761,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_test", 
@@ -5402,6 +5773,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_and_writes_closed_test", 
@@ -5413,6 +5785,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_cancel_after_invoke_test", 
@@ -5424,6 +5797,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_cancel_before_invoke_test", 
@@ -5435,6 +5809,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_cancel_in_a_vacuum_test", 
@@ -5446,6 +5821,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_census_simple_request_test", 
@@ -5457,6 +5833,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_channel_connectivity_test", 
@@ -5468,6 +5845,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_default_host_test", 
@@ -5479,6 +5857,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_disappearing_server_test", 
@@ -5490,6 +5869,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test", 
@@ -5501,6 +5881,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_tags_test", 
@@ -5512,6 +5893,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_empty_batch_test", 
@@ -5523,6 +5905,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_graceful_server_shutdown_test", 
@@ -5534,6 +5917,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_invoke_large_request_test", 
@@ -5545,6 +5929,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_max_concurrent_streams_test", 
@@ -5556,6 +5941,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_max_message_length_test", 
@@ -5567,6 +5953,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_no_op_test", 
@@ -5578,6 +5965,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_ping_pong_streaming_test", 
@@ -5589,6 +5977,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_registered_call_test", 
@@ -5600,6 +5989,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test", 
@@ -5611,6 +6001,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_response_with_metadata_and_payload_test", 
@@ -5622,6 +6013,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_test", 
@@ -5633,6 +6025,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_and_call_creds_test", 
@@ -5644,6 +6037,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test", 
@@ -5655,6 +6049,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_with_compressed_payload_test", 
@@ -5666,6 +6061,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_with_flags_test", 
@@ -5677,6 +6073,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_with_large_metadata_test", 
@@ -5688,6 +6085,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_request_with_payload_test", 
@@ -5699,6 +6097,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_server_finishes_request_test", 
@@ -5710,6 +6109,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_simple_delayed_request_test", 
@@ -5721,6 +6121,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_simple_request_test", 
@@ -5732,6 +6133,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_poll_simple_request_with_high_initial_sequence_number_test", 
@@ -5745,6 +6147,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_bad_hostname_test", 
@@ -5761,6 +6164,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_cancel_after_accept_test", 
@@ -5777,6 +6181,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_cancel_after_accept_and_writes_closed_test", 
@@ -5793,6 +6198,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_cancel_after_invoke_test", 
@@ -5809,6 +6215,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_cancel_before_invoke_test", 
@@ -5825,6 +6232,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_cancel_in_a_vacuum_test", 
@@ -5841,6 +6249,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_census_simple_request_test", 
@@ -5857,6 +6266,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_default_host_test", 
@@ -5873,6 +6283,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_disappearing_server_test", 
@@ -5889,6 +6300,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_early_server_shutdown_finishes_inflight_calls_test", 
@@ -5905,6 +6317,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_early_server_shutdown_finishes_tags_test", 
@@ -5921,6 +6334,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_empty_batch_test", 
@@ -5937,6 +6351,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_graceful_server_shutdown_test", 
@@ -5953,6 +6368,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_invoke_large_request_test", 
@@ -5969,6 +6385,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_max_message_length_test", 
@@ -5985,6 +6402,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_no_op_test", 
@@ -6001,6 +6419,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_ping_pong_streaming_test", 
@@ -6017,6 +6436,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_registered_call_test", 
@@ -6033,6 +6453,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_response_with_binary_metadata_and_payload_test", 
@@ -6049,6 +6470,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_response_with_metadata_and_payload_test", 
@@ -6065,6 +6487,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_response_with_payload_test", 
@@ -6081,6 +6504,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_response_with_payload_and_call_creds_test", 
@@ -6097,6 +6521,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_response_with_trailing_metadata_and_payload_test", 
@@ -6113,6 +6538,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_with_large_metadata_test", 
@@ -6129,6 +6555,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_request_with_payload_test", 
@@ -6145,6 +6572,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_server_finishes_request_test", 
@@ -6161,6 +6589,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_simple_delayed_request_test", 
@@ -6177,6 +6606,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_simple_request_test", 
@@ -6193,6 +6623,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_with_proxy_simple_request_with_high_initial_sequence_number_test", 
@@ -6209,6 +6640,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test", 
@@ -6225,6 +6657,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test", 
@@ -6241,6 +6674,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test", 
@@ -6257,6 +6691,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test", 
@@ -6273,6 +6708,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test", 
@@ -6289,6 +6725,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test", 
@@ -6305,6 +6742,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test", 
@@ -6321,6 +6759,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_channel_connectivity_test", 
@@ -6337,6 +6776,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_default_host_test", 
@@ -6353,6 +6793,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test", 
@@ -6369,6 +6810,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test", 
@@ -6385,6 +6827,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test", 
@@ -6401,6 +6844,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test", 
@@ -6417,6 +6861,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test", 
@@ -6433,6 +6878,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test", 
@@ -6449,6 +6895,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test", 
@@ -6465,6 +6912,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_max_message_length_test", 
@@ -6481,6 +6929,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_no_op_test", 
@@ -6497,6 +6946,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test", 
@@ -6513,6 +6963,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_registered_call_test", 
@@ -6529,6 +6980,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test", 
@@ -6545,6 +6997,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test", 
@@ -6561,6 +7014,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test", 
@@ -6577,6 +7031,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_and_call_creds_test", 
@@ -6593,6 +7048,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test", 
@@ -6609,6 +7065,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_compressed_payload_test", 
@@ -6625,6 +7082,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_flags_test", 
@@ -6641,6 +7099,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test", 
@@ -6657,6 +7116,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test", 
@@ -6673,6 +7133,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_server_finishes_request_test", 
@@ -6689,6 +7150,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test", 
@@ -6705,6 +7167,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test", 
@@ -6721,6 +7184,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_request_with_high_initial_sequence_number_test", 
@@ -6737,6 +7201,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_bad_hostname_test", 
@@ -6753,6 +7218,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_test", 
@@ -6769,6 +7235,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_and_writes_closed_test", 
@@ -6785,6 +7252,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_invoke_test", 
@@ -6801,6 +7269,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_before_invoke_test", 
@@ -6817,6 +7286,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_in_a_vacuum_test", 
@@ -6833,6 +7303,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_census_simple_request_test", 
@@ -6849,6 +7320,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test", 
@@ -6865,6 +7337,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_test", 
@@ -6881,6 +7354,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_empty_batch_test", 
@@ -6897,6 +7371,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_graceful_server_shutdown_test", 
@@ -6913,6 +7388,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_invoke_large_request_test", 
@@ -6929,6 +7405,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_max_concurrent_streams_test", 
@@ -6945,6 +7422,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_max_message_length_test", 
@@ -6961,6 +7439,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_no_op_test", 
@@ -6977,6 +7456,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_ping_pong_streaming_test", 
@@ -6993,6 +7473,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_registered_call_test", 
@@ -7009,6 +7490,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test", 
@@ -7025,6 +7507,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_metadata_and_payload_test", 
@@ -7041,6 +7524,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_payload_test", 
@@ -7057,6 +7541,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_payload_and_call_creds_test", 
@@ -7073,6 +7558,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test", 
@@ -7089,6 +7575,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_compressed_payload_test", 
@@ -7105,6 +7592,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_flags_test", 
@@ -7121,6 +7609,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_large_metadata_test", 
@@ -7137,6 +7626,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_payload_test", 
@@ -7153,6 +7643,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_server_finishes_request_test", 
@@ -7169,6 +7660,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_request_test", 
@@ -7185,6 +7677,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_request_with_high_initial_sequence_number_test", 
@@ -7201,6 +7694,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test", 
@@ -7217,6 +7711,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test", 
@@ -7233,6 +7728,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test", 
@@ -7249,6 +7745,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test", 
@@ -7265,6 +7762,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test", 
@@ -7281,6 +7779,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test", 
@@ -7297,6 +7796,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test", 
@@ -7313,6 +7813,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test", 
@@ -7329,6 +7830,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test", 
@@ -7345,6 +7847,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_empty_batch_test", 
@@ -7361,6 +7864,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test", 
@@ -7377,6 +7881,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test", 
@@ -7393,6 +7898,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test", 
@@ -7409,6 +7915,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_max_message_length_test", 
@@ -7425,6 +7932,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_no_op_test", 
@@ -7441,6 +7949,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test", 
@@ -7457,6 +7966,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_registered_call_test", 
@@ -7473,6 +7983,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test", 
@@ -7489,6 +8000,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test", 
@@ -7505,6 +8017,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test", 
@@ -7521,6 +8034,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_and_call_creds_test", 
@@ -7537,6 +8051,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test", 
@@ -7553,6 +8068,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_compressed_payload_test", 
@@ -7569,6 +8085,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_flags_test", 
@@ -7585,6 +8102,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test", 
@@ -7601,6 +8119,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test", 
@@ -7617,6 +8136,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_test", 
@@ -7633,6 +8153,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_request_test", 
@@ -7649,6 +8170,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_test", 
@@ -7666,6 +8188,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_bad_hostname_test", 
@@ -7683,6 +8206,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test", 
@@ -7700,6 +8224,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test", 
@@ -7717,6 +8242,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test", 
@@ -7734,6 +8260,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test", 
@@ -7751,6 +8278,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test", 
@@ -7768,6 +8296,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_census_simple_request_test", 
@@ -7785,6 +8314,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test", 
@@ -7802,6 +8332,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test", 
@@ -7819,6 +8350,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_empty_batch_test", 
@@ -7836,6 +8368,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test", 
@@ -7853,6 +8386,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_invoke_large_request_test", 
@@ -7870,6 +8404,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test", 
@@ -7887,6 +8422,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_max_message_length_test", 
@@ -7904,6 +8440,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_no_op_test", 
@@ -7921,6 +8458,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test", 
@@ -7938,6 +8476,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_registered_call_test", 
@@ -7955,6 +8494,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test", 
@@ -7972,6 +8512,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test", 
@@ -7989,6 +8530,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test", 
@@ -8006,6 +8548,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test", 
@@ -8023,6 +8566,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test", 
@@ -8040,6 +8584,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_compressed_payload_test", 
@@ -8057,6 +8602,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_flags_test", 
@@ -8074,6 +8620,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test", 
@@ -8091,6 +8638,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_payload_test", 
@@ -8108,6 +8656,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_server_finishes_request_test", 
@@ -8125,6 +8674,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_simple_request_test", 
@@ -8142,6 +8692,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_test", 
@@ -8159,6 +8710,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_bad_hostname_unsecure_test", 
@@ -8176,6 +8728,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_unsecure_test", 
@@ -8193,6 +8746,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -8210,6 +8764,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_invoke_unsecure_test", 
@@ -8227,6 +8782,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_before_invoke_unsecure_test", 
@@ -8244,6 +8800,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_in_a_vacuum_unsecure_test", 
@@ -8261,6 +8818,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_census_simple_request_unsecure_test", 
@@ -8278,6 +8836,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_channel_connectivity_unsecure_test", 
@@ -8295,6 +8854,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_default_host_unsecure_test", 
@@ -8312,6 +8872,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_disappearing_server_unsecure_test", 
@@ -8329,6 +8890,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -8346,6 +8908,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -8363,6 +8926,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_empty_batch_unsecure_test", 
@@ -8380,6 +8944,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_graceful_server_shutdown_unsecure_test", 
@@ -8397,6 +8962,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_invoke_large_request_unsecure_test", 
@@ -8414,6 +8980,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_max_concurrent_streams_unsecure_test", 
@@ -8431,6 +8998,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_max_message_length_unsecure_test", 
@@ -8448,6 +9016,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_no_op_unsecure_test", 
@@ -8465,6 +9034,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_ping_pong_streaming_unsecure_test", 
@@ -8482,6 +9052,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_registered_call_unsecure_test", 
@@ -8499,6 +9070,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -8516,6 +9088,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test", 
@@ -8533,6 +9106,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_payload_unsecure_test", 
@@ -8550,6 +9124,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -8567,6 +9142,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_compressed_payload_unsecure_test", 
@@ -8584,6 +9160,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_flags_unsecure_test", 
@@ -8601,6 +9178,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_large_metadata_unsecure_test", 
@@ -8618,6 +9196,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_payload_unsecure_test", 
@@ -8635,6 +9214,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_server_finishes_request_unsecure_test", 
@@ -8652,6 +9232,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_delayed_request_unsecure_test", 
@@ -8669,6 +9250,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_request_unsecure_test", 
@@ -8686,6 +9268,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -8703,6 +9286,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_bad_hostname_unsecure_test", 
@@ -8720,6 +9304,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_after_accept_unsecure_test", 
@@ -8737,6 +9322,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -8754,6 +9340,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_after_invoke_unsecure_test", 
@@ -8771,6 +9358,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_before_invoke_unsecure_test", 
@@ -8788,6 +9376,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_cancel_in_a_vacuum_unsecure_test", 
@@ -8805,6 +9394,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_census_simple_request_unsecure_test", 
@@ -8822,6 +9412,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_channel_connectivity_unsecure_test", 
@@ -8839,6 +9430,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_default_host_unsecure_test", 
@@ -8856,6 +9448,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_disappearing_server_unsecure_test", 
@@ -8873,6 +9466,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -8890,6 +9484,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -8907,6 +9502,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_empty_batch_unsecure_test", 
@@ -8924,6 +9520,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_graceful_server_shutdown_unsecure_test", 
@@ -8941,6 +9538,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_invoke_large_request_unsecure_test", 
@@ -8958,6 +9556,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_max_concurrent_streams_unsecure_test", 
@@ -8975,6 +9574,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_max_message_length_unsecure_test", 
@@ -8992,6 +9592,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_no_op_unsecure_test", 
@@ -9009,6 +9610,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_ping_pong_streaming_unsecure_test", 
@@ -9026,6 +9628,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_registered_call_unsecure_test", 
@@ -9043,6 +9646,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -9060,6 +9664,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_metadata_and_payload_unsecure_test", 
@@ -9077,6 +9682,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_payload_unsecure_test", 
@@ -9094,6 +9700,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -9111,6 +9718,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_compressed_payload_unsecure_test", 
@@ -9128,6 +9736,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_flags_unsecure_test", 
@@ -9145,6 +9754,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_large_metadata_unsecure_test", 
@@ -9162,6 +9772,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_request_with_payload_unsecure_test", 
@@ -9179,6 +9790,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_server_finishes_request_unsecure_test", 
@@ -9196,6 +9808,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_simple_delayed_request_unsecure_test", 
@@ -9213,6 +9826,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_simple_request_unsecure_test", 
@@ -9230,6 +9844,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_compression_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -9246,6 +9861,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_bad_hostname_unsecure_test", 
@@ -9261,6 +9877,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_after_accept_unsecure_test", 
@@ -9276,6 +9893,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -9291,6 +9909,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_after_invoke_unsecure_test", 
@@ -9306,6 +9925,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_before_invoke_unsecure_test", 
@@ -9321,6 +9941,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_cancel_in_a_vacuum_unsecure_test", 
@@ -9336,6 +9957,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_census_simple_request_unsecure_test", 
@@ -9351,6 +9973,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_channel_connectivity_unsecure_test", 
@@ -9366,6 +9989,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_disappearing_server_unsecure_test", 
@@ -9381,6 +10005,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -9396,6 +10021,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -9411,6 +10037,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_empty_batch_unsecure_test", 
@@ -9426,6 +10053,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_graceful_server_shutdown_unsecure_test", 
@@ -9441,6 +10069,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_invoke_large_request_unsecure_test", 
@@ -9456,6 +10085,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_max_concurrent_streams_unsecure_test", 
@@ -9471,6 +10101,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_max_message_length_unsecure_test", 
@@ -9486,6 +10117,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_no_op_unsecure_test", 
@@ -9501,6 +10133,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_ping_pong_streaming_unsecure_test", 
@@ -9516,6 +10149,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_registered_call_unsecure_test", 
@@ -9531,6 +10165,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -9546,6 +10181,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_unsecure_test", 
@@ -9561,6 +10197,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_payload_unsecure_test", 
@@ -9576,6 +10213,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -9591,6 +10229,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_compressed_payload_unsecure_test", 
@@ -9606,6 +10245,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_flags_unsecure_test", 
@@ -9621,6 +10261,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_large_metadata_unsecure_test", 
@@ -9636,6 +10277,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_request_with_payload_unsecure_test", 
@@ -9651,6 +10293,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_server_finishes_request_unsecure_test", 
@@ -9666,6 +10309,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_simple_delayed_request_unsecure_test", 
@@ -9681,6 +10325,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_simple_request_unsecure_test", 
@@ -9696,6 +10341,7 @@
       "mac", 
       "posix"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -9709,6 +10355,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_bad_hostname_unsecure_test", 
@@ -9720,6 +10367,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_unsecure_test", 
@@ -9731,6 +10379,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -9742,6 +10391,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_after_invoke_unsecure_test", 
@@ -9753,6 +10403,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_before_invoke_unsecure_test", 
@@ -9764,6 +10415,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_cancel_in_a_vacuum_unsecure_test", 
@@ -9775,6 +10427,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_census_simple_request_unsecure_test", 
@@ -9786,6 +10439,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_channel_connectivity_unsecure_test", 
@@ -9797,6 +10451,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_disappearing_server_unsecure_test", 
@@ -9808,6 +10463,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -9819,6 +10475,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -9830,6 +10487,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_empty_batch_unsecure_test", 
@@ -9841,6 +10499,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_graceful_server_shutdown_unsecure_test", 
@@ -9852,6 +10511,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_invoke_large_request_unsecure_test", 
@@ -9863,6 +10523,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_max_concurrent_streams_unsecure_test", 
@@ -9874,6 +10535,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_max_message_length_unsecure_test", 
@@ -9885,6 +10547,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_no_op_unsecure_test", 
@@ -9896,6 +10559,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_ping_pong_streaming_unsecure_test", 
@@ -9907,6 +10571,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_registered_call_unsecure_test", 
@@ -9918,6 +10583,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -9929,6 +10595,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_metadata_and_payload_unsecure_test", 
@@ -9940,6 +10607,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_payload_unsecure_test", 
@@ -9951,6 +10619,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -9962,6 +10631,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_compressed_payload_unsecure_test", 
@@ -9973,6 +10643,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_flags_unsecure_test", 
@@ -9984,6 +10655,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_large_metadata_unsecure_test", 
@@ -9995,6 +10667,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_request_with_payload_unsecure_test", 
@@ -10006,6 +10679,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_server_finishes_request_unsecure_test", 
@@ -10017,6 +10691,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_simple_delayed_request_unsecure_test", 
@@ -10028,6 +10703,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_simple_request_unsecure_test", 
@@ -10039,6 +10715,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_posix_with_poll_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -10050,6 +10727,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_bad_hostname_unsecure_test", 
@@ -10061,6 +10739,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_after_accept_unsecure_test", 
@@ -10072,6 +10751,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -10083,6 +10763,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_after_invoke_unsecure_test", 
@@ -10094,6 +10775,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_before_invoke_unsecure_test", 
@@ -10105,6 +10787,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_cancel_in_a_vacuum_unsecure_test", 
@@ -10116,6 +10799,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_census_simple_request_unsecure_test", 
@@ -10127,6 +10811,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_channel_connectivity_unsecure_test", 
@@ -10138,6 +10823,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_default_host_unsecure_test", 
@@ -10149,6 +10835,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_disappearing_server_unsecure_test", 
@@ -10160,6 +10847,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -10171,6 +10859,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -10182,6 +10871,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_empty_batch_unsecure_test", 
@@ -10193,6 +10883,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_graceful_server_shutdown_unsecure_test", 
@@ -10204,6 +10895,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_invoke_large_request_unsecure_test", 
@@ -10215,6 +10907,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_max_concurrent_streams_unsecure_test", 
@@ -10226,6 +10919,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_max_message_length_unsecure_test", 
@@ -10237,6 +10931,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_no_op_unsecure_test", 
@@ -10248,6 +10943,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_ping_pong_streaming_unsecure_test", 
@@ -10259,6 +10955,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_registered_call_unsecure_test", 
@@ -10270,6 +10967,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -10281,6 +10979,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_unsecure_test", 
@@ -10292,6 +10991,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_payload_unsecure_test", 
@@ -10303,6 +11003,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -10314,6 +11015,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_compressed_payload_unsecure_test", 
@@ -10325,6 +11027,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_flags_unsecure_test", 
@@ -10336,6 +11039,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_large_metadata_unsecure_test", 
@@ -10347,6 +11051,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_request_with_payload_unsecure_test", 
@@ -10358,6 +11063,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_server_finishes_request_unsecure_test", 
@@ -10369,6 +11075,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_simple_delayed_request_unsecure_test", 
@@ -10380,6 +11087,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_simple_request_unsecure_test", 
@@ -10391,6 +11099,7 @@
     "ci_platforms": [
       "linux"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_poll_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -10404,6 +11113,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_bad_hostname_unsecure_test", 
@@ -10420,6 +11130,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_after_accept_unsecure_test", 
@@ -10436,6 +11147,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -10452,6 +11164,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_after_invoke_unsecure_test", 
@@ -10468,6 +11181,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_before_invoke_unsecure_test", 
@@ -10484,6 +11198,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_cancel_in_a_vacuum_unsecure_test", 
@@ -10500,6 +11215,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_census_simple_request_unsecure_test", 
@@ -10516,6 +11232,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_default_host_unsecure_test", 
@@ -10532,6 +11249,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_disappearing_server_unsecure_test", 
@@ -10548,6 +11266,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -10564,6 +11283,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -10580,6 +11300,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_empty_batch_unsecure_test", 
@@ -10596,6 +11317,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_graceful_server_shutdown_unsecure_test", 
@@ -10612,6 +11334,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_invoke_large_request_unsecure_test", 
@@ -10628,6 +11351,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_max_message_length_unsecure_test", 
@@ -10644,6 +11368,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_no_op_unsecure_test", 
@@ -10660,6 +11385,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_ping_pong_streaming_unsecure_test", 
@@ -10676,6 +11402,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_registered_call_unsecure_test", 
@@ -10692,6 +11419,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -10708,6 +11436,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_metadata_and_payload_unsecure_test", 
@@ -10724,6 +11453,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_payload_unsecure_test", 
@@ -10740,6 +11470,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -10756,6 +11487,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_with_large_metadata_unsecure_test", 
@@ -10772,6 +11504,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_request_with_payload_unsecure_test", 
@@ -10788,6 +11521,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_server_finishes_request_unsecure_test", 
@@ -10804,6 +11538,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_simple_delayed_request_unsecure_test", 
@@ -10820,6 +11555,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_simple_request_unsecure_test", 
@@ -10836,6 +11572,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_with_proxy_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -10852,6 +11589,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_bad_hostname_unsecure_test", 
@@ -10868,6 +11606,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_unsecure_test", 
@@ -10884,6 +11623,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -10900,6 +11640,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_invoke_unsecure_test", 
@@ -10916,6 +11657,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_before_invoke_unsecure_test", 
@@ -10932,6 +11674,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test", 
@@ -10948,6 +11691,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_census_simple_request_unsecure_test", 
@@ -10964,6 +11708,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -10980,6 +11725,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -10996,6 +11742,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_empty_batch_unsecure_test", 
@@ -11012,6 +11759,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_graceful_server_shutdown_unsecure_test", 
@@ -11028,6 +11776,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_invoke_large_request_unsecure_test", 
@@ -11044,6 +11793,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_max_concurrent_streams_unsecure_test", 
@@ -11060,6 +11810,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_max_message_length_unsecure_test", 
@@ -11076,6 +11827,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_no_op_unsecure_test", 
@@ -11092,6 +11844,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_ping_pong_streaming_unsecure_test", 
@@ -11108,6 +11861,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_registered_call_unsecure_test", 
@@ -11124,6 +11878,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -11140,6 +11895,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test", 
@@ -11156,6 +11912,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_payload_unsecure_test", 
@@ -11172,6 +11929,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -11188,6 +11946,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_compressed_payload_unsecure_test", 
@@ -11204,6 +11963,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_flags_unsecure_test", 
@@ -11220,6 +11980,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_large_metadata_unsecure_test", 
@@ -11236,6 +11997,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_payload_unsecure_test", 
@@ -11252,6 +12014,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_server_finishes_request_unsecure_test", 
@@ -11268,6 +12031,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_request_unsecure_test", 
@@ -11284,6 +12048,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -11300,6 +12065,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test", 
@@ -11316,6 +12082,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test", 
@@ -11332,6 +12099,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -11348,6 +12116,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test", 
@@ -11364,6 +12133,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test", 
@@ -11380,6 +12150,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test", 
@@ -11396,6 +12167,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test", 
@@ -11412,6 +12184,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -11428,6 +12201,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -11444,6 +12218,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test", 
@@ -11460,6 +12235,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test", 
@@ -11476,6 +12252,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test", 
@@ -11492,6 +12269,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test", 
@@ -11508,6 +12286,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test", 
@@ -11524,6 +12303,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test", 
@@ -11540,6 +12320,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test", 
@@ -11556,6 +12337,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test", 
@@ -11572,6 +12354,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -11588,6 +12371,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test", 
@@ -11604,6 +12388,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test", 
@@ -11620,6 +12405,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -11636,6 +12422,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_compressed_payload_unsecure_test", 
@@ -11652,6 +12439,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_flags_unsecure_test", 
@@ -11668,6 +12456,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test", 
@@ -11684,6 +12473,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test", 
@@ -11700,6 +12490,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_unsecure_test", 
@@ -11716,6 +12507,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test", 
@@ -11732,6 +12524,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -11749,6 +12542,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test", 
@@ -11766,6 +12560,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test", 
@@ -11783,6 +12578,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test", 
@@ -11800,6 +12596,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test", 
@@ -11817,6 +12614,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test", 
@@ -11834,6 +12632,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test", 
@@ -11851,6 +12650,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test", 
@@ -11868,6 +12668,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test", 
@@ -11885,6 +12686,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test", 
@@ -11902,6 +12704,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test", 
@@ -11919,6 +12722,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test", 
@@ -11936,6 +12740,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test", 
@@ -11953,6 +12758,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test", 
@@ -11970,6 +12776,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test", 
@@ -11987,6 +12794,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test", 
@@ -12004,6 +12812,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test", 
@@ -12021,6 +12830,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test", 
@@ -12038,6 +12848,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test", 
@@ -12055,6 +12866,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test", 
@@ -12072,6 +12884,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test", 
@@ -12089,6 +12902,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test", 
@@ -12106,6 +12920,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_compressed_payload_unsecure_test", 
@@ -12123,6 +12938,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_flags_unsecure_test", 
@@ -12140,6 +12956,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test", 
@@ -12157,6 +12974,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test", 
@@ -12174,6 +12992,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test", 
@@ -12191,6 +13010,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test", 
@@ -12208,6 +13028,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test", 
@@ -12225,6 +13046,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "connection_prefix_bad_client_test", 
@@ -12242,6 +13064,7 @@
       "posix", 
       "windows"
     ], 
+    "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
     "name": "initial_settings_frame_bad_client_test", 
diff --git a/vsprojects/Grpc.mak b/vsprojects/Grpc.mak
index 6d49586..662de78 100644
--- a/vsprojects/Grpc.mak
+++ b/vsprojects/Grpc.mak
@@ -83,7 +83,7 @@
 buildtests_c: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe compression_test.exe fling_client.exe fling_server.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_stack_lockfree_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_tls_test.exe gpr_useful_test.exe grpc_auth_context_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_jwt_verifier_test.exe grpc_security_connector_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe json_rewrite.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe multi_init_test.exe multiple_server_queues_test.exe murmur_hash_test.exe no_server_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe time_averaged_stats_test.exe timeout_encoding_test.exe timers_test.exe transport_metadata_test.exe transport_security_test.exe uri_parser_test.exe chttp2_fake_security_bad_hostname_test.exe chttp2_fake_security_cancel_after_accept_test.exe chttp2_fake_security_cancel_after_accept_and_writes_closed_test.exe chttp2_fake_security_cancel_after_invoke_test.exe chttp2_fake_security_cancel_before_invoke_test.exe chttp2_fake_security_cancel_in_a_vacuum_test.exe chttp2_fake_security_census_simple_request_test.exe chttp2_fake_security_channel_connectivity_test.exe chttp2_fake_security_default_host_test.exe chttp2_fake_security_disappearing_server_test.exe chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fake_security_early_server_shutdown_finishes_tags_test.exe chttp2_fake_security_empty_batch_test.exe chttp2_fake_security_graceful_server_shutdown_test.exe chttp2_fake_security_invoke_large_request_test.exe chttp2_fake_security_max_concurrent_streams_test.exe chttp2_fake_security_max_message_length_test.exe chttp2_fake_security_no_op_test.exe chttp2_fake_security_ping_pong_streaming_test.exe chttp2_fake_security_registered_call_test.exe chttp2_fake_security_request_response_with_binary_metadata_and_payload_test.exe chttp2_fake_security_request_response_with_metadata_and_payload_test.exe chttp2_fake_security_request_response_with_payload_test.exe chttp2_fake_security_request_response_with_payload_and_call_creds_test.exe chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fake_security_request_with_compressed_payload_test.exe chttp2_fake_security_request_with_flags_test.exe chttp2_fake_security_request_with_large_metadata_test.exe chttp2_fake_security_request_with_payload_test.exe chttp2_fake_security_server_finishes_request_test.exe chttp2_fake_security_simple_delayed_request_test.exe chttp2_fake_security_simple_request_test.exe chttp2_fake_security_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_bad_hostname_test.exe chttp2_fullstack_cancel_after_accept_test.exe chttp2_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_fullstack_cancel_after_invoke_test.exe chttp2_fullstack_cancel_before_invoke_test.exe chttp2_fullstack_cancel_in_a_vacuum_test.exe chttp2_fullstack_census_simple_request_test.exe chttp2_fullstack_channel_connectivity_test.exe chttp2_fullstack_default_host_test.exe chttp2_fullstack_disappearing_server_test.exe chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_fullstack_empty_batch_test.exe chttp2_fullstack_graceful_server_shutdown_test.exe chttp2_fullstack_invoke_large_request_test.exe chttp2_fullstack_max_concurrent_streams_test.exe chttp2_fullstack_max_message_length_test.exe chttp2_fullstack_no_op_test.exe chttp2_fullstack_ping_pong_streaming_test.exe chttp2_fullstack_registered_call_test.exe chttp2_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_fullstack_request_response_with_payload_test.exe chttp2_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fullstack_request_with_compressed_payload_test.exe chttp2_fullstack_request_with_flags_test.exe chttp2_fullstack_request_with_large_metadata_test.exe chttp2_fullstack_request_with_payload_test.exe chttp2_fullstack_server_finishes_request_test.exe chttp2_fullstack_simple_delayed_request_test.exe chttp2_fullstack_simple_request_test.exe chttp2_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_compression_bad_hostname_test.exe chttp2_fullstack_compression_cancel_after_accept_test.exe chttp2_fullstack_compression_cancel_after_accept_and_writes_closed_test.exe chttp2_fullstack_compression_cancel_after_invoke_test.exe chttp2_fullstack_compression_cancel_before_invoke_test.exe chttp2_fullstack_compression_cancel_in_a_vacuum_test.exe chttp2_fullstack_compression_census_simple_request_test.exe chttp2_fullstack_compression_channel_connectivity_test.exe chttp2_fullstack_compression_default_host_test.exe chttp2_fullstack_compression_disappearing_server_test.exe chttp2_fullstack_compression_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fullstack_compression_early_server_shutdown_finishes_tags_test.exe chttp2_fullstack_compression_empty_batch_test.exe chttp2_fullstack_compression_graceful_server_shutdown_test.exe chttp2_fullstack_compression_invoke_large_request_test.exe chttp2_fullstack_compression_max_concurrent_streams_test.exe chttp2_fullstack_compression_max_message_length_test.exe chttp2_fullstack_compression_no_op_test.exe chttp2_fullstack_compression_ping_pong_streaming_test.exe chttp2_fullstack_compression_registered_call_test.exe chttp2_fullstack_compression_request_response_with_binary_metadata_and_payload_test.exe chttp2_fullstack_compression_request_response_with_metadata_and_payload_test.exe chttp2_fullstack_compression_request_response_with_payload_test.exe chttp2_fullstack_compression_request_response_with_payload_and_call_creds_test.exe chttp2_fullstack_compression_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fullstack_compression_request_with_compressed_payload_test.exe chttp2_fullstack_compression_request_with_flags_test.exe chttp2_fullstack_compression_request_with_large_metadata_test.exe chttp2_fullstack_compression_request_with_payload_test.exe chttp2_fullstack_compression_server_finishes_request_test.exe chttp2_fullstack_compression_simple_delayed_request_test.exe chttp2_fullstack_compression_simple_request_test.exe chttp2_fullstack_compression_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_with_proxy_bad_hostname_test.exe chttp2_fullstack_with_proxy_cancel_after_accept_test.exe chttp2_fullstack_with_proxy_cancel_after_accept_and_writes_closed_test.exe chttp2_fullstack_with_proxy_cancel_after_invoke_test.exe chttp2_fullstack_with_proxy_cancel_before_invoke_test.exe chttp2_fullstack_with_proxy_cancel_in_a_vacuum_test.exe chttp2_fullstack_with_proxy_census_simple_request_test.exe chttp2_fullstack_with_proxy_default_host_test.exe chttp2_fullstack_with_proxy_disappearing_server_test.exe chttp2_fullstack_with_proxy_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fullstack_with_proxy_early_server_shutdown_finishes_tags_test.exe chttp2_fullstack_with_proxy_empty_batch_test.exe chttp2_fullstack_with_proxy_graceful_server_shutdown_test.exe chttp2_fullstack_with_proxy_invoke_large_request_test.exe chttp2_fullstack_with_proxy_max_message_length_test.exe chttp2_fullstack_with_proxy_no_op_test.exe chttp2_fullstack_with_proxy_ping_pong_streaming_test.exe chttp2_fullstack_with_proxy_registered_call_test.exe chttp2_fullstack_with_proxy_request_response_with_binary_metadata_and_payload_test.exe chttp2_fullstack_with_proxy_request_response_with_metadata_and_payload_test.exe chttp2_fullstack_with_proxy_request_response_with_payload_test.exe chttp2_fullstack_with_proxy_request_response_with_payload_and_call_creds_test.exe chttp2_fullstack_with_proxy_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fullstack_with_proxy_request_with_large_metadata_test.exe chttp2_fullstack_with_proxy_request_with_payload_test.exe chttp2_fullstack_with_proxy_server_finishes_request_test.exe chttp2_fullstack_with_proxy_simple_delayed_request_test.exe chttp2_fullstack_with_proxy_simple_request_test.exe chttp2_fullstack_with_proxy_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_fullstack_bad_hostname_test.exe chttp2_simple_ssl_fullstack_cancel_after_accept_test.exe chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_fullstack_cancel_after_invoke_test.exe chttp2_simple_ssl_fullstack_cancel_before_invoke_test.exe chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_fullstack_census_simple_request_test.exe chttp2_simple_ssl_fullstack_channel_connectivity_test.exe chttp2_simple_ssl_fullstack_default_host_test.exe chttp2_simple_ssl_fullstack_disappearing_server_test.exe chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_fullstack_empty_batch_test.exe chttp2_simple_ssl_fullstack_graceful_server_shutdown_test.exe chttp2_simple_ssl_fullstack_invoke_large_request_test.exe chttp2_simple_ssl_fullstack_max_concurrent_streams_test.exe chttp2_simple_ssl_fullstack_max_message_length_test.exe chttp2_simple_ssl_fullstack_no_op_test.exe chttp2_simple_ssl_fullstack_ping_pong_streaming_test.exe chttp2_simple_ssl_fullstack_registered_call_test.exe chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_with_compressed_payload_test.exe chttp2_simple_ssl_fullstack_request_with_flags_test.exe chttp2_simple_ssl_fullstack_request_with_large_metadata_test.exe chttp2_simple_ssl_fullstack_request_with_payload_test.exe chttp2_simple_ssl_fullstack_server_finishes_request_test.exe chttp2_simple_ssl_fullstack_simple_delayed_request_test.exe chttp2_simple_ssl_fullstack_simple_request_test.exe chttp2_simple_ssl_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_fullstack_with_proxy_bad_hostname_test.exe chttp2_simple_ssl_fullstack_with_proxy_cancel_after_accept_test.exe chttp2_simple_ssl_fullstack_with_proxy_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_fullstack_with_proxy_cancel_after_invoke_test.exe chttp2_simple_ssl_fullstack_with_proxy_cancel_before_invoke_test.exe chttp2_simple_ssl_fullstack_with_proxy_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_fullstack_with_proxy_census_simple_request_test.exe chttp2_simple_ssl_fullstack_with_proxy_default_host_test.exe chttp2_simple_ssl_fullstack_with_proxy_disappearing_server_test.exe chttp2_simple_ssl_fullstack_with_proxy_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_fullstack_with_proxy_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_fullstack_with_proxy_empty_batch_test.exe chttp2_simple_ssl_fullstack_with_proxy_graceful_server_shutdown_test.exe chttp2_simple_ssl_fullstack_with_proxy_invoke_large_request_test.exe chttp2_simple_ssl_fullstack_with_proxy_max_message_length_test.exe chttp2_simple_ssl_fullstack_with_proxy_no_op_test.exe chttp2_simple_ssl_fullstack_with_proxy_ping_pong_streaming_test.exe chttp2_simple_ssl_fullstack_with_proxy_registered_call_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_response_with_payload_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_with_large_metadata_test.exe chttp2_simple_ssl_fullstack_with_proxy_request_with_payload_test.exe chttp2_simple_ssl_fullstack_with_proxy_server_finishes_request_test.exe chttp2_simple_ssl_fullstack_with_proxy_simple_delayed_request_test.exe chttp2_simple_ssl_fullstack_with_proxy_simple_request_test.exe chttp2_simple_ssl_fullstack_with_proxy_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_channel_connectivity_test.exe chttp2_simple_ssl_with_oauth2_fullstack_default_host_test.exe chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test.exe chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test.exe chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test.exe chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test.exe chttp2_simple_ssl_with_oauth2_fullstack_max_message_length_test.exe chttp2_simple_ssl_with_oauth2_fullstack_no_op_test.exe chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test.exe chttp2_simple_ssl_with_oauth2_fullstack_registered_call_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_compressed_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_flags_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_server_finishes_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_bad_hostname_test.exe chttp2_socket_pair_cancel_after_accept_test.exe chttp2_socket_pair_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_cancel_after_invoke_test.exe chttp2_socket_pair_cancel_before_invoke_test.exe chttp2_socket_pair_cancel_in_a_vacuum_test.exe chttp2_socket_pair_census_simple_request_test.exe chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_empty_batch_test.exe chttp2_socket_pair_graceful_server_shutdown_test.exe chttp2_socket_pair_invoke_large_request_test.exe chttp2_socket_pair_max_concurrent_streams_test.exe chttp2_socket_pair_max_message_length_test.exe chttp2_socket_pair_no_op_test.exe chttp2_socket_pair_ping_pong_streaming_test.exe chttp2_socket_pair_registered_call_test.exe chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_request_response_with_payload_test.exe chttp2_socket_pair_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_request_with_compressed_payload_test.exe chttp2_socket_pair_request_with_flags_test.exe chttp2_socket_pair_request_with_large_metadata_test.exe chttp2_socket_pair_request_with_payload_test.exe chttp2_socket_pair_server_finishes_request_test.exe chttp2_socket_pair_simple_request_test.exe chttp2_socket_pair_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test.exe chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_one_byte_at_a_time_empty_batch_test.exe chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test.exe chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test.exe chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test.exe chttp2_socket_pair_one_byte_at_a_time_max_message_length_test.exe chttp2_socket_pair_one_byte_at_a_time_no_op_test.exe chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test.exe chttp2_socket_pair_one_byte_at_a_time_registered_call_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_compressed_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_flags_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_with_grpc_trace_bad_hostname_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test.exe chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test.exe chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test.exe chttp2_socket_pair_with_grpc_trace_census_simple_request_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_with_grpc_trace_empty_batch_test.exe chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test.exe chttp2_socket_pair_with_grpc_trace_invoke_large_request_test.exe chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test.exe chttp2_socket_pair_with_grpc_trace_max_message_length_test.exe chttp2_socket_pair_with_grpc_trace_no_op_test.exe chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test.exe chttp2_socket_pair_with_grpc_trace_registered_call_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_with_compressed_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_with_flags_test.exe chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test.exe chttp2_socket_pair_with_grpc_trace_request_with_payload_test.exe chttp2_socket_pair_with_grpc_trace_server_finishes_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_bad_hostname_unsecure_test.exe chttp2_fullstack_cancel_after_accept_unsecure_test.exe chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_fullstack_cancel_after_invoke_unsecure_test.exe chttp2_fullstack_cancel_before_invoke_unsecure_test.exe chttp2_fullstack_cancel_in_a_vacuum_unsecure_test.exe chttp2_fullstack_census_simple_request_unsecure_test.exe chttp2_fullstack_channel_connectivity_unsecure_test.exe chttp2_fullstack_default_host_unsecure_test.exe chttp2_fullstack_disappearing_server_unsecure_test.exe chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_fullstack_empty_batch_unsecure_test.exe chttp2_fullstack_graceful_server_shutdown_unsecure_test.exe chttp2_fullstack_invoke_large_request_unsecure_test.exe chttp2_fullstack_max_concurrent_streams_unsecure_test.exe chttp2_fullstack_max_message_length_unsecure_test.exe chttp2_fullstack_no_op_unsecure_test.exe chttp2_fullstack_ping_pong_streaming_unsecure_test.exe chttp2_fullstack_registered_call_unsecure_test.exe chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_response_with_payload_unsecure_test.exe chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_with_compressed_payload_unsecure_test.exe chttp2_fullstack_request_with_flags_unsecure_test.exe chttp2_fullstack_request_with_large_metadata_unsecure_test.exe chttp2_fullstack_request_with_payload_unsecure_test.exe chttp2_fullstack_server_finishes_request_unsecure_test.exe chttp2_fullstack_simple_delayed_request_unsecure_test.exe chttp2_fullstack_simple_request_unsecure_test.exe chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_fullstack_compression_bad_hostname_unsecure_test.exe chttp2_fullstack_compression_cancel_after_accept_unsecure_test.exe chttp2_fullstack_compression_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_fullstack_compression_cancel_after_invoke_unsecure_test.exe chttp2_fullstack_compression_cancel_before_invoke_unsecure_test.exe chttp2_fullstack_compression_cancel_in_a_vacuum_unsecure_test.exe chttp2_fullstack_compression_census_simple_request_unsecure_test.exe chttp2_fullstack_compression_channel_connectivity_unsecure_test.exe chttp2_fullstack_compression_default_host_unsecure_test.exe chttp2_fullstack_compression_disappearing_server_unsecure_test.exe chttp2_fullstack_compression_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_fullstack_compression_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_fullstack_compression_empty_batch_unsecure_test.exe chttp2_fullstack_compression_graceful_server_shutdown_unsecure_test.exe chttp2_fullstack_compression_invoke_large_request_unsecure_test.exe chttp2_fullstack_compression_max_concurrent_streams_unsecure_test.exe chttp2_fullstack_compression_max_message_length_unsecure_test.exe chttp2_fullstack_compression_no_op_unsecure_test.exe chttp2_fullstack_compression_ping_pong_streaming_unsecure_test.exe chttp2_fullstack_compression_registered_call_unsecure_test.exe chttp2_fullstack_compression_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_fullstack_compression_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_fullstack_compression_request_response_with_payload_unsecure_test.exe chttp2_fullstack_compression_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_fullstack_compression_request_with_compressed_payload_unsecure_test.exe chttp2_fullstack_compression_request_with_flags_unsecure_test.exe chttp2_fullstack_compression_request_with_large_metadata_unsecure_test.exe chttp2_fullstack_compression_request_with_payload_unsecure_test.exe chttp2_fullstack_compression_server_finishes_request_unsecure_test.exe chttp2_fullstack_compression_simple_delayed_request_unsecure_test.exe chttp2_fullstack_compression_simple_request_unsecure_test.exe chttp2_fullstack_compression_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_fullstack_with_proxy_bad_hostname_unsecure_test.exe chttp2_fullstack_with_proxy_cancel_after_accept_unsecure_test.exe chttp2_fullstack_with_proxy_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_fullstack_with_proxy_cancel_after_invoke_unsecure_test.exe chttp2_fullstack_with_proxy_cancel_before_invoke_unsecure_test.exe chttp2_fullstack_with_proxy_cancel_in_a_vacuum_unsecure_test.exe chttp2_fullstack_with_proxy_census_simple_request_unsecure_test.exe chttp2_fullstack_with_proxy_default_host_unsecure_test.exe chttp2_fullstack_with_proxy_disappearing_server_unsecure_test.exe chttp2_fullstack_with_proxy_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_fullstack_with_proxy_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_fullstack_with_proxy_empty_batch_unsecure_test.exe chttp2_fullstack_with_proxy_graceful_server_shutdown_unsecure_test.exe chttp2_fullstack_with_proxy_invoke_large_request_unsecure_test.exe chttp2_fullstack_with_proxy_max_message_length_unsecure_test.exe chttp2_fullstack_with_proxy_no_op_unsecure_test.exe chttp2_fullstack_with_proxy_ping_pong_streaming_unsecure_test.exe chttp2_fullstack_with_proxy_registered_call_unsecure_test.exe chttp2_fullstack_with_proxy_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_fullstack_with_proxy_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_fullstack_with_proxy_request_response_with_payload_unsecure_test.exe chttp2_fullstack_with_proxy_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_fullstack_with_proxy_request_with_large_metadata_unsecure_test.exe chttp2_fullstack_with_proxy_request_with_payload_unsecure_test.exe chttp2_fullstack_with_proxy_server_finishes_request_unsecure_test.exe chttp2_fullstack_with_proxy_simple_delayed_request_unsecure_test.exe chttp2_fullstack_with_proxy_simple_request_unsecure_test.exe chttp2_fullstack_with_proxy_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_bad_hostname_unsecure_test.exe chttp2_socket_pair_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_census_simple_request_unsecure_test.exe chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_empty_batch_unsecure_test.exe chttp2_socket_pair_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_invoke_large_request_unsecure_test.exe chttp2_socket_pair_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_max_message_length_unsecure_test.exe chttp2_socket_pair_no_op_unsecure_test.exe chttp2_socket_pair_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_registered_call_unsecure_test.exe chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_with_compressed_payload_unsecure_test.exe chttp2_socket_pair_request_with_flags_unsecure_test.exe chttp2_socket_pair_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_request_with_payload_unsecure_test.exe chttp2_socket_pair_server_finishes_request_unsecure_test.exe chttp2_socket_pair_simple_request_unsecure_test.exe chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_compressed_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_flags_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_compressed_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_flags_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test.exe connection_prefix_bad_client_test.exe initial_settings_frame_bad_client_test.exe 
 	echo All C tests built.
 
-buildtests_cxx: async_end2end_test.exe auth_property_iterator_test.exe channel_arguments_test.exe cli_call_test.exe client_crash_test_server.exe credentials_test.exe cxx_byte_buffer_test.exe cxx_slice_test.exe cxx_time_test.exe dynamic_thread_pool_test.exe end2end_test.exe fixed_size_thread_pool_test.exe generic_end2end_test.exe grpc_cli.exe mock_test.exe reconnect_interop_client.exe reconnect_interop_server.exe secure_auth_context_test.exe server_crash_test_client.exe status_test.exe thread_stress_test.exe zookeeper_test.exe 
+buildtests_cxx: async_end2end_test.exe auth_property_iterator_test.exe channel_arguments_test.exe cli_call_test.exe client_crash_test_server.exe credentials_test.exe cxx_byte_buffer_test.exe cxx_slice_test.exe cxx_time_test.exe dynamic_thread_pool_test.exe end2end_test.exe fixed_size_thread_pool_test.exe generic_end2end_test.exe grpc_cli.exe mock_test.exe reconnect_interop_client.exe reconnect_interop_server.exe secure_auth_context_test.exe server_crash_test_client.exe shutdown_test.exe status_test.exe thread_stress_test.exe zookeeper_test.exe 
 	echo All C++ tests built.
 
 
@@ -767,6 +767,14 @@
 	echo Running server_crash_test_client
 	$(OUT_DIR)\server_crash_test_client.exe
 
+shutdown_test.exe: Debug\grpc++_test_util.lib build_grpc_test_util build_grpc++ Debug\grpc_zookeeper.lib build_grpc build_gpr_test_util build_gpr $(OUT_DIR)
+	echo Building shutdown_test
+    $(CC) $(CXXFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\cpp\end2end\shutdown_test.cc 
+	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\shutdown_test.exe" Debug\grpc++_test_util.lib Debug\grpc_test_util.lib Debug\grpc++.lib Debug\grpc_zookeeper.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(CXX_LIBS) $(LIBS) $(OUT_DIR)\shutdown_test.obj 
+shutdown_test: shutdown_test.exe
+	echo Running shutdown_test
+	$(OUT_DIR)\shutdown_test.exe
+
 status_test.exe: build_grpc_test_util build_grpc++ build_grpc build_gpr_test_util build_gpr $(OUT_DIR)
 	echo Building status_test
     $(CC) $(CXXFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\cpp\util\status_test.cc