diff --git a/.gitignore b/.gitignore
index ed015b3c92e1c23d1827016d097fb77d8f56e185..3cc35ff7cd1f4357b7649d76d2cc4ea1c8e52711 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,7 @@ py27/
 py34/
 
 # Node installation output
-^node_modules
+node_modules
 src/node/extension_binary/
 
 # gcov coverage data
diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json
index 40fba7cf1f5d097b579904d30e36bef1d9f7edf6..72254ce73e9b3e65f22d22441bdd81fb39de6a88 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/project.json
+++ b/examples/csharp/helloworld-from-cli/Greeter/project.json
@@ -6,7 +6,7 @@
   },
   "dependencies": {
     "Google.Protobuf": "3.0.0",
-    "Grpc": "1.0.0",
+    "Grpc": "1.0.1",
   },
   "frameworks": {
     "net45": {
@@ -17,6 +17,15 @@
       "dependencies": {
 	"Microsoft.NETCore.Platforms": "1.0.1" 
       }
+    },
+    "netcoreapp1.0": {
+      "dependencies": {
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.1"
+        }
+      },
+      "imports": "dnxcore50"
     }
   }
 }
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
index 74962a90e90e538158f4a9df4710d451521d9c30..09e156f68e8f3103f587f5b8b822e54feaf68566 100644
--- a/examples/csharp/helloworld-from-cli/GreeterClient/project.json
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
@@ -7,7 +7,7 @@
   },
   "dependencies": {
     "Google.Protobuf": "3.0.0",
-    "Grpc": "1.0.0",
+    "Grpc": "1.0.1",
     "Greeter": {
       "target": "project"
     }
@@ -21,6 +21,15 @@
       "dependencies": {
 	"Microsoft.NETCore.Platforms": "1.0.1" 
       }
+    },
+    "netcoreapp1.0": {
+      "dependencies": {
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.1"
+        }
+      },
+      "imports": "dnxcore50"
     }
   }
 }
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
index 33af25448197a1556a943e04660734a77908d578..8802fe32657843089e2f6bb4b2a6f71d32d2ed65 100644
--- a/examples/csharp/helloworld-from-cli/GreeterServer/project.json
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
@@ -7,7 +7,7 @@
   },
   "dependencies": {
     "Google.Protobuf": "3.0.0",
-    "Grpc": "1.0.0",
+    "Grpc": "1.0.1",
     "Greeter": {
       "target": "project"
     }
@@ -21,6 +21,15 @@
       "dependencies": {
 	"Microsoft.NETCore.Platforms": "1.0.1" 
       }
+    },
+    "netcoreapp1.0": {
+      "dependencies": {
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.1"
+        }
+      },
+      "imports": "dnxcore50"
     }
   }
 }
diff --git a/examples/csharp/helloworld/Greeter/Greeter.csproj b/examples/csharp/helloworld/Greeter/Greeter.csproj
index 54a41d1746a0d850f2abd69f32a61127eeaa2601..036e6b59fbcfce1854206e191ad37d76e5b692b0 100644
--- a/examples/csharp/helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/helloworld/Greeter/Greeter.csproj
@@ -35,9 +35,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -61,11 +61,11 @@
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup />
-  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
   </Target>
 </Project>
diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config
index 46f7ddacb76413f9afd2c44d2c77236c8bf819a9..2bb3a182a660b1b20c03a9e4be930586ec3bb58b 100644
--- a/examples/csharp/helloworld/Greeter/packages.config
+++ b/examples/csharp/helloworld/Greeter/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.1" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc.Tools" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Tools" version="1.0.1" targetFramework="net45" />
 </packages>
diff --git a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
index 43d85e194cff8fe8f571708221ccf98a84bb2df3..639ac0e70ca00c0b22b80fc1f649f46f9e22c49f 100644
--- a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
@@ -35,9 +35,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -59,11 +59,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
   </Target>
 </Project>
diff --git a/examples/csharp/helloworld/GreeterClient/packages.config b/examples/csharp/helloworld/GreeterClient/packages.config
index 9f5509769a18625477b4222e5242c23935642f4c..addcae0f17317f727c4361dae91641a7d90c6dc0 100644
--- a/examples/csharp/helloworld/GreeterClient/packages.config
+++ b/examples/csharp/helloworld/GreeterClient/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.1" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
 </packages>
diff --git a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
index 5a3457fb7a221014ec3841e7fa7142fbe0c98c62..aa7188839c5d57050984f9471ce883f16b2c732d 100644
--- a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
@@ -35,9 +35,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -59,11 +59,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
   </Target>
 </Project>
diff --git a/examples/csharp/helloworld/GreeterServer/packages.config b/examples/csharp/helloworld/GreeterServer/packages.config
index 9f5509769a18625477b4222e5242c23935642f4c..addcae0f17317f727c4361dae91641a7d90c6dc0 100644
--- a/examples/csharp/helloworld/GreeterServer/packages.config
+++ b/examples/csharp/helloworld/GreeterServer/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.1" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
 </packages>
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
index 446113de9d5c387f67f106059f2a52031f5d0359..54cb823983e13dc9ac11dc1092a5ab9a7761f680 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
 namespace Routeguide {
 
   /// <summary>Holder for reflection information generated from route_guide.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class RouteGuideReflection {
 
     #region Descriptor
@@ -59,30 +58,35 @@ namespace Routeguide {
   ///  Latitudes should be in the range +/- 90 degrees and longitude should be in
   ///  the range +/- 180 degrees (inclusive).
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Point : pb::IMessage<Point> {
     private static readonly pb::MessageParser<Point> _parser = new pb::MessageParser<Point>(() => new Point());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Point> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Point() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Point(Point other) : this() {
       latitude_ = other.latitude_;
       longitude_ = other.longitude_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Point Clone() {
       return new Point(this);
     }
@@ -90,6 +94,7 @@ namespace Routeguide {
     /// <summary>Field number for the "latitude" field.</summary>
     public const int LatitudeFieldNumber = 1;
     private int latitude_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Latitude {
       get { return latitude_; }
       set {
@@ -100,6 +105,7 @@ namespace Routeguide {
     /// <summary>Field number for the "longitude" field.</summary>
     public const int LongitudeFieldNumber = 2;
     private int longitude_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Longitude {
       get { return longitude_; }
       set {
@@ -107,10 +113,12 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Point);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Point other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -123,6 +131,7 @@ namespace Routeguide {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Latitude != 0) hash ^= Latitude.GetHashCode();
@@ -130,10 +139,12 @@ namespace Routeguide {
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Latitude != 0) {
         output.WriteRawTag(8);
@@ -145,6 +156,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Latitude != 0) {
@@ -156,6 +168,7 @@ namespace Routeguide {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Point other) {
       if (other == null) {
         return;
@@ -168,6 +181,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -193,30 +207,35 @@ namespace Routeguide {
   ///  A latitude-longitude rectangle, represented as two diagonally opposite
   ///  points "lo" and "hi".
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Rectangle : pb::IMessage<Rectangle> {
     private static readonly pb::MessageParser<Rectangle> _parser = new pb::MessageParser<Rectangle>(() => new Rectangle());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Rectangle> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Rectangle() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Rectangle(Rectangle other) : this() {
       Lo = other.lo_ != null ? other.Lo.Clone() : null;
       Hi = other.hi_ != null ? other.Hi.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Rectangle Clone() {
       return new Rectangle(this);
     }
@@ -227,6 +246,7 @@ namespace Routeguide {
     /// <summary>
     ///  One corner of the rectangle.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Lo {
       get { return lo_; }
       set {
@@ -240,6 +260,7 @@ namespace Routeguide {
     /// <summary>
     ///  The other corner of the rectangle.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Hi {
       get { return hi_; }
       set {
@@ -247,10 +268,12 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Rectangle);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Rectangle other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -263,6 +286,7 @@ namespace Routeguide {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (lo_ != null) hash ^= Lo.GetHashCode();
@@ -270,10 +294,12 @@ namespace Routeguide {
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (lo_ != null) {
         output.WriteRawTag(10);
@@ -285,6 +311,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (lo_ != null) {
@@ -296,6 +323,7 @@ namespace Routeguide {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Rectangle other) {
       if (other == null) {
         return;
@@ -314,6 +342,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -346,30 +375,35 @@ namespace Routeguide {
   ///
   ///  If a feature could not be named, the name is empty.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Feature : pb::IMessage<Feature> {
     private static readonly pb::MessageParser<Feature> _parser = new pb::MessageParser<Feature>(() => new Feature());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Feature> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Feature() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Feature(Feature other) : this() {
       name_ = other.name_;
       Location = other.location_ != null ? other.Location.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Feature Clone() {
       return new Feature(this);
     }
@@ -380,6 +414,7 @@ namespace Routeguide {
     /// <summary>
     ///  The name of the feature.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
       get { return name_; }
       set {
@@ -393,6 +428,7 @@ namespace Routeguide {
     /// <summary>
     ///  The point where the feature is detected.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Location {
       get { return location_; }
       set {
@@ -400,10 +436,12 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Feature);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Feature other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -416,6 +454,7 @@ namespace Routeguide {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -423,10 +462,12 @@ namespace Routeguide {
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
         output.WriteRawTag(10);
@@ -438,6 +479,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
@@ -449,6 +491,7 @@ namespace Routeguide {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Feature other) {
       if (other == null) {
         return;
@@ -464,6 +507,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -491,30 +535,35 @@ namespace Routeguide {
   /// <summary>
   ///  A RouteNote is a message sent while at a given point.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class RouteNote : pb::IMessage<RouteNote> {
     private static readonly pb::MessageParser<RouteNote> _parser = new pb::MessageParser<RouteNote>(() => new RouteNote());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<RouteNote> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[3]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RouteNote() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RouteNote(RouteNote other) : this() {
       Location = other.location_ != null ? other.Location.Clone() : null;
       message_ = other.message_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RouteNote Clone() {
       return new RouteNote(this);
     }
@@ -525,6 +574,7 @@ namespace Routeguide {
     /// <summary>
     ///  The location from which the message is sent.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Routeguide.Point Location {
       get { return location_; }
       set {
@@ -538,6 +588,7 @@ namespace Routeguide {
     /// <summary>
     ///  The message to be sent.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Message {
       get { return message_; }
       set {
@@ -545,10 +596,12 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as RouteNote);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(RouteNote other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -561,6 +614,7 @@ namespace Routeguide {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (location_ != null) hash ^= Location.GetHashCode();
@@ -568,10 +622,12 @@ namespace Routeguide {
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (location_ != null) {
         output.WriteRawTag(10);
@@ -583,6 +639,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (location_ != null) {
@@ -594,6 +651,7 @@ namespace Routeguide {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(RouteNote other) {
       if (other == null) {
         return;
@@ -609,6 +667,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -640,25 +699,29 @@ namespace Routeguide {
   ///  detected features, and the total distance covered as the cumulative sum of
   ///  the distance between each point.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class RouteSummary : pb::IMessage<RouteSummary> {
     private static readonly pb::MessageParser<RouteSummary> _parser = new pb::MessageParser<RouteSummary>(() => new RouteSummary());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<RouteSummary> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[4]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RouteSummary() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RouteSummary(RouteSummary other) : this() {
       pointCount_ = other.pointCount_;
       featureCount_ = other.featureCount_;
@@ -666,6 +729,7 @@ namespace Routeguide {
       elapsedTime_ = other.elapsedTime_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RouteSummary Clone() {
       return new RouteSummary(this);
     }
@@ -676,6 +740,7 @@ namespace Routeguide {
     /// <summary>
     ///  The number of points received.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int PointCount {
       get { return pointCount_; }
       set {
@@ -689,6 +754,7 @@ namespace Routeguide {
     /// <summary>
     ///  The number of known features passed while traversing the route.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FeatureCount {
       get { return featureCount_; }
       set {
@@ -702,6 +768,7 @@ namespace Routeguide {
     /// <summary>
     ///  The distance covered in metres.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Distance {
       get { return distance_; }
       set {
@@ -715,6 +782,7 @@ namespace Routeguide {
     /// <summary>
     ///  The duration of the traversal in seconds.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ElapsedTime {
       get { return elapsedTime_; }
       set {
@@ -722,10 +790,12 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as RouteSummary);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(RouteSummary other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -740,6 +810,7 @@ namespace Routeguide {
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (PointCount != 0) hash ^= PointCount.GetHashCode();
@@ -749,10 +820,12 @@ namespace Routeguide {
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (PointCount != 0) {
         output.WriteRawTag(8);
@@ -772,6 +845,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (PointCount != 0) {
@@ -789,6 +863,7 @@ namespace Routeguide {
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(RouteSummary other) {
       if (other == null) {
         return;
@@ -807,6 +882,7 @@ namespace Routeguide {
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
index 02bca2fc7255299a2636582a0462cd74fc01f482..eee8f0a1bcee1bc63907d02bbf43b05ea346b254 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
@@ -35,9 +35,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -74,12 +74,12 @@
     </None>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config
index 4e8d3f236dc7d666511dceeb7d9069f53fe27d13..b7c401b3c85140ca5c8c98f9ad83053a6ff2e56a 100644
--- a/examples/csharp/route_guide/RouteGuide/packages.config
+++ b/examples/csharp/route_guide/RouteGuide/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.1" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
diff --git a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
index 4792c5287445ff119acac8e701d6b418357bef46..a513f6af877b60b87f9f228ed693be826e210266 100644
--- a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
+++ b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
@@ -37,9 +37,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -71,12 +71,12 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config
index 4e8d3f236dc7d666511dceeb7d9069f53fe27d13..b7c401b3c85140ca5c8c98f9ad83053a6ff2e56a 100644
--- a/examples/csharp/route_guide/RouteGuideClient/packages.config
+++ b/examples/csharp/route_guide/RouteGuideClient/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.1" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
index b35e576fb86e9fd57d3b653fa9b72d0edd61ea76..8892554b7edc4df8f1612794d5ecf1f32b0e5e3b 100644
--- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
+++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
@@ -37,9 +37,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+    <Reference Include="Grpc.Core, Version=1.0.1.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.1\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -72,12 +72,12 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.1\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config
index a742eb2ff108a1f6b006ded31c7003f93ce0705b..dd498f48ea34ac16a98c78ee5aa73067a2d4ea5c 100644
--- a/examples/csharp/route_guide/RouteGuideServer/packages.config
+++ b/examples/csharp/route_guide/RouteGuideServer/packages.config
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
-  <package id="Grpc" version="1.0.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.1" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.1" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="Grpc.Tools" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Tools" version="1.0.1" targetFramework="net45" />
 </packages>
diff --git a/grpc.gemspec b/grpc.gemspec
index e2a2ffc21a9460e10cd0f25ccf218193ea10743e..cce6f2cfcccd2add5d390126cb0b9b274e5023d5 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -29,7 +29,6 @@ Gem::Specification.new do |s|
 
   s.add_dependency 'google-protobuf', '~> 3.0.2'
   s.add_dependency 'googleauth',      '~> 0.5.1'
-  s.add_dependency 'concurrent-ruby'
 
   s.add_development_dependency 'bundler',            '~> 1.9'
   s.add_development_dependency 'facter',             '~> 2.4'
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 48157033db60c3ff4bd27dd24fe3796c8da1cfe5..a3af258d9c36b20bd1e36c21538cd48618046660 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -313,7 +313,7 @@ void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
       "/// <summary>Base class for server-side implementations of "
       "$servicename$</summary>\n",
       "servicename", GetServiceClassName(service));
-  out->Print("public abstract class $name$\n", "name",
+  out->Print("public abstract partial class $name$\n", "name",
              GetServerClassName(service));
   out->Print("{\n");
   out->Indent();
@@ -344,7 +344,7 @@ void GenerateServerClass(Printer *out, const ServiceDescriptor *service) {
 void GenerateClientStub(Printer *out, const ServiceDescriptor *service) {
   out->Print("/// <summary>Client for $servicename$</summary>\n", "servicename",
              GetServiceClassName(service));
-  out->Print("public class $name$ : ClientBase<$name$>\n", "name",
+  out->Print("public partial class $name$ : ClientBase<$name$>\n", "name",
              GetClientClassName(service));
   out->Print("{\n");
   out->Indent();
@@ -549,8 +549,8 @@ void GenerateService(Printer *out, const ServiceDescriptor *service,
                      bool generate_client, bool generate_server,
                      bool internal_access) {
   GenerateDocCommentBody(out, service);
-  out->Print("$access_level$ static class $classname$\n", "access_level",
-             GetAccessLevel(internal_access), "classname",
+  out->Print("$access_level$ static partial class $classname$\n",
+             "access_level", GetAccessLevel(internal_access), "classname",
              GetServiceClassName(service));
   out->Print("{\n");
   out->Indent();
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 127e1cdc132a3351c82c3cfe98a6f2149fa3ed12..4e3c7ff681ff19356148b3a5ade04142947b4b9e 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -954,6 +954,16 @@ static void complete_fetch(grpc_exec_ctx *exec_ctx, void *gs,
 
 static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
 
+static void log_metadata(const grpc_metadata_batch *md_batch, uint32_t id,
+                         bool is_client, bool is_initial) {
+  for (grpc_linked_mdelem *md = md_batch->list.head; md != md_batch->list.tail;
+       md = md->next) {
+    gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL",
+            is_client ? "CLI" : "SVR", grpc_mdstr_as_c_string(md->md->key),
+            grpc_mdstr_as_c_string(md->md->value));
+  }
+}
+
 static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
                                      grpc_error *error_ignored) {
   GPR_TIMER_BEGIN("perform_stream_op_locked", 0);
@@ -967,6 +977,12 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
     gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
             op->on_complete);
     gpr_free(str);
+    if (op->send_initial_metadata) {
+      log_metadata(op->send_initial_metadata, s->id, t->is_client, true);
+    }
+    if (op->send_trailing_metadata) {
+      log_metadata(op->send_trailing_metadata, s->id, t->is_client, false);
+    }
   }
 
   grpc_closure *on_complete = op->on_complete;
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 91041a7c283a44587c7d08b2a257042c6f6749ec..07fbfd849e2c8470d965c65466aa468a01e2433b 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -72,6 +72,11 @@ static int grpc_polling_trace = 0; /* Disabled by default */
 static int grpc_wakeup_signal = -1;
 static bool is_grpc_wakeup_signal_initialized = false;
 
+/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
+ * sure to wake up one polling thread (which can wake up other threads if
+ * needed) */
+static grpc_wakeup_fd global_wakeup_fd;
+
 /* Implements the function defined in grpc_posix.h. This function might be
  * called before even calling grpc_init() to set either a different signal to
  * use. If signum == -1, then the use of signals is disabled */
@@ -437,9 +442,8 @@ static void polling_island_add_wakeup_fd_locked(polling_island *pi,
     gpr_asprintf(&err_msg,
                  "epoll_ctl (epoll_fd: %d) add wakeup fd: %d failed with "
                  "error: %d (%s)",
-                 pi->epoll_fd,
-                 GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), errno,
-                 strerror(errno));
+                 pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd),
+                 errno, strerror(errno));
     append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
     gpr_free(err_msg);
   }
@@ -541,7 +545,7 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
     goto done;
   }
 
-  polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd, error);
+  polling_island_add_wakeup_fd_locked(pi, &global_wakeup_fd, error);
   polling_island_add_wakeup_fd_locked(pi, &pi->workqueue_wakeup_fd, error);
 
   if (initial_fd != NULL) {
@@ -843,11 +847,6 @@ static void polling_island_global_shutdown() {
  * alarm 'epoch'). This wakeup_fd gives us something to alert on when such a
  * case occurs. */
 
-/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
- * sure to wake up one polling thread (which can wake up other threads if
- * needed) */
-grpc_wakeup_fd grpc_global_wakeup_fd;
-
 static grpc_fd *fd_freelist = NULL;
 static gpr_mu fd_freelist_mu;
 
@@ -1163,11 +1162,11 @@ static grpc_error *pollset_global_init(void) {
   gpr_tls_init(&g_current_thread_pollset);
   gpr_tls_init(&g_current_thread_worker);
   poller_kick_init();
-  return grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
+  return grpc_wakeup_fd_init(&global_wakeup_fd);
 }
 
 static void pollset_global_shutdown(void) {
-  grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
+  grpc_wakeup_fd_destroy(&global_wakeup_fd);
   gpr_tls_destroy(&g_current_thread_pollset);
   gpr_tls_destroy(&g_current_thread_worker);
 }
@@ -1274,7 +1273,7 @@ static grpc_error *pollset_kick(grpc_pollset *p,
 }
 
 static grpc_error *kick_poller(void) {
-  return grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd);
+  return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
 }
 
 static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
@@ -1501,13 +1500,11 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
 
     for (int i = 0; i < ep_rv; ++i) {
       void *data_ptr = ep_ev[i].data.ptr;
-      if (data_ptr == &grpc_global_wakeup_fd) {
-        append_error(error,
-                     grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd),
+      if (data_ptr == &global_wakeup_fd) {
+        append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
                      err_desc);
       } else if (data_ptr == &pi->workqueue_wakeup_fd) {
-        append_error(error,
-                     grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd),
+        append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
                      err_desc);
         maybe_do_workqueue_work(exec_ctx, pi);
       } else if (data_ptr == &polling_island_wakeup_fd) {
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index e1d620cfff93f9528be062fa96ff2c1076a94f59..21b28e5554e9c23a3f87e0d29b5101fcf8e50294 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -120,6 +120,8 @@ struct grpc_fd {
   grpc_pollset *read_notifier_pollset;
 };
 
+static grpc_wakeup_fd global_wakeup_fd;
+
 /* Begin polling on an fd.
    Registers that the given pollset is interested in this fd - so that if read
    or writability interest changes, the pollset can be kicked to pick up that
@@ -769,17 +771,17 @@ static grpc_error *pollset_kick(grpc_pollset *p,
 static grpc_error *pollset_global_init(void) {
   gpr_tls_init(&g_current_thread_poller);
   gpr_tls_init(&g_current_thread_worker);
-  return grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
+  return grpc_wakeup_fd_init(&global_wakeup_fd);
 }
 
 static void pollset_global_shutdown(void) {
-  grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
+  grpc_wakeup_fd_destroy(&global_wakeup_fd);
   gpr_tls_destroy(&g_current_thread_poller);
   gpr_tls_destroy(&g_current_thread_worker);
 }
 
 static grpc_error *kick_poller(void) {
-  return grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd);
+  return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
 }
 
 /* main interface */
@@ -947,7 +949,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
 
       fd_count = 0;
       pfd_count = 2;
-      pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd);
+      pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd);
       pfds[0].events = POLLIN;
       pfds[0].revents = 0;
       pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker.wakeup_fd->fd);
@@ -1001,8 +1003,8 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
         }
       } else {
         if (pfds[0].revents & POLLIN_CHECK) {
-          work_combine_error(
-              &error, grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd));
+          work_combine_error(&error,
+                             grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd));
         }
         if (pfds[1].revents & POLLIN_CHECK) {
           work_combine_error(
@@ -1343,6 +1345,7 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
   int res, idx;
   gpr_cv *pollcv;
   cv_node *cvn, *prev;
+  int skip_poll = 0;
   nfds_t nsockfds = 0;
   gpr_thd_id t_id;
   gpr_thd_options opt;
@@ -1358,17 +1361,17 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
       cvn->cv = pollcv;
       cvn->next = g_cvfds.cvfds[idx].cvs;
       g_cvfds.cvfds[idx].cvs = cvn;
-      // We should return immediately if there are pending events,
-      // but we still need to call poll() to check for socket events
+      // Don't bother polling if a wakeup fd is ready
       if (g_cvfds.cvfds[idx].is_set) {
-        timeout = 0;
+        skip_poll = 1;
       }
     } else if (fds[i].fd >= 0) {
       nsockfds++;
     }
   }
 
-  if (nsockfds > 0) {
+  res = 0;
+  if (!skip_poll && nsockfds > 0) {
     pargs = gpr_malloc(sizeof(struct poll_args));
     // Both the main thread and calling thread get a reference
     gpr_ref_init(&pargs->refcount, 2);
@@ -1398,16 +1401,14 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
       res = pargs->retval;
       errno = pargs->err;
     } else {
-      res = 0;
       errno = 0;
       gpr_atm_no_barrier_store(&pargs->status, CANCELLED);
     }
-  } else {
+  } else if (!skip_poll) {
     gpr_timespec deadline = gpr_now(GPR_CLOCK_REALTIME);
     deadline =
         gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN));
     gpr_cv_wait(pollcv, &g_cvfds.mu, deadline);
-    res = 0;
   }
 
   idx = 0;
@@ -1431,7 +1432,7 @@ static int cvfd_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
         fds[i].revents = POLLIN;
         if (res >= 0) res++;
       }
-    } else if (fds[i].fd >= 0 &&
+    } else if (!skip_poll && fds[i].fd >= 0 &&
                gpr_atm_no_barrier_load(&pargs->status) == COMPLETED) {
       fds[i].revents = pargs->fds[idx].revents;
       idx++;
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 2fdef06838c7dd2951c0bd06f480131c81acfa6d..cb5832539da421b8abe0810f4bc3c314c442b4ef 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -183,6 +183,5 @@ void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
 /* override to allow tests to hook poll() usage */
 typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int);
 extern grpc_poll_function_type grpc_poll_function;
-extern grpc_wakeup_fd grpc_global_wakeup_fd;
 
 #endif /* GRPC_CORE_LIB_IOMGR_EV_POSIX_H */
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 62afbcef51223b5c0f6ee3c0ab478ac18070af30..d4613b674e53870c924fd66bedf9a50112a75eec 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -423,7 +423,7 @@ grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket,
   tcp->base.vtable = &vtable;
   tcp->socket = socket;
   gpr_mu_init(&tcp->mu);
-  gpr_ref_init(&tcp->refcount, 2);
+  gpr_ref_init(&tcp->refcount, 1);
   grpc_closure_init(&tcp->on_read, on_read, tcp);
   grpc_closure_init(&tcp->on_write, on_write, tcp);
   tcp->peer_string = gpr_strdup(peer_string);
diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json
index 595e29f50af1eebb7f89b9877f01f115e146f69d..4052ec839848ea5efbb28e2326263b9dab5f12e1 100644
--- a/src/csharp/Grpc.Auth/project.json
+++ b/src/csharp/Grpc.Auth/project.json
@@ -15,7 +15,6 @@
   "buildOptions": {
     "define": [ "SIGNED" ],
     "keyFile": "../keys/Grpc.snk",
-    "publicSign": true,
     "xmlDoc": true,
     "compile": {
       "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json
index faf28dcee8413435ff1155801a78c56bbd910273..509084a71a6d698c01dbfdec3479ab992d578db1 100644
--- a/src/csharp/Grpc.Core.Tests/project.json
+++ b/src/csharp/Grpc.Core.Tests/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -26,7 +25,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json
index 80f59b2af6774606d918a3d8690dbccbd9201db4..4405ecc5a21a908ea4b43cb950c27b5b3a168858 100644
--- a/src/csharp/Grpc.Core/project.json
+++ b/src/csharp/Grpc.Core/project.json
@@ -27,7 +27,6 @@
     "embed": [ "../../../etc/roots.pem" ],
     "define": [ "SIGNED" ],
     "keyFile": "../keys/Grpc.snk",
-    "publicSign": true,
     "xmlDoc": true
   },
   "dependencies": {
diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json
index 628f5329661b9f9eafe44e9ff2b399207a76be79..9a8880b5d422463547cf15e02dc508c5a1e74d65 100644
--- a/src/csharp/Grpc.Examples.MathClient/project.json
+++ b/src/csharp/Grpc.Examples.MathClient/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -26,7 +25,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json
index 628f5329661b9f9eafe44e9ff2b399207a76be79..9a8880b5d422463547cf15e02dc508c5a1e74d65 100644
--- a/src/csharp/Grpc.Examples.MathServer/project.json
+++ b/src/csharp/Grpc.Examples.MathServer/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -26,7 +25,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json
index 0109617e6b51efc2395f796982e1e20fab960b87..3e130beeac9c8ad23ab5fea46c731297b169082e 100644
--- a/src/csharp/Grpc.Examples.Tests/project.json
+++ b/src/csharp/Grpc.Examples.Tests/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -26,7 +25,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index d6ba61e7dc0bbac0698dd15f259a83c44cb36793..21727d57c6bfa80668b0aaf544e74292cb8ee9ba 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -38,7 +38,7 @@ using System.Threading.Tasks;
 using Grpc.Core;
 
 namespace Math {
-  public static class Math
+  public static partial class Math
   {
     static readonly string __ServiceName = "math.Math";
 
@@ -82,7 +82,7 @@ namespace Math {
     }
 
     /// <summary>Base class for server-side implementations of Math</summary>
-    public abstract class MathBase
+    public abstract partial class MathBase
     {
       /// <summary>
       ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
@@ -126,7 +126,7 @@ namespace Math {
     }
 
     /// <summary>Client for Math</summary>
-    public class MathClient : ClientBase<MathClient>
+    public partial class MathClient : ClientBase<MathClient>
     {
       /// <summary>Creates a new client for Math</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json
index 66dcd79a397cb444757b6baeebd0f982b9a5d9a2..addc782afe8ed3c0675322827af8feda69a7368a 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/project.json
+++ b/src/csharp/Grpc.HealthCheck.Tests/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -26,7 +25,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index b2a35a79be9a6e8e610318766bfc6b728c7e4853..03381f0b884625d54afb12ab5563e95314567607 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -38,7 +38,7 @@ using System.Threading.Tasks;
 using Grpc.Core;
 
 namespace Grpc.Health.V1 {
-  public static class Health
+  public static partial class Health
   {
     static readonly string __ServiceName = "grpc.health.v1.Health";
 
@@ -59,7 +59,7 @@ namespace Grpc.Health.V1 {
     }
 
     /// <summary>Base class for server-side implementations of Health</summary>
-    public abstract class HealthBase
+    public abstract partial class HealthBase
     {
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context)
       {
@@ -69,7 +69,7 @@ namespace Grpc.Health.V1 {
     }
 
     /// <summary>Client for Health</summary>
-    public class HealthClient : ClientBase<HealthClient>
+    public partial class HealthClient : ClientBase<HealthClient>
     {
       /// <summary>Creates a new client for Health</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json
index 9d631229d8e7fca7aa6e0555f945ea41cd31baee..8f1237d00301a65511018e2ea53bef9f69c8198a 100644
--- a/src/csharp/Grpc.HealthCheck/project.json
+++ b/src/csharp/Grpc.HealthCheck/project.json
@@ -15,7 +15,6 @@
   "buildOptions": {
     "define": [ "SIGNED" ],
     "keyFile": "../keys/Grpc.snk",
-    "publicSign": true,
     "xmlDoc": true,
     "compile": {
       "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json
index 1b900c8af3270baafe9a421f7ae4a672dae5a8b4..ad81cbc48b36ef30d8830eb915232d75aa98e967 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -29,7 +28,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
index fe200f8d4406da87234543221f74ac5293d69027..2c7643b74f0c36ea84eda29113124d65b7a63d46 100644
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -29,7 +28,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json
index 1b900c8af3270baafe9a421f7ae4a672dae5a8b4..ad81cbc48b36ef30d8830eb915232d75aa98e967 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -29,7 +28,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
index 1b900c8af3270baafe9a421f7ae4a672dae5a8b4..ad81cbc48b36ef30d8830eb915232d75aa98e967 100644
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -29,7 +28,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 7928b51ba54b9a54ed47e0936c75269a8f71ab5e..3f4862d5671cb0d530bcd280b8f008085202e656 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -45,44 +45,48 @@ namespace Grpc.Testing {
             "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr",
             "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy",
             "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS",
-            "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSKWAgoMU2VydmVyQ29u",
+            "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSK0AgoMU2VydmVyQ29u",
             "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl",
             "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n",
             "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy",
             "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk",
             "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK",
-            "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJImgK",
-            "ClNlcnZlckFyZ3MSKwoFc2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2Vy",
-            "dmVyQ29uZmlnSAASIgoEbWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJr",
-            "SABCCQoHYXJndHlwZSJVCgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsy",
-            "GS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVj",
-            "b3JlcxgDIAEoBSINCgtDb3JlUmVxdWVzdCIdCgxDb3JlUmVzcG9uc2USDQoF",
-            "Y29yZXMYASABKAUiBgoEVm9pZCL9AQoIU2NlbmFyaW8SDAoEbmFtZRgBIAEo",
-            "CRIxCg1jbGllbnRfY29uZmlnGAIgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVu",
-            "dENvbmZpZxITCgtudW1fY2xpZW50cxgDIAEoBRIxCg1zZXJ2ZXJfY29uZmln",
-            "GAQgASgLMhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZxITCgtudW1fc2Vy",
-            "dmVycxgFIAEoBRIWCg53YXJtdXBfc2Vjb25kcxgGIAEoBRIZChFiZW5jaG1h",
-            "cmtfc2Vjb25kcxgHIAEoBRIgChhzcGF3bl9sb2NhbF93b3JrZXJfY291bnQY",
-            "CCABKAUiNgoJU2NlbmFyaW9zEikKCXNjZW5hcmlvcxgBIAMoCzIWLmdycGMu",
-            "dGVzdGluZy5TY2VuYXJpbyKSAgoVU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EgsK",
-            "A3FwcxgBIAEoARIbChNxcHNfcGVyX3NlcnZlcl9jb3JlGAIgASgBEhoKEnNl",
-            "cnZlcl9zeXN0ZW1fdGltZRgDIAEoARIYChBzZXJ2ZXJfdXNlcl90aW1lGAQg",
-            "ASgBEhoKEmNsaWVudF9zeXN0ZW1fdGltZRgFIAEoARIYChBjbGllbnRfdXNl",
-            "cl90aW1lGAYgASgBEhIKCmxhdGVuY3lfNTAYByABKAESEgoKbGF0ZW5jeV85",
-            "MBgIIAEoARISCgpsYXRlbmN5Xzk1GAkgASgBEhIKCmxhdGVuY3lfOTkYCiAB",
-            "KAESEwoLbGF0ZW5jeV85OTkYCyABKAEiyAIKDlNjZW5hcmlvUmVzdWx0EigK",
-            "CHNjZW5hcmlvGAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxh",
-            "dGVuY2llcxgCIAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8K",
-            "DGNsaWVudF9zdGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0",
-            "cxIvCgxzZXJ2ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVy",
-            "U3RhdHMSFAoMc2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsy",
-            "Iy5ncnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVu",
-            "dF9zdWNjZXNzGAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIKkEKCkNs",
-            "aWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQARIQ",
-            "CgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VSVkVS",
-            "EAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJWRVIQ",
-            "AhIQCgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJ",
-            "U1RSRUFNSU5HEAFiBnByb3RvMw=="));
+            "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhwK",
+            "E3Jlc291cmNlX3F1b3RhX3NpemUY6QcgASgFImgKClNlcnZlckFyZ3MSKwoF",
+            "c2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVyQ29uZmlnSAASIgoE",
+            "bWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSJV",
+            "CgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rpbmcu",
+            "U2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3JlcxgDIAEoBSINCgtD",
+            "b3JlUmVxdWVzdCIdCgxDb3JlUmVzcG9uc2USDQoFY29yZXMYASABKAUiBgoE",
+            "Vm9pZCL9AQoIU2NlbmFyaW8SDAoEbmFtZRgBIAEoCRIxCg1jbGllbnRfY29u",
+            "ZmlnGAIgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENvbmZpZxITCgtudW1f",
+            "Y2xpZW50cxgDIAEoBRIxCg1zZXJ2ZXJfY29uZmlnGAQgASgLMhouZ3JwYy50",
+            "ZXN0aW5nLlNlcnZlckNvbmZpZxITCgtudW1fc2VydmVycxgFIAEoBRIWCg53",
+            "YXJtdXBfc2Vjb25kcxgGIAEoBRIZChFiZW5jaG1hcmtfc2Vjb25kcxgHIAEo",
+            "BRIgChhzcGF3bl9sb2NhbF93b3JrZXJfY291bnQYCCABKAUiNgoJU2NlbmFy",
+            "aW9zEikKCXNjZW5hcmlvcxgBIAMoCzIWLmdycGMudGVzdGluZy5TY2VuYXJp",
+            "byL4AgoVU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EgsKA3FwcxgBIAEoARIbChNx",
+            "cHNfcGVyX3NlcnZlcl9jb3JlGAIgASgBEhoKEnNlcnZlcl9zeXN0ZW1fdGlt",
+            "ZRgDIAEoARIYChBzZXJ2ZXJfdXNlcl90aW1lGAQgASgBEhoKEmNsaWVudF9z",
+            "eXN0ZW1fdGltZRgFIAEoARIYChBjbGllbnRfdXNlcl90aW1lGAYgASgBEhIK",
+            "CmxhdGVuY3lfNTAYByABKAESEgoKbGF0ZW5jeV85MBgIIAEoARISCgpsYXRl",
+            "bmN5Xzk1GAkgASgBEhIKCmxhdGVuY3lfOTkYCiABKAESEwoLbGF0ZW5jeV85",
+            "OTkYCyABKAESGAoQc2VydmVyX2NwdV91c2FnZRgMIAEoARImCh5zdWNjZXNz",
+            "ZnVsX3JlcXVlc3RzX3Blcl9zZWNvbmQYDSABKAESIgoaZmFpbGVkX3JlcXVl",
+            "c3RzX3Blcl9zZWNvbmQYDiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNj",
+            "ZW5hcmlvGAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVu",
+            "Y2llcxgCIAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNs",
+            "aWVudF9zdGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIv",
+            "CgxzZXJ2ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3Rh",
+            "dHMSFAoMc2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5n",
+            "cnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9z",
+            "dWNjZXNzGAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVl",
+            "c3RfcmVzdWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0",
+            "Q291bnQqQQoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5D",
+            "X0NMSUVOVBABEhAKDE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoL",
+            "U1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5F",
+            "UklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhADKiMKB1JwY1R5cGUSCQoF",
+            "VU5BUlkQABINCglTVFJFQU1JTkcQAWIGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -94,7 +98,7 @@ namespace Grpc.Testing {
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig", "CoreList", "OtherServerApi" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig", "CoreList", "OtherServerApi", "ResourceQuotaSize" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerArgs), global::Grpc.Testing.ServerArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStatus), global::Grpc.Testing.ServerStatus.Parser, new[]{ "Stats", "Port", "Cores" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.CoreRequest), global::Grpc.Testing.CoreRequest.Parser, null, null, null, null),
@@ -102,8 +106,8 @@ namespace Grpc.Testing {
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Void), global::Grpc.Testing.Void.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenario), global::Grpc.Testing.Scenario.Parser, new[]{ "Name", "ClientConfig", "NumClients", "ServerConfig", "NumServers", "WarmupSeconds", "BenchmarkSeconds", "SpawnLocalWorkerCount" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenarios), global::Grpc.Testing.Scenarios.Parser, new[]{ "Scenarios_" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary", "ClientSuccess", "ServerSuccess" }, null, null, null)
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999", "ServerCpuUsage", "SuccessfulRequestsPerSecond", "FailedRequestsPerSecond" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary", "ClientSuccess", "ServerSuccess", "RequestResults" }, null, null, null)
           }));
     }
     #endregion
@@ -1641,6 +1645,7 @@ namespace Grpc.Testing {
       PayloadConfig = other.payloadConfig_ != null ? other.PayloadConfig.Clone() : null;
       coreList_ = other.coreList_.Clone();
       otherServerApi_ = other.otherServerApi_;
+      resourceQuotaSize_ = other.resourceQuotaSize_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1753,6 +1758,20 @@ namespace Grpc.Testing {
       }
     }
 
+    /// <summary>Field number for the "resource_quota_size" field.</summary>
+    public const int ResourceQuotaSizeFieldNumber = 1001;
+    private int resourceQuotaSize_;
+    /// <summary>
+    ///  Buffer pool size (no buffer pool specified if unset)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int ResourceQuotaSize {
+      get { return resourceQuotaSize_; }
+      set {
+        resourceQuotaSize_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ServerConfig);
@@ -1774,6 +1793,7 @@ namespace Grpc.Testing {
       if (!object.Equals(PayloadConfig, other.PayloadConfig)) return false;
       if(!coreList_.Equals(other.coreList_)) return false;
       if (OtherServerApi != other.OtherServerApi) return false;
+      if (ResourceQuotaSize != other.ResourceQuotaSize) return false;
       return true;
     }
 
@@ -1788,6 +1808,7 @@ namespace Grpc.Testing {
       if (payloadConfig_ != null) hash ^= PayloadConfig.GetHashCode();
       hash ^= coreList_.GetHashCode();
       if (OtherServerApi.Length != 0) hash ^= OtherServerApi.GetHashCode();
+      if (ResourceQuotaSize != 0) hash ^= ResourceQuotaSize.GetHashCode();
       return hash;
     }
 
@@ -1827,6 +1848,10 @@ namespace Grpc.Testing {
         output.WriteRawTag(90);
         output.WriteString(OtherServerApi);
       }
+      if (ResourceQuotaSize != 0) {
+        output.WriteRawTag(200, 62);
+        output.WriteInt32(ResourceQuotaSize);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1854,6 +1879,9 @@ namespace Grpc.Testing {
       if (OtherServerApi.Length != 0) {
         size += 1 + pb::CodedOutputStream.ComputeStringSize(OtherServerApi);
       }
+      if (ResourceQuotaSize != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(ResourceQuotaSize);
+      }
       return size;
     }
 
@@ -1890,6 +1918,9 @@ namespace Grpc.Testing {
       if (other.OtherServerApi.Length != 0) {
         OtherServerApi = other.OtherServerApi;
       }
+      if (other.ResourceQuotaSize != 0) {
+        ResourceQuotaSize = other.ResourceQuotaSize;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1939,6 +1970,10 @@ namespace Grpc.Testing {
             OtherServerApi = input.ReadString();
             break;
           }
+          case 8008: {
+            ResourceQuotaSize = input.ReadInt32();
+            break;
+          }
         }
       }
     }
@@ -3117,6 +3152,9 @@ namespace Grpc.Testing {
       latency95_ = other.latency95_;
       latency99_ = other.latency99_;
       latency999_ = other.latency999_;
+      serverCpuUsage_ = other.serverCpuUsage_;
+      successfulRequestsPerSecond_ = other.successfulRequestsPerSecond_;
+      failedRequestsPerSecond_ = other.failedRequestsPerSecond_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3266,6 +3304,45 @@ namespace Grpc.Testing {
       }
     }
 
+    /// <summary>Field number for the "server_cpu_usage" field.</summary>
+    public const int ServerCpuUsageFieldNumber = 12;
+    private double serverCpuUsage_;
+    /// <summary>
+    ///  server cpu usage percentage
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public double ServerCpuUsage {
+      get { return serverCpuUsage_; }
+      set {
+        serverCpuUsage_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "successful_requests_per_second" field.</summary>
+    public const int SuccessfulRequestsPerSecondFieldNumber = 13;
+    private double successfulRequestsPerSecond_;
+    /// <summary>
+    ///  Number of requests that succeeded/failed
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public double SuccessfulRequestsPerSecond {
+      get { return successfulRequestsPerSecond_; }
+      set {
+        successfulRequestsPerSecond_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "failed_requests_per_second" field.</summary>
+    public const int FailedRequestsPerSecondFieldNumber = 14;
+    private double failedRequestsPerSecond_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public double FailedRequestsPerSecond {
+      get { return failedRequestsPerSecond_; }
+      set {
+        failedRequestsPerSecond_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ScenarioResultSummary);
@@ -3290,6 +3367,9 @@ namespace Grpc.Testing {
       if (Latency95 != other.Latency95) return false;
       if (Latency99 != other.Latency99) return false;
       if (Latency999 != other.Latency999) return false;
+      if (ServerCpuUsage != other.ServerCpuUsage) return false;
+      if (SuccessfulRequestsPerSecond != other.SuccessfulRequestsPerSecond) return false;
+      if (FailedRequestsPerSecond != other.FailedRequestsPerSecond) return false;
       return true;
     }
 
@@ -3307,6 +3387,9 @@ namespace Grpc.Testing {
       if (Latency95 != 0D) hash ^= Latency95.GetHashCode();
       if (Latency99 != 0D) hash ^= Latency99.GetHashCode();
       if (Latency999 != 0D) hash ^= Latency999.GetHashCode();
+      if (ServerCpuUsage != 0D) hash ^= ServerCpuUsage.GetHashCode();
+      if (SuccessfulRequestsPerSecond != 0D) hash ^= SuccessfulRequestsPerSecond.GetHashCode();
+      if (FailedRequestsPerSecond != 0D) hash ^= FailedRequestsPerSecond.GetHashCode();
       return hash;
     }
 
@@ -3361,6 +3444,18 @@ namespace Grpc.Testing {
         output.WriteRawTag(89);
         output.WriteDouble(Latency999);
       }
+      if (ServerCpuUsage != 0D) {
+        output.WriteRawTag(97);
+        output.WriteDouble(ServerCpuUsage);
+      }
+      if (SuccessfulRequestsPerSecond != 0D) {
+        output.WriteRawTag(105);
+        output.WriteDouble(SuccessfulRequestsPerSecond);
+      }
+      if (FailedRequestsPerSecond != 0D) {
+        output.WriteRawTag(113);
+        output.WriteDouble(FailedRequestsPerSecond);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3399,6 +3494,15 @@ namespace Grpc.Testing {
       if (Latency999 != 0D) {
         size += 1 + 8;
       }
+      if (ServerCpuUsage != 0D) {
+        size += 1 + 8;
+      }
+      if (SuccessfulRequestsPerSecond != 0D) {
+        size += 1 + 8;
+      }
+      if (FailedRequestsPerSecond != 0D) {
+        size += 1 + 8;
+      }
       return size;
     }
 
@@ -3440,6 +3544,15 @@ namespace Grpc.Testing {
       if (other.Latency999 != 0D) {
         Latency999 = other.Latency999;
       }
+      if (other.ServerCpuUsage != 0D) {
+        ServerCpuUsage = other.ServerCpuUsage;
+      }
+      if (other.SuccessfulRequestsPerSecond != 0D) {
+        SuccessfulRequestsPerSecond = other.SuccessfulRequestsPerSecond;
+      }
+      if (other.FailedRequestsPerSecond != 0D) {
+        FailedRequestsPerSecond = other.FailedRequestsPerSecond;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3494,6 +3607,18 @@ namespace Grpc.Testing {
             Latency999 = input.ReadDouble();
             break;
           }
+          case 97: {
+            ServerCpuUsage = input.ReadDouble();
+            break;
+          }
+          case 105: {
+            SuccessfulRequestsPerSecond = input.ReadDouble();
+            break;
+          }
+          case 113: {
+            FailedRequestsPerSecond = input.ReadDouble();
+            break;
+          }
         }
       }
     }
@@ -3535,6 +3660,7 @@ namespace Grpc.Testing {
       Summary = other.summary_ != null ? other.Summary.Clone() : null;
       clientSuccess_ = other.clientSuccess_.Clone();
       serverSuccess_ = other.serverSuccess_.Clone();
+      requestResults_ = other.requestResults_.Clone();
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3646,6 +3772,19 @@ namespace Grpc.Testing {
       get { return serverSuccess_; }
     }
 
+    /// <summary>Field number for the "request_results" field.</summary>
+    public const int RequestResultsFieldNumber = 9;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.RequestResultCount> _repeated_requestResults_codec
+        = pb::FieldCodec.ForMessage(74, global::Grpc.Testing.RequestResultCount.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> requestResults_ = new pbc::RepeatedField<global::Grpc.Testing.RequestResultCount>();
+    /// <summary>
+    ///  Number of failed requests (one row per status code seen)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> RequestResults {
+      get { return requestResults_; }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ScenarioResult);
@@ -3667,6 +3806,7 @@ namespace Grpc.Testing {
       if (!object.Equals(Summary, other.Summary)) return false;
       if(!clientSuccess_.Equals(other.clientSuccess_)) return false;
       if(!serverSuccess_.Equals(other.serverSuccess_)) return false;
+      if(!requestResults_.Equals(other.requestResults_)) return false;
       return true;
     }
 
@@ -3681,6 +3821,7 @@ namespace Grpc.Testing {
       if (summary_ != null) hash ^= Summary.GetHashCode();
       hash ^= clientSuccess_.GetHashCode();
       hash ^= serverSuccess_.GetHashCode();
+      hash ^= requestResults_.GetHashCode();
       return hash;
     }
 
@@ -3708,6 +3849,7 @@ namespace Grpc.Testing {
       }
       clientSuccess_.WriteTo(output, _repeated_clientSuccess_codec);
       serverSuccess_.WriteTo(output, _repeated_serverSuccess_codec);
+      requestResults_.WriteTo(output, _repeated_requestResults_codec);
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3727,6 +3869,7 @@ namespace Grpc.Testing {
       }
       size += clientSuccess_.CalculateSize(_repeated_clientSuccess_codec);
       size += serverSuccess_.CalculateSize(_repeated_serverSuccess_codec);
+      size += requestResults_.CalculateSize(_repeated_requestResults_codec);
       return size;
     }
 
@@ -3758,6 +3901,7 @@ namespace Grpc.Testing {
       }
       clientSuccess_.Add(other.clientSuccess_);
       serverSuccess_.Add(other.serverSuccess_);
+      requestResults_.Add(other.requestResults_);
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3812,6 +3956,10 @@ namespace Grpc.Testing {
             serverSuccess_.AddEntriesFrom(input, _repeated_serverSuccess_codec);
             break;
           }
+          case 74: {
+            requestResults_.AddEntriesFrom(input, _repeated_requestResults_codec);
+            break;
+          }
         }
       }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index bcd7e3c040a21caec3e40ecf1e1e2e86688ad6c8..d0bf0afc1d0715043d31bdfe5d137e2f25c49244 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -44,7 +44,7 @@ using System.Threading.Tasks;
 using Grpc.Core;
 
 namespace Grpc.Testing {
-  public static class MetricsService
+  public static partial class MetricsService
   {
     static readonly string __ServiceName = "grpc.testing.MetricsService";
 
@@ -73,7 +73,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Base class for server-side implementations of MetricsService</summary>
-    public abstract class MetricsServiceBase
+    public abstract partial class MetricsServiceBase
     {
       /// <summary>
       ///  Returns the values of all the gauges that are currently being maintained by
@@ -95,7 +95,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Client for MetricsService</summary>
-    public class MetricsServiceClient : ClientBase<MetricsServiceClient>
+    public partial class MetricsServiceClient : ClientBase<MetricsServiceClient>
     {
       /// <summary>Creates a new client for MetricsService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 848dd04fa78cd1f195aa97fb80bd097945179f21..3cc4ed9f3c3a489f642a9dbc906cb95615d83b26 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -40,7 +40,7 @@ using System.Threading.Tasks;
 using Grpc.Core;
 
 namespace Grpc.Testing {
-  public static class BenchmarkService
+  public static partial class BenchmarkService
   {
     static readonly string __ServiceName = "grpc.testing.BenchmarkService";
 
@@ -68,7 +68,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Base class for server-side implementations of BenchmarkService</summary>
-    public abstract class BenchmarkServiceBase
+    public abstract partial class BenchmarkServiceBase
     {
       /// <summary>
       ///  One request followed by one response.
@@ -91,7 +91,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Client for BenchmarkService</summary>
-    public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>
+    public partial class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>
     {
       /// <summary>Creates a new client for BenchmarkService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
@@ -177,7 +177,7 @@ namespace Grpc.Testing {
     }
 
   }
-  public static class WorkerService
+  public static partial class WorkerService
   {
     static readonly string __ServiceName = "grpc.testing.WorkerService";
 
@@ -224,7 +224,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Base class for server-side implementations of WorkerService</summary>
-    public abstract class WorkerServiceBase
+    public abstract partial class WorkerServiceBase
     {
       /// <summary>
       ///  Start server with specified workload.
@@ -271,7 +271,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Client for WorkerService</summary>
-    public class WorkerServiceClient : ClientBase<WorkerServiceClient>
+    public partial class WorkerServiceClient : ClientBase<WorkerServiceClient>
     {
       /// <summary>Creates a new client for WorkerService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs
index 0ae77cfb922f052e5f36ee2893287962c2ef3b41..504aa11d8a7729e112a08bb3c557f69af9dd9b78 100644
--- a/src/csharp/Grpc.IntegrationTesting/Stats.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs
@@ -23,22 +23,27 @@ namespace Grpc.Testing {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
             "CiJzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3N0YXRzLnByb3RvEgxncnBjLnRl",
-            "c3RpbmciSwoLU2VydmVyU3RhdHMSFAoMdGltZV9lbGFwc2VkGAEgASgBEhEK",
-            "CXRpbWVfdXNlchgCIAEoARITCgt0aW1lX3N5c3RlbRgDIAEoASI7Cg9IaXN0",
-            "b2dyYW1QYXJhbXMSEgoKcmVzb2x1dGlvbhgBIAEoARIUCgxtYXhfcG9zc2li",
-            "bGUYAiABKAEidwoNSGlzdG9ncmFtRGF0YRIOCgZidWNrZXQYASADKA0SEAoI",
-            "bWluX3NlZW4YAiABKAESEAoIbWF4X3NlZW4YAyABKAESCwoDc3VtGAQgASgB",
-            "EhYKDnN1bV9vZl9zcXVhcmVzGAUgASgBEg0KBWNvdW50GAYgASgBInsKC0Ns",
-            "aWVudFN0YXRzEi4KCWxhdGVuY2llcxgBIAEoCzIbLmdycGMudGVzdGluZy5I",
-            "aXN0b2dyYW1EYXRhEhQKDHRpbWVfZWxhcHNlZBgCIAEoARIRCgl0aW1lX3Vz",
-            "ZXIYAyABKAESEwoLdGltZV9zeXN0ZW0YBCABKAFiBnByb3RvMw=="));
+            "c3RpbmciegoLU2VydmVyU3RhdHMSFAoMdGltZV9lbGFwc2VkGAEgASgBEhEK",
+            "CXRpbWVfdXNlchgCIAEoARITCgt0aW1lX3N5c3RlbRgDIAEoARIWCg50b3Rh",
+            "bF9jcHVfdGltZRgEIAEoBBIVCg1pZGxlX2NwdV90aW1lGAUgASgEIjsKD0hp",
+            "c3RvZ3JhbVBhcmFtcxISCgpyZXNvbHV0aW9uGAEgASgBEhQKDG1heF9wb3Nz",
+            "aWJsZRgCIAEoASJ3Cg1IaXN0b2dyYW1EYXRhEg4KBmJ1Y2tldBgBIAMoDRIQ",
+            "CghtaW5fc2VlbhgCIAEoARIQCghtYXhfc2VlbhgDIAEoARILCgNzdW0YBCAB",
+            "KAESFgoOc3VtX29mX3NxdWFyZXMYBSABKAESDQoFY291bnQYBiABKAEiOAoS",
+            "UmVxdWVzdFJlc3VsdENvdW50EhMKC3N0YXR1c19jb2RlGAEgASgFEg0KBWNv",
+            "dW50GAIgASgDIrYBCgtDbGllbnRTdGF0cxIuCglsYXRlbmNpZXMYASABKAsy",
+            "Gy5ncnBjLnRlc3RpbmcuSGlzdG9ncmFtRGF0YRIUCgx0aW1lX2VsYXBzZWQY",
+            "AiABKAESEQoJdGltZV91c2VyGAMgASgBEhMKC3RpbWVfc3lzdGVtGAQgASgB",
+            "EjkKD3JlcXVlc3RfcmVzdWx0cxgFIAMoCzIgLmdycGMudGVzdGluZy5SZXF1",
+            "ZXN0UmVzdWx0Q291bnRiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStats), global::Grpc.Testing.ServerStats.Parser, new[]{ "TimeElapsed", "TimeUser", "TimeSystem" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStats), global::Grpc.Testing.ServerStats.Parser, new[]{ "TimeElapsed", "TimeUser", "TimeSystem", "TotalCpuTime", "IdleCpuTime" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.HistogramParams), global::Grpc.Testing.HistogramParams.Parser, new[]{ "Resolution", "MaxPossible" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.HistogramData), global::Grpc.Testing.HistogramData.Parser, new[]{ "Bucket", "MinSeen", "MaxSeen", "Sum", "SumOfSquares", "Count" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStats), global::Grpc.Testing.ClientStats.Parser, new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem" }, null, null, null)
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestResultCount), global::Grpc.Testing.RequestResultCount.Parser, new[]{ "StatusCode", "Count" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStats), global::Grpc.Testing.ClientStats.Parser, new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem", "RequestResults" }, null, null, null)
           }));
     }
     #endregion
@@ -72,6 +77,8 @@ namespace Grpc.Testing {
       timeElapsed_ = other.timeElapsed_;
       timeUser_ = other.timeUser_;
       timeSystem_ = other.timeSystem_;
+      totalCpuTime_ = other.totalCpuTime_;
+      idleCpuTime_ = other.idleCpuTime_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -122,6 +129,34 @@ namespace Grpc.Testing {
       }
     }
 
+    /// <summary>Field number for the "total_cpu_time" field.</summary>
+    public const int TotalCpuTimeFieldNumber = 4;
+    private ulong totalCpuTime_;
+    /// <summary>
+    ///  change in total cpu time of the server (data from proc/stat)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong TotalCpuTime {
+      get { return totalCpuTime_; }
+      set {
+        totalCpuTime_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "idle_cpu_time" field.</summary>
+    public const int IdleCpuTimeFieldNumber = 5;
+    private ulong idleCpuTime_;
+    /// <summary>
+    ///  change in idle time of the server (data from proc/stat)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong IdleCpuTime {
+      get { return idleCpuTime_; }
+      set {
+        idleCpuTime_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ServerStats);
@@ -138,6 +173,8 @@ namespace Grpc.Testing {
       if (TimeElapsed != other.TimeElapsed) return false;
       if (TimeUser != other.TimeUser) return false;
       if (TimeSystem != other.TimeSystem) return false;
+      if (TotalCpuTime != other.TotalCpuTime) return false;
+      if (IdleCpuTime != other.IdleCpuTime) return false;
       return true;
     }
 
@@ -147,6 +184,8 @@ namespace Grpc.Testing {
       if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
       if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
       if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
+      if (TotalCpuTime != 0UL) hash ^= TotalCpuTime.GetHashCode();
+      if (IdleCpuTime != 0UL) hash ^= IdleCpuTime.GetHashCode();
       return hash;
     }
 
@@ -169,6 +208,14 @@ namespace Grpc.Testing {
         output.WriteRawTag(25);
         output.WriteDouble(TimeSystem);
       }
+      if (TotalCpuTime != 0UL) {
+        output.WriteRawTag(32);
+        output.WriteUInt64(TotalCpuTime);
+      }
+      if (IdleCpuTime != 0UL) {
+        output.WriteRawTag(40);
+        output.WriteUInt64(IdleCpuTime);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -183,6 +230,12 @@ namespace Grpc.Testing {
       if (TimeSystem != 0D) {
         size += 1 + 8;
       }
+      if (TotalCpuTime != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(TotalCpuTime);
+      }
+      if (IdleCpuTime != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(IdleCpuTime);
+      }
       return size;
     }
 
@@ -200,6 +253,12 @@ namespace Grpc.Testing {
       if (other.TimeSystem != 0D) {
         TimeSystem = other.TimeSystem;
       }
+      if (other.TotalCpuTime != 0UL) {
+        TotalCpuTime = other.TotalCpuTime;
+      }
+      if (other.IdleCpuTime != 0UL) {
+        IdleCpuTime = other.IdleCpuTime;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -222,6 +281,14 @@ namespace Grpc.Testing {
             TimeSystem = input.ReadDouble();
             break;
           }
+          case 32: {
+            TotalCpuTime = input.ReadUInt64();
+            break;
+          }
+          case 40: {
+            IdleCpuTime = input.ReadUInt64();
+            break;
+          }
         }
       }
     }
@@ -635,6 +702,151 @@ namespace Grpc.Testing {
 
   }
 
+  public sealed partial class RequestResultCount : pb::IMessage<RequestResultCount> {
+    private static readonly pb::MessageParser<RequestResultCount> _parser = new pb::MessageParser<RequestResultCount>(() => new RequestResultCount());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<RequestResultCount> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[3]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RequestResultCount() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RequestResultCount(RequestResultCount other) : this() {
+      statusCode_ = other.statusCode_;
+      count_ = other.count_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RequestResultCount Clone() {
+      return new RequestResultCount(this);
+    }
+
+    /// <summary>Field number for the "status_code" field.</summary>
+    public const int StatusCodeFieldNumber = 1;
+    private int statusCode_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int StatusCode {
+      get { return statusCode_; }
+      set {
+        statusCode_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "count" field.</summary>
+    public const int CountFieldNumber = 2;
+    private long count_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long Count {
+      get { return count_; }
+      set {
+        count_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as RequestResultCount);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(RequestResultCount other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (StatusCode != other.StatusCode) return false;
+      if (Count != other.Count) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (StatusCode != 0) hash ^= StatusCode.GetHashCode();
+      if (Count != 0L) hash ^= Count.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (StatusCode != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(StatusCode);
+      }
+      if (Count != 0L) {
+        output.WriteRawTag(16);
+        output.WriteInt64(Count);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (StatusCode != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(StatusCode);
+      }
+      if (Count != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Count);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(RequestResultCount other) {
+      if (other == null) {
+        return;
+      }
+      if (other.StatusCode != 0) {
+        StatusCode = other.StatusCode;
+      }
+      if (other.Count != 0L) {
+        Count = other.Count;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            StatusCode = input.ReadInt32();
+            break;
+          }
+          case 16: {
+            Count = input.ReadInt64();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   public sealed partial class ClientStats : pb::IMessage<ClientStats> {
     private static readonly pb::MessageParser<ClientStats> _parser = new pb::MessageParser<ClientStats>(() => new ClientStats());
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -642,7 +854,7 @@ namespace Grpc.Testing {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[3]; }
+      get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[4]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -663,6 +875,7 @@ namespace Grpc.Testing {
       timeElapsed_ = other.timeElapsed_;
       timeUser_ = other.timeUser_;
       timeSystem_ = other.timeSystem_;
+      requestResults_ = other.requestResults_.Clone();
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -720,6 +933,19 @@ namespace Grpc.Testing {
       }
     }
 
+    /// <summary>Field number for the "request_results" field.</summary>
+    public const int RequestResultsFieldNumber = 5;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.RequestResultCount> _repeated_requestResults_codec
+        = pb::FieldCodec.ForMessage(42, global::Grpc.Testing.RequestResultCount.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> requestResults_ = new pbc::RepeatedField<global::Grpc.Testing.RequestResultCount>();
+    /// <summary>
+    ///  Number of failed requests (one row per status code seen)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Grpc.Testing.RequestResultCount> RequestResults {
+      get { return requestResults_; }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClientStats);
@@ -737,6 +963,7 @@ namespace Grpc.Testing {
       if (TimeElapsed != other.TimeElapsed) return false;
       if (TimeUser != other.TimeUser) return false;
       if (TimeSystem != other.TimeSystem) return false;
+      if(!requestResults_.Equals(other.requestResults_)) return false;
       return true;
     }
 
@@ -747,6 +974,7 @@ namespace Grpc.Testing {
       if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
       if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
       if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
+      hash ^= requestResults_.GetHashCode();
       return hash;
     }
 
@@ -773,6 +1001,7 @@ namespace Grpc.Testing {
         output.WriteRawTag(33);
         output.WriteDouble(TimeSystem);
       }
+      requestResults_.WriteTo(output, _repeated_requestResults_codec);
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -790,6 +1019,7 @@ namespace Grpc.Testing {
       if (TimeSystem != 0D) {
         size += 1 + 8;
       }
+      size += requestResults_.CalculateSize(_repeated_requestResults_codec);
       return size;
     }
 
@@ -813,6 +1043,7 @@ namespace Grpc.Testing {
       if (other.TimeSystem != 0D) {
         TimeSystem = other.TimeSystem;
       }
+      requestResults_.Add(other.requestResults_);
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -842,6 +1073,10 @@ namespace Grpc.Testing {
             TimeSystem = input.ReadDouble();
             break;
           }
+          case 42: {
+            requestResults_.AddEntriesFrom(input, _repeated_requestResults_codec);
+            break;
+          }
         }
       }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 8d649bf5c521a9edc75cd82c32789d1ff1a56693..43dbc2865f5b6c80933134e13a3cdac5c728edc0 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -45,7 +45,7 @@ namespace Grpc.Testing {
   ///  A simple service to test the various types of RPCs and experiment with
   ///  performance with various types of payload.
   /// </summary>
-  public static class TestService
+  public static partial class TestService
   {
     static readonly string __ServiceName = "grpc.testing.TestService";
 
@@ -120,7 +120,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Base class for server-side implementations of TestService</summary>
-    public abstract class TestServiceBase
+    public abstract partial class TestServiceBase
     {
       /// <summary>
       ///  One empty request followed by one empty response.
@@ -199,7 +199,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Client for TestService</summary>
-    public class TestServiceClient : ClientBase<TestServiceClient>
+    public partial class TestServiceClient : ClientBase<TestServiceClient>
     {
       /// <summary>Creates a new client for TestService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
@@ -441,7 +441,7 @@ namespace Grpc.Testing {
   ///  A simple service NOT implemented at servers so clients can test for
   ///  that case.
   /// </summary>
-  public static class UnimplementedService
+  public static partial class UnimplementedService
   {
     static readonly string __ServiceName = "grpc.testing.UnimplementedService";
 
@@ -461,7 +461,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Base class for server-side implementations of UnimplementedService</summary>
-    public abstract class UnimplementedServiceBase
+    public abstract partial class UnimplementedServiceBase
     {
       /// <summary>
       ///  A call that no server should implement
@@ -474,7 +474,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Client for UnimplementedService</summary>
-    public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>
+    public partial class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>
     {
       /// <summary>Creates a new client for UnimplementedService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
@@ -542,7 +542,7 @@ namespace Grpc.Testing {
   /// <summary>
   ///  A service used to control reconnect server.
   /// </summary>
-  public static class ReconnectService
+  public static partial class ReconnectService
   {
     static readonly string __ServiceName = "grpc.testing.ReconnectService";
 
@@ -571,7 +571,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Base class for server-side implementations of ReconnectService</summary>
-    public abstract class ReconnectServiceBase
+    public abstract partial class ReconnectServiceBase
     {
       public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context)
       {
@@ -586,7 +586,7 @@ namespace Grpc.Testing {
     }
 
     /// <summary>Client for ReconnectService</summary>
-    public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>
+    public partial class ReconnectServiceClient : ClientBase<ReconnectServiceClient>
     {
       /// <summary>Creates a new client for ReconnectService</summary>
       /// <param name="channel">The channel to use to make remote calls.</param>
diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json
index 0225abb4148207381d149ffdd3c4d5a42fb928c9..e47b5953da0431595c3f91046d582a72ef60c64f 100644
--- a/src/csharp/Grpc.IntegrationTesting/project.json
+++ b/src/csharp/Grpc.IntegrationTesting/project.json
@@ -7,7 +7,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -29,7 +28,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
new file mode 100755
index 0000000000000000000000000000000000000000..b0e358fdff97d50eddae55d863059c7b5df30c86
--- /dev/null
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -0,0 +1,79 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem     * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem     * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem     * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+@rem Current package versions
+set VERSION=1.0.1
+set PROTOBUF_VERSION=3.0.0
+
+@rem Adjust the location of nuget.exe
+set NUGET=C:\nuget\nuget.exe
+set DOTNET=C:\dotnet\dotnet.exe
+
+set -ex
+
+mkdir -p ..\..\artifacts\
+
+@rem Collect the artifacts built by the previous build step if running on Jenkins
+@rem TODO(jtattermusch): is there a better way to do this?
+xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* nativelibs\windows_x86\
+xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* nativelibs\windows_x64\
+xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* nativelibs\linux_x86\
+xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* nativelibs\linux_x64\
+xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* nativelibs\macosx_x86\
+xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* nativelibs\macosx_x64\
+
+@rem Collect protoc artifacts built by the previous build step
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x64\
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x64\
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64\
+
+%DOTNET% restore . || goto :error
+
+%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
+
+%NUGET% pack Grpc.nuspec -Version "1.0.1" -OutputDirectory ..\..\artifacts || goto :error
+%NUGET% pack Grpc.Tools.nuspec -Version "1.0.1" -OutputDirectory ..\..\artifacts 
+
+@rem copy resulting nuget packages to artifacts directory
+xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error
+
+@rem create a zipfile with the artifacts as well
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_windows_dotnetcli.zip');"
+xcopy /Y /I csharp_nugets_windows_dotnetcli.zip ..\..\artifacts\ || goto :error
+
+goto :EOF
+
+:error
+echo Failed!
+exit /b %errorlevel%
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 526bd9e14fa350698dad6a4f5e3ed372271a6727..4e4062bafce150379e7a2d436549829ae606796d 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -927,10 +927,16 @@ class Server(six.with_metaclass(abc.ABCMeta)):
     passed in a previous call will not have the effect of stopping the server
     later.
 
+    This method does not block for any significant length of time. If None is
+    passed as the grace value, existing RPCs are immediately aborted and this
+    method blocks until this Server is completely stopped.
+
     Args:
-      grace: A duration of time in seconds to allow existing RPCs to complete
-        before being aborted by this Server's stopping. If None, this method
-        will block until the server is completely stopped.
+      grace: A duration of time in seconds or None. If a duration of time in
+        seconds, the time to allow existing RPCs to complete before being
+        aborted by this Server's stopping. If None, all RPCs will be aborted
+        immediately and this method will block until this Server is completely
+        stopped.
 
     Returns:
       A threading.Event that will be set when this Server has completely
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 57f99c8ce6926fb5b68296cfd675de0ce4864bd8..00e0db71bed66fc6876b7c3a0d5a6ee53f3e81e8 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -31,10 +31,133 @@ require_relative '../grpc'
 require_relative 'active_call'
 require_relative 'service'
 require 'thread'
-require 'concurrent'
 
 # GRPC contains the General RPC module.
 module GRPC
+  # Pool is a simple thread pool.
+  class Pool
+    # Default keep alive period is 1s
+    DEFAULT_KEEP_ALIVE = 1
+
+    def initialize(size, keep_alive: DEFAULT_KEEP_ALIVE)
+      fail 'pool size must be positive' unless size > 0
+      @jobs = Queue.new
+      @size = size
+      @stopped = false
+      @stop_mutex = Mutex.new # needs to be held when accessing @stopped
+      @stop_cond = ConditionVariable.new
+      @workers = []
+      @keep_alive = keep_alive
+
+      # Each worker thread has its own queue to push and pull jobs
+      # these queues are put into @ready_queues when that worker is idle
+      @ready_workers = Queue.new
+    end
+
+    # Returns the number of jobs waiting
+    def jobs_waiting
+      @jobs.size
+    end
+
+    def ready_for_work?
+      # Busy worker threads are either doing work, or have a single job
+      # waiting on them. Workers that are idle with no jobs waiting
+      # have their "queues" in @ready_workers
+      !@ready_workers.empty?
+    end
+
+    # Runs the given block on the queue with the provided args.
+    #
+    # @param args the args passed blk when it is called
+    # @param blk the block to call
+    def schedule(*args, &blk)
+      return if blk.nil?
+      @stop_mutex.synchronize do
+        if @stopped
+          GRPC.logger.warn('did not schedule job, already stopped')
+          return
+        end
+        GRPC.logger.info('schedule another job')
+        fail 'No worker threads available' if @ready_workers.empty?
+        worker_queue = @ready_workers.pop
+
+        fail 'worker already has a task waiting' unless worker_queue.empty?
+        worker_queue << [blk, args]
+      end
+    end
+
+    # Starts running the jobs in the thread pool.
+    def start
+      @stop_mutex.synchronize do
+        fail 'already stopped' if @stopped
+      end
+      until @workers.size == @size.to_i
+        new_worker_queue = Queue.new
+        @ready_workers << new_worker_queue
+        next_thread = Thread.new(new_worker_queue) do |jobs|
+          catch(:exit) do  # allows { throw :exit } to kill a thread
+            loop_execute_jobs(jobs)
+          end
+          remove_current_thread
+        end
+        @workers << next_thread
+      end
+    end
+
+    # Stops the jobs in the pool
+    def stop
+      GRPC.logger.info('stopping, will wait for all the workers to exit')
+      schedule { throw :exit } while ready_for_work?
+      @stop_mutex.synchronize do  # wait @keep_alive for works to stop
+        @stopped = true
+        @stop_cond.wait(@stop_mutex, @keep_alive) if @workers.size > 0
+      end
+      forcibly_stop_workers
+      GRPC.logger.info('stopped, all workers are shutdown')
+    end
+
+    protected
+
+    # Forcibly shutdown any threads that are still alive.
+    def forcibly_stop_workers
+      return unless @workers.size > 0
+      GRPC.logger.info("forcibly terminating #{@workers.size} worker(s)")
+      @workers.each do |t|
+        next unless t.alive?
+        begin
+          t.exit
+        rescue StandardError => e
+          GRPC.logger.warn('error while terminating a worker')
+          GRPC.logger.warn(e)
+        end
+      end
+    end
+
+    # removes the threads from workers, and signal when all the
+    # threads are complete.
+    def remove_current_thread
+      @stop_mutex.synchronize do
+        @workers.delete(Thread.current)
+        @stop_cond.signal if @workers.size.zero?
+      end
+    end
+
+    def loop_execute_jobs(worker_queue)
+      loop do
+        begin
+          blk, args = worker_queue.pop
+          blk.call(*args)
+        rescue StandardError => e
+          GRPC.logger.warn('Error in worker thread')
+          GRPC.logger.warn(e)
+        end
+        # there shouldn't be any work given to this thread while its busy
+        fail('received a task while busy') unless worker_queue.empty?
+        @ready_workers << worker_queue
+      end
+    end
+  end
+
   # RpcServer hosts a number of services and makes them available on the
   # network.
   class RpcServer
@@ -44,17 +167,13 @@ module GRPC
 
     def_delegators :@server, :add_http2_port
 
-    # Default max size of the thread pool size is 100
-    DEFAULT_MAX_POOL_SIZE = 100
-
-    # Default minimum size of the thread pool is 5
-    DEFAULT_MIN_POOL_SIZE = 5
+    # Default thread pool size is 30
+    DEFAULT_POOL_SIZE = 30
 
-    # Default max_waiting_requests size is 60
-    DEFAULT_MAX_WAITING_REQUESTS = 60
+    # Deprecated due to internal changes to the thread pool
+    DEFAULT_MAX_WAITING_REQUESTS = 20
 
     # Default poll period is 1s
-    # Used for grpc server shutdown and thread pool shutdown timeouts
     DEFAULT_POLL_PERIOD = 1
 
     # Signal check period is 0.25s
@@ -75,12 +194,12 @@ module GRPC
     # There are some specific keyword args used to configure the RpcServer
     # instance.
     #
-    # * pool_size: the maximum size of the thread pool that the server's
-    # thread pool can reach.
+    # * pool_size: the size of the thread pool the server uses to run its
+    # threads. No more concurrent requests can be made than the size
+    # of the thread pool
     #
-    # * max_waiting_requests: the maximum number of requests that are not
-    # being handled to allow. When this limit is exceeded, the server responds
-    # with not available to new requests
+    # * max_waiting_requests: Deprecated due to internal changes to the thread
+    # pool. This is still an argument for compatibility but is ignored.
     #
     # * poll_period: when present, the server polls for new events with this
     # period
@@ -92,8 +211,7 @@ module GRPC
     #
     # * server_args:
     # A server arguments hash to be passed down to the underlying core server
-    def initialize(pool_size:DEFAULT_MAX_POOL_SIZE,
-                   min_pool_size:DEFAULT_MIN_POOL_SIZE,
+    def initialize(pool_size:DEFAULT_POOL_SIZE,
                    max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
                    poll_period:DEFAULT_POLL_PERIOD,
                    connect_md_proc:nil,
@@ -101,12 +219,8 @@ module GRPC
       @connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc)
       @max_waiting_requests = max_waiting_requests
       @poll_period = poll_period
-
-      @pool = Concurrent::ThreadPoolExecutor.new(
-        min_threads: [min_pool_size, pool_size].min,
-        max_threads: pool_size,
-        max_queue: max_waiting_requests,
-        fallback_policy: :discard)
+      @pool_size = pool_size
+      @pool = Pool.new(@pool_size)
       @run_cond = ConditionVariable.new
       @run_mutex = Mutex.new
       # running_state can take 4 values: :not_started, :running, :stopping, and
@@ -127,8 +241,7 @@ module GRPC
       end
       deadline = from_relative_time(@poll_period)
       @server.close(deadline)
-      @pool.shutdown
-      @pool.wait_for_termination(@poll_period)
+      @pool.stop
     end
 
     def running_state
@@ -225,6 +338,7 @@ module GRPC
     def run
       @run_mutex.synchronize do
         fail 'cannot run without registering services' if rpc_descs.size.zero?
+        @pool.start
         @server.start
         transition_running_state(:running)
         @run_cond.broadcast
@@ -236,12 +350,8 @@ module GRPC
 
     # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs
     def available?(an_rpc)
-      jobs_count, max = @pool.queue_length, @pool.max_queue
-      GRPC.logger.info("waiting: #{jobs_count}, max: #{max}")
-
-      # remaining capacity for ThreadPoolExecutors is -1 if unbounded
-      return an_rpc if @pool.remaining_capacity != 0
-      GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
+      return an_rpc if @pool.ready_for_work?
+      GRPC.logger.warn('no free worker threads currently')
       noop = proc { |x| x }
 
       # Create a new active call that knows that metadata hasn't been
@@ -276,7 +386,7 @@ module GRPC
           break if (!an_rpc.nil?) && an_rpc.call.nil?
           active_call = new_active_server_call(an_rpc)
           unless active_call.nil?
-            @pool.post(active_call) do |ac|
+            @pool.schedule(active_call) do |ac|
               c, mth = ac
               begin
                 rpc_descs[mth].run_server_method(c, rpc_handlers[mth])
diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..48ccaee510156e69688a85c817f63db8a027c998
--- /dev/null
+++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb
@@ -0,0 +1,144 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+require 'grpc'
+
+Thread.abort_on_exception = true
+
+describe GRPC::Pool do
+  Pool = GRPC::Pool
+
+  describe '#new' do
+    it 'raises if a non-positive size is used' do
+      expect { Pool.new(0) }.to raise_error
+      expect { Pool.new(-1) }.to raise_error
+      expect { Pool.new(Object.new) }.to raise_error
+    end
+
+    it 'is constructed OK with a positive size' do
+      expect { Pool.new(1) }.not_to raise_error
+    end
+  end
+
+  describe '#ready_for_work?' do
+    it 'before start it is not ready' do
+      p = Pool.new(1)
+      expect(p.ready_for_work?).to be(false)
+    end
+
+    it 'it stops being ready after all workers jobs waiting or running' do
+      p = Pool.new(5)
+      p.start
+      job = proc { sleep(3) } # sleep so workers busy when done scheduling
+      5.times do
+        expect(p.ready_for_work?).to be(true)
+        p.schedule(&job)
+      end
+      expect(p.ready_for_work?).to be(false)
+    end
+
+    it 'it becomes ready again after jobs complete' do
+      p = Pool.new(5)
+      p.start
+      job = proc {}
+      5.times do
+        expect(p.ready_for_work?).to be(true)
+        p.schedule(&job)
+      end
+      expect(p.ready_for_work?).to be(false)
+      sleep 5 # give the pool time do get at least one task done
+      expect(p.ready_for_work?).to be(true)
+    end
+  end
+
+  describe '#schedule' do
+    it 'return if the pool is already stopped' do
+      p = Pool.new(1)
+      p.stop
+      job = proc {}
+      expect { p.schedule(&job) }.to_not raise_error
+    end
+
+    it 'adds jobs that get run by the pool' do
+      p = Pool.new(1)
+      p.start
+      o, q = Object.new, Queue.new
+      job = proc { q.push(o) }
+      p.schedule(&job)
+      expect(q.pop).to be(o)
+      p.stop
+    end
+
+    it 'it throws an error if all of the workers have tasks to do' do
+      p = Pool.new(5)
+      p.start
+      job = proc {}
+      5.times do
+        expect(p.ready_for_work?).to be(true)
+        p.schedule(&job)
+      end
+      expect { p.schedule(&job) }.to raise_error
+      expect { p.schedule(&job) }.to raise_error
+    end
+  end
+
+  describe '#stop' do
+    it 'works when there are no scheduled tasks' do
+      p = Pool.new(1)
+      expect { p.stop }.not_to raise_error
+    end
+
+    it 'stops jobs when there are long running jobs' do
+      p = Pool.new(1)
+      p.start
+      o, q = Object.new, Queue.new
+      job = proc do
+        sleep(5)  # long running
+        q.push(o)
+      end
+      p.schedule(&job)
+      sleep(1)  # should ensure the long job gets scheduled
+      expect { p.stop }.not_to raise_error
+    end
+  end
+
+  describe '#start' do
+    it 'runs jobs as they are scheduled' do
+      p = Pool.new(5)
+      o, q = Object.new, Queue.new
+      p.start
+      n = 5  # arbitrary
+      n.times do
+        p.schedule(o, &q.method(:push))
+        expect(q.pop).to be(o)
+      end
+      p.stop
+    end
+  end
+end
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index d80248c623a0dd7cb8d8013e3c0ba63f4b0f4e65..62d61b75c1df74fbbdfa7ad58f2c44c6d77b1c9e 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -31,7 +31,6 @@
 
     s.add_dependency 'google-protobuf', '~> 3.0.2'
     s.add_dependency 'googleauth',      '~> 0.5.1'
-    s.add_dependency 'concurrent-ruby'
 
     s.add_development_dependency 'bundler',            '~> 1.9'
     s.add_development_dependency 'facter',             '~> 2.4'
diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template
index 939a0c8d280b4743947ce518b13bf40436862fbd..8bcac1ac74092fe2b2d71dfcd487259ae8899301 100644
--- a/templates/src/csharp/Grpc.Auth/project.json.template
+++ b/templates/src/csharp/Grpc.Auth/project.json.template
@@ -17,7 +17,6 @@
     "buildOptions": {
       "define": [ "SIGNED" ],
       "keyFile": "../keys/Grpc.snk",
-      "publicSign": true,
       "xmlDoc": true,
       "compile": {
         "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template
index f8d3cf490b3790e53ea71ed38f68266a78507ee0..120a9943e30e543a709dbe37e0702279b1653572 100644
--- a/templates/src/csharp/Grpc.Core/project.json.template
+++ b/templates/src/csharp/Grpc.Core/project.json.template
@@ -29,7 +29,6 @@
       "embed": [ "../../../etc/roots.pem" ],
       "define": [ "SIGNED" ],
       "keyFile": "../keys/Grpc.snk",
-      "publicSign": true,
       "xmlDoc": true
     },
     "dependencies": {
diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template
index 46307dda002856e97ad56f4aa06fe69b5e68dd31..cba68940153c16270f5bb02612c4e8db6fea0876 100644
--- a/templates/src/csharp/Grpc.HealthCheck/project.json.template
+++ b/templates/src/csharp/Grpc.HealthCheck/project.json.template
@@ -17,7 +17,6 @@
     "buildOptions": {
       "define": [ "SIGNED" ],
       "keyFile": "../keys/Grpc.snk",
-      "publicSign": true,
       "xmlDoc": true,
       "compile": {
         "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include
index bda2d7607479912b0ca1acb9e9750192300b19e3..9a32b7c6f454876722e31338eeacc8bc0459f719 100644
--- a/templates/src/csharp/build_options.include
+++ b/templates/src/csharp/build_options.include
@@ -10,7 +10,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
@@ -34,7 +33,6 @@
       "buildOptions": {
         "define": [ "SIGNED" ],
         "keyFile": "../keys/Grpc.snk",
-        "publicSign": true,
         "xmlDoc": true,
         "compile": {
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 37ce3b122210f70163b55ba2b7d3f296a711616b..ea63d4542085d7af2730a067eafd77667fddeea4 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -226,18 +226,6 @@ static void test_request(grpc_end2end_test_config config) {
   grpc_call_destroy(s);
   grpc_call_destroy(c);
 
-  const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC);
-  const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
-
-  gpr_mu_lock(&g_mu);
-  GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
-  GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) < 0);
-  GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
-  GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) < 0);
-  // Server latency should always be smaller than client latency.
-  GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
-  gpr_mu_unlock(&g_mu);
-
   cq_verifier_destroy(cqv);
 
   grpc_byte_buffer_destroy(request_payload);
@@ -245,6 +233,24 @@ static void test_request(grpc_end2end_test_config config) {
 
   end_test(&f);
   config.tear_down_data(&f);
+
+  const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC);
+  const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
+
+  // Perform checks after test tear-down
+  // Guards against the case that there's outstanding channel-related work on a
+  // call prior to verification
+  gpr_mu_lock(&g_mu);
+  GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) <= 0);
+  GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) <= 0);
+  // Server latency should always be smaller than client latency, however since
+  // we only calculate latency at destruction time, and that might mean that we
+  // need to wait for outstanding channel-related work, this isn't verifiable
+  // right now (the server MAY hold on to the call for longer than the client).
+  // GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
+  gpr_mu_unlock(&g_mu);
 }
 
 /*******************************************************************************
diff --git a/test/core/handshake/client_ssl.c b/test/core/handshake/client_ssl.c
index 44efe4dbacff6bc2a61cdd5dff596e9983a66163..24281e0b418ee43c9aa2cd71d12641a0b89b4f44 100644
--- a/test/core/handshake/client_ssl.c
+++ b/test/core/handshake/client_ssl.c
@@ -211,7 +211,7 @@ static bool client_ssl_test(char *server_alpn_preferred) {
   // and port picking.
   int port = -1;
   int server_socket = -1;
-  int socket_retries = 10;
+  int socket_retries = 30;
   while (server_socket == -1 && socket_retries-- > 0) {
     port = grpc_pick_unused_port_or_die();
     server_socket = create_socket(port);
diff --git a/test/core/iomgr/wakeup_fd_cv_test.c b/test/core/iomgr/wakeup_fd_cv_test.c
index 82452d2157ed939caa671aecdfb705757ad6fbd9..04ae9376ddd71989c2b3808b655bc588b521b4bd 100644
--- a/test/core/iomgr/wakeup_fd_cv_test.c
+++ b/test/core/iomgr/wakeup_fd_cv_test.c
@@ -195,16 +195,15 @@ void test_poll_cv_trigger(void) {
   GPR_ASSERT(pfds[4].revents == 0);
   GPR_ASSERT(pfds[5].revents == 0);
 
-  // Pollin on wakeup fd + socket fd
-  trigger_socket_event();
+  // Pollin on wakeupfd before poll()
   pargs.result = -2;
   gpr_thd_new(&t_id, &background_poll, &pargs, &opt);
   gpr_thd_join(t_id);
 
-  GPR_ASSERT(pargs.result == 2);
+  GPR_ASSERT(pargs.result == 1);
   GPR_ASSERT(pfds[0].revents == 0);
   GPR_ASSERT(pfds[1].revents == POLLIN);
-  GPR_ASSERT(pfds[2].revents == POLLIN);
+  GPR_ASSERT(pfds[2].revents == 0);
   GPR_ASSERT(pfds[3].revents == 0);
   GPR_ASSERT(pfds[4].revents == 0);
   GPR_ASSERT(pfds[5].revents == 0);
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 60537b49469cfb7c2681100f15d4f32684ada530..4a42e4c7021b4610429b708867dd475a6f571c10 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -39,6 +39,7 @@
 
 #include <errno.h>
 #include <netinet/in.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/socket.h>
@@ -50,6 +51,8 @@
 #include <grpc/support/string_util.h>
 
 #include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/support/env.h"
 #include "test/core/util/port_server_client.h"
 
@@ -115,55 +118,68 @@ static void chose_port(int port) {
   chosen_ports[num_chosen_ports - 1] = port;
 }
 
-static int is_port_available(int *port, int is_tcp) {
-  const int proto = is_tcp ? IPPROTO_TCP : 0;
-  const int fd = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, proto);
-  int one = 1;
-  struct sockaddr_in addr;
-  socklen_t alen = sizeof(addr);
-  int actual_port;
-
+static bool is_port_available(int *port, bool is_tcp) {
   GPR_ASSERT(*port >= 0);
   GPR_ASSERT(*port <= 65535);
-  if (fd < 0) {
-    gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno));
-    return 0;
-  }
 
-  /* Reuseaddr lets us start up a server immediately after it exits */
-  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
-    gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno));
-    close(fd);
-    return 0;
-  }
+  /* For a port to be considered available, the kernel must support
+     at least one of (IPv6, IPv4), and the port must be available
+     on each supported family. */
+  bool got_socket = false;
+  for (int is_ipv6 = 1; is_ipv6 >= 0; is_ipv6--) {
+    const int fd =
+        socket(is_ipv6 ? AF_INET6 : AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM,
+               is_tcp ? IPPROTO_TCP : 0);
+    if (fd >= 0) {
+      got_socket = true;
+    } else {
+      continue;
+    }
 
-  /* Try binding to port */
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = INADDR_ANY;
-  addr.sin_port = htons((uint16_t)*port);
-  if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-    gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
-    close(fd);
-    return 0;
-  }
+    /* Reuseaddr lets us start up a server immediately after it exits */
+    const int one = 1;
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
+      gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno));
+      close(fd);
+      return false;
+    }
+
+    /* Try binding to port */
+    grpc_resolved_address addr;
+    if (is_ipv6) {
+      grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
+    } else {
+      grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
+    }
+    if (bind(fd, (struct sockaddr *)addr.addr, (socklen_t)addr.len) < 0) {
+      gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
+      close(fd);
+      return false;
+    }
+
+    /* Get the bound port number */
+    if (getsockname(fd, (struct sockaddr *)addr.addr, (socklen_t *)&addr.len) <
+        0) {
+      gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
+      close(fd);
+      return false;
+    }
+    GPR_ASSERT(addr.len <= sizeof(addr.addr));
+    const int actual_port = grpc_sockaddr_get_port(&addr);
+    GPR_ASSERT(actual_port > 0);
+    if (*port == 0) {
+      *port = actual_port;
+    } else {
+      GPR_ASSERT(*port == actual_port);
+    }
 
-  /* Get the bound port number */
-  if (getsockname(fd, (struct sockaddr *)&addr, &alen) < 0) {
-    gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
     close(fd);
-    return 0;
   }
-  GPR_ASSERT(alen <= sizeof(addr));
-  actual_port = ntohs(addr.sin_port);
-  GPR_ASSERT(actual_port > 0);
-  if (*port == 0) {
-    *port = actual_port;
-  } else {
-    GPR_ASSERT(*port == actual_port);
+  if (!got_socket) {
+    gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno));
+    return false;
   }
-
-  close(fd);
-  return 1;
+  return true;
 }
 
 int grpc_pick_unused_port(void) {
@@ -180,7 +196,7 @@ int grpc_pick_unused_port(void) {
      UDP ports and they are scarcer. */
 
   /* Type of port to first pick in next iteration */
-  int is_tcp = 1;
+  bool is_tcp = true;
   int trial = 0;
 
   char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 479aeda8984ef6257be87be7a47935eba269d972..8e02f41b560826246aa1bda6e81feafd166ac41e 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -33,14 +33,19 @@
 
 #include "test/core/util/test_config.h"
 
-#include <grpc/support/log.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
 
 double g_fixture_slowdown_factor = 1.0;
+double g_poller_slowdown_factor = 1.0;
 
 #if GPR_GETPID_IN_UNISTD_H
 #include <unistd.h>
@@ -274,9 +279,16 @@ static void install_crash_handler() {}
 
 void grpc_test_init(int argc, char **argv) {
   install_crash_handler();
-  gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f total=%f",
+  { /* poll-cv poll strategy runs much more slowly than anything else */
+    char *s = gpr_getenv("GRPC_POLL_STRATEGY");
+    if (s != NULL && 0 == strcmp(s, "poll-cv")) {
+      g_poller_slowdown_factor = 5.0;
+    }
+    gpr_free(s);
+  }
+  gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f poll=%f total=%f",
           (double)GRPC_TEST_SLOWDOWN_MACHINE_FACTOR,
-          (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
+          (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR, g_poller_slowdown_factor,
           (double)GRPC_TEST_SLOWDOWN_FACTOR);
   /* seed rng with pid, so we don't end up with the same random numbers as a
      concurrently running test binary */
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index 76686f1c51b8e49e43a1f444bded88aeccc8b11b..c13fe86a64920b597367004613b5426592c41a9e 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -49,10 +49,11 @@ extern "C" {
 #endif
 
 extern double g_fixture_slowdown_factor;
+extern double g_poller_slowdown_factor;
 
 #define GRPC_TEST_SLOWDOWN_FACTOR                                        \
   (GRPC_TEST_SLOWDOWN_BUILD_FACTOR * GRPC_TEST_SLOWDOWN_MACHINE_FACTOR * \
-   g_fixture_slowdown_factor)
+   g_fixture_slowdown_factor * g_poller_slowdown_factor)
 
 #define GRPC_TIMEOUT_SECONDS_TO_DEADLINE(x)                                  \
   gpr_time_add(                                                              \
diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
index 858ee0a68cd358bf25ea7c534b09d14c6032bd79..46aabc6b3846128d6de8b69599c8dbf614279f8e 100755
--- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh
@@ -37,7 +37,7 @@ set -e
 git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc
 
 # Get all gRPC Go dependencies
-(cd src/google.golang.org/grpc && go get -t .)
+(cd src/google.golang.org/grpc && make deps && make testdeps)
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py
index abbb5fa905a26bb46f65f3f39f2ce488c788f2b0..2802957ff12391c596f2ad144bf1e673288af642 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/package_targets.py
@@ -71,17 +71,28 @@ def create_jobspec(name, cmdline, environ=None, cwd=None, shell=False,
 class CSharpPackage:
   """Builds C# nuget packages."""
 
-  def __init__(self, use_dotnet_cli=False):
+  def __init__(self, linux=False, use_dotnet_cli=True):
+    self.linux = linux
     self.use_dotnet_cli = use_dotnet_cli
-    self.name = 'csharp_package_dotnetcli' if use_dotnet_cli else 'csharp_package'
+
     self.labels = ['package', 'csharp']
+
     if use_dotnet_cli:
-      self.labels += ['linux']
+      if linux:
+        self.name = 'csharp_package_dotnetcli_linux'
+	self.labels += ['linux']
+      else:
+        self.name = 'csharp_package_dotnetcli_windows'
+        self.labels += ['windows']
     else:
-      self.labels += ['windows']
+      # official packages built with dotnet cli rather than nuget pack
+      self.name = 'csharp_package_obsolete'
+      self.labels += ['obsolete']
+
 
   def pre_build_jobspecs(self):
-    if 'windows' in self.labels:
+    # The older, obsolete build uses nuget only instead of dotnet cli
+    if 'obsolete' in self.labels:
       return [create_jobspec('prebuild_%s' % self.name,
                              ['tools\\run_tests\\pre_build_csharp.bat'],
                              shell=True,
@@ -91,11 +102,16 @@ class CSharpPackage:
       return []
 
   def build_jobspec(self):
-    if self.use_dotnet_cli:
+    if self.use_dotnet_cli and self.linux:
       return create_docker_jobspec(
           self.name,
           'tools/dockerfile/test/csharp_coreclr_x64',
           'src/csharp/build_packages_dotnetcli.sh')
+    elif self.use_dotnet_cli:
+      return create_jobspec(self.name,
+                            ['build_packages_dotnetcli.bat'],
+                            cwd='src\\csharp',
+                            shell=True)
     else:
       return create_jobspec(self.name,
                             ['build_packages.bat'],
@@ -177,7 +193,8 @@ class PHPPackage:
 def targets():
   """Gets list of supported targets"""
   return [CSharpPackage(),
-          CSharpPackage(use_dotnet_cli=True),
+          CSharpPackage(linux=True),
+          CSharpPackage(use_dotnet_cli=False),
           NodePackage(),
           RubyPackage(),
           PythonPackage(),
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 6a01bc23c412ab4fe60e340fa19736a4b307ea35..83cfc429f98ade556908df6d724b96ac997f7106 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -64,11 +64,10 @@ _SKIP_SERVER_COMPRESSION = ['server_compressed_unary',
 
 _SKIP_COMPRESSION = _SKIP_CLIENT_COMPRESSION + _SKIP_SERVER_COMPRESSION
 
-_SKIP_ADVANCED_GO = ['custom_metadata',
-                     'unimplemented_method',
-                     'unimplemented_service']
-
-_SKIP_ADVANCED = _SKIP_ADVANCED_GO + ['status_code_and_message']
+_SKIP_ADVANCED = ['status_code_and_message',
+                  'custom_metadata',
+                  'unimplemented_method',
+                  'unimplemented_service']
 
 _TEST_TIMEOUT = 3*60
 
@@ -209,10 +208,10 @@ class GoLanguage:
     return {}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def unimplemented_test_cases_server(self):
-    return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION
+    return _SKIP_COMPRESSION
 
   def __str__(self):
     return 'go'
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index e147cf387de1e64bfd2cc5b351e0fbe28b02cc8a..989bc7eb218c1169eba5ad4b2769d6d32e08915b 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -189,6 +189,7 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS)
                                 labels=['portability'],
                                 extra_args=extra_args,
                                 inner_jobs=inner_jobs)
+
   for compiler in ['gcc4.8', 'gcc5.3',
                    'clang3.5', 'clang3.6', 'clang3.7']:
     test_jobs += _generate_jobs(languages=['c++'],