Merge branch 'master' into testc++ize
diff --git a/examples/php/README.md b/examples/php/README.md
index d30cbda..49703ce 100644
--- a/examples/php/README.md
+++ b/examples/php/README.md
@@ -41,10 +41,11 @@
    $ node greeter_server.js
    ```
 
- - Run the client
+ - Generate proto files and run the client
 
    ```
    $ cd examples/php
+   $ ./greeter_proto_gen.sh
    $ ./run_greeter_client.sh
    ```
 
diff --git a/examples/php/greeter_client.php b/examples/php/greeter_client.php
index 981319a..bb94a08 100644
--- a/examples/php/greeter_client.php
+++ b/examples/php/greeter_client.php
@@ -17,12 +17,14 @@
  *
  */
 
+// php:generate protoc --proto_path=./../protos   --php_out=./   --grpc_out=./ --plugin=protoc-gen-grpc=./../../bins/opt/grpc_php_plugin ./../protos/helloworld.proto
+
 require dirname(__FILE__).'/vendor/autoload.php';
 
-// The following includes are needed when using protobuf 3.1.0
-// and will suppress warnings when using protobuf 3.2.0+
-@include_once dirname(__FILE__).'/helloworld.pb.php';
-@include_once dirname(__FILE__).'/helloworld_grpc_pb.php';
+@include_once dirname(__FILE__).'/Helloworld/GreeterClient.php';
+@include_once dirname(__FILE__).'/Helloworld/HelloReply.php';
+@include_once dirname(__FILE__).'/Helloworld/HelloRequest.php';
+@include_once dirname(__FILE__).'/GPBMetadata/Helloworld.php';
 
 function greet($name)
 {
diff --git a/examples/php/greeter_proto_gen.sh b/examples/php/greeter_proto_gen.sh
new file mode 100755
index 0000000..a0d7b29
--- /dev/null
+++ b/examples/php/greeter_proto_gen.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+protoc --proto_path=./../protos   --php_out=./   --grpc_out=./   --plugin=protoc-gen-grpc=./../../bins/opt/grpc_php_plugin   ./../protos/helloworld.proto
+
diff --git a/examples/php/helloworld.pb.php b/examples/php/helloworld.pb.php
deleted file mode 100644
index 757a4a5..0000000
--- a/examples/php/helloworld.pb.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-# Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: helloworld.proto
-
-namespace Helloworld;
-
-use Google\Protobuf\Internal\DescriptorPool;
-use Google\Protobuf\Internal\GPBType;
-use Google\Protobuf\Internal\RepeatedField;
-use Google\Protobuf\Internal\GPBUtil;
-
-class HelloRequest extends \Google\Protobuf\Internal\Message
-{
-    private $name = '';
-
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    public function setName($var)
-    {
-        GPBUtil::checkString($var, True);
-        $this->name = $var;
-    }
-
-}
-
-class HelloReply extends \Google\Protobuf\Internal\Message
-{
-    private $message = '';
-
-    public function getMessage()
-    {
-        return $this->message;
-    }
-
-    public function setMessage($var)
-    {
-        GPBUtil::checkString($var, True);
-        $this->message = $var;
-    }
-
-}
-
-$pool = DescriptorPool::getGeneratedPool();
-
-$pool->internalAddGeneratedFile(hex2bin(
-    "0ae6010a1068656c6c6f776f726c642e70726f746f120a68656c6c6f776f" .
-    "726c64221c0a0c48656c6c6f52657175657374120c0a046e616d65180120" .
-    "012809221d0a0a48656c6c6f5265706c79120f0a076d6573736167651801" .
-    "2001280932490a0747726565746572123e0a0853617948656c6c6f12182e" .
-    "68656c6c6f776f726c642e48656c6c6f526571756573741a162e68656c6c" .
-    "6f776f726c642e48656c6c6f5265706c79220042360a1b696f2e67727063" .
-    "2e6578616d706c65732e68656c6c6f776f726c64420f48656c6c6f576f72" .
-    "6c6450726f746f5001a20203484c57620670726f746f33"
-));
-
diff --git a/examples/php/helloworld_grpc_pb.php b/examples/php/helloworld_grpc_pb.php
deleted file mode 100644
index ba83ed2..0000000
--- a/examples/php/helloworld_grpc_pb.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-// GENERATED CODE -- DO NOT EDIT!
-
-// Original file comments:
-// Copyright 2015 gRPC authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-namespace Helloworld {
-
-  // The greeting service definition.
-  class GreeterClient extends \Grpc\BaseStub {
-
-    /**
-     * @param string $hostname hostname
-     * @param array $opts channel options
-     * @param Grpc\Channel $channel (optional) re-use channel object
-     */
-    public function __construct($hostname, $opts, $channel = null) {
-      parent::__construct($hostname, $opts, $channel);
-    }
-
-    /**
-     * Sends a greeting
-     * @param \Helloworld\HelloRequest $argument input argument
-     * @param array $metadata metadata
-     * @param array $options call options
-     */
-    public function SayHello(\Helloworld\HelloRequest $argument,
-      $metadata = [], $options = []) {
-      return $this->_simpleRequest('/helloworld.Greeter/SayHello',
-      $argument,
-      ['\Helloworld\HelloReply', 'decode'],
-      $metadata, $options);
-    }
-
-  }
-
-}
diff --git a/examples/php/route_guide/route_guide.pb.php b/examples/php/route_guide/route_guide.pb.php
deleted file mode 100644
index 78f3ea6..0000000
--- a/examples/php/route_guide/route_guide.pb.php
+++ /dev/null
@@ -1,209 +0,0 @@
-<?php
-# Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: route_guide.proto
-
-namespace Routeguide;
-
-use Google\Protobuf\Internal\DescriptorPool;
-use Google\Protobuf\Internal\GPBType;
-use Google\Protobuf\Internal\RepeatedField;
-use Google\Protobuf\Internal\GPBUtil;
-
-class Point extends \Google\Protobuf\Internal\Message
-{
-    private $latitude = 0;
-    private $longitude = 0;
-
-    public function getLatitude()
-    {
-        return $this->latitude;
-    }
-
-    public function setLatitude($var)
-    {
-        GPBUtil::checkInt32($var);
-        $this->latitude = $var;
-    }
-
-    public function getLongitude()
-    {
-        return $this->longitude;
-    }
-
-    public function setLongitude($var)
-    {
-        GPBUtil::checkInt32($var);
-        $this->longitude = $var;
-    }
-
-}
-
-class Rectangle extends \Google\Protobuf\Internal\Message
-{
-    private $lo = null;
-    private $hi = null;
-
-    public function getLo()
-    {
-        return $this->lo;
-    }
-
-    public function setLo(&$var)
-    {
-        GPBUtil::checkMessage($var, \Routeguide\Point::class);
-        $this->lo = $var;
-    }
-
-    public function getHi()
-    {
-        return $this->hi;
-    }
-
-    public function setHi(&$var)
-    {
-        GPBUtil::checkMessage($var, \Routeguide\Point::class);
-        $this->hi = $var;
-    }
-
-}
-
-class Feature extends \Google\Protobuf\Internal\Message
-{
-    private $name = '';
-    private $location = null;
-
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    public function setName($var)
-    {
-        GPBUtil::checkString($var, True);
-        $this->name = $var;
-    }
-
-    public function getLocation()
-    {
-        return $this->location;
-    }
-
-    public function setLocation(&$var)
-    {
-        GPBUtil::checkMessage($var, \Routeguide\Point::class);
-        $this->location = $var;
-    }
-
-}
-
-class RouteNote extends \Google\Protobuf\Internal\Message
-{
-    private $location = null;
-    private $message = '';
-
-    public function getLocation()
-    {
-        return $this->location;
-    }
-
-    public function setLocation(&$var)
-    {
-        GPBUtil::checkMessage($var, \Routeguide\Point::class);
-        $this->location = $var;
-    }
-
-    public function getMessage()
-    {
-        return $this->message;
-    }
-
-    public function setMessage($var)
-    {
-        GPBUtil::checkString($var, True);
-        $this->message = $var;
-    }
-
-}
-
-class RouteSummary extends \Google\Protobuf\Internal\Message
-{
-    private $point_count = 0;
-    private $feature_count = 0;
-    private $distance = 0;
-    private $elapsed_time = 0;
-
-    public function getPointCount()
-    {
-        return $this->point_count;
-    }
-
-    public function setPointCount($var)
-    {
-        GPBUtil::checkInt32($var);
-        $this->point_count = $var;
-    }
-
-    public function getFeatureCount()
-    {
-        return $this->feature_count;
-    }
-
-    public function setFeatureCount($var)
-    {
-        GPBUtil::checkInt32($var);
-        $this->feature_count = $var;
-    }
-
-    public function getDistance()
-    {
-        return $this->distance;
-    }
-
-    public function setDistance($var)
-    {
-        GPBUtil::checkInt32($var);
-        $this->distance = $var;
-    }
-
-    public function getElapsedTime()
-    {
-        return $this->elapsed_time;
-    }
-
-    public function setElapsedTime($var)
-    {
-        GPBUtil::checkInt32($var);
-        $this->elapsed_time = $var;
-    }
-
-}
-
-$pool = DescriptorPool::getGeneratedPool();
-
-$pool->internalAddGeneratedFile(hex2bin(
-    "0ac5050a11726f7574655f67756964652e70726f746f120a726f75746567" .
-    "75696465222c0a05506f696e7412100a086c617469747564651801200128" .
-    "0512110a096c6f6e67697475646518022001280522490a0952656374616e" .
-    "676c65121d0a026c6f18012001280b32112e726f75746567756964652e50" .
-    "6f696e74121d0a02686918022001280b32112e726f75746567756964652e" .
-    "506f696e74223c0a0746656174757265120c0a046e616d65180120012809" .
-    "12230a086c6f636174696f6e18022001280b32112e726f75746567756964" .
-    "652e506f696e7422410a09526f7574654e6f746512230a086c6f63617469" .
-    "6f6e18012001280b32112e726f75746567756964652e506f696e74120f0a" .
-    "076d65737361676518022001280922620a0c526f75746553756d6d617279" .
-    "12130a0b706f696e745f636f756e7418012001280512150a0d6665617475" .
-    "72655f636f756e7418022001280512100a0864697374616e636518032001" .
-    "280512140a0c656c61707365645f74696d651804200128053285020a0a52" .
-    "6f757465477569646512360a0a4765744665617475726512112e726f7574" .
-    "6567756964652e506f696e741a132e726f75746567756964652e46656174" .
-    "7572652200123e0a0c4c697374466561747572657312152e726f75746567" .
-    "756964652e52656374616e676c651a132e726f75746567756964652e4665" .
-    "617475726522003001123e0a0b5265636f7264526f75746512112e726f75" .
-    "746567756964652e506f696e741a182e726f75746567756964652e526f75" .
-    "746553756d6d61727922002801123f0a09526f7574654368617412152e72" .
-    "6f75746567756964652e526f7574654e6f74651a152e726f757465677569" .
-    "64652e526f7574654e6f746522002801300142360a1b696f2e677270632e" .
-    "6578616d706c65732e726f7574656775696465420f526f75746547756964" .
-    "6550726f746f5001a20203525447620670726f746f33"
-));
-
diff --git a/examples/php/route_guide/route_guide_client.php b/examples/php/route_guide/route_guide_client.php
index 8ac7977..92b2bac 100644
--- a/examples/php/route_guide/route_guide_client.php
+++ b/examples/php/route_guide/route_guide_client.php
@@ -17,12 +17,9 @@
  *
  */
 
-require dirname(__FILE__).'/../vendor/autoload.php';
+// php:generate protoc --proto_path=./../../protos  --php_out=./  --grpc_out=./ --plugin=protoc-gen-grpc=./../../../bins/opt/grpc_php_plugin ./../../protos/route_guide.proto
 
-// The following includes are needed when using protobuf 3.1.0
-// and will suppress warnings when using protobuf 3.2.0+
-@include_once dirname(__FILE__).'/route_guide.pb.php';
-@include_once dirname(__FILE__).'/route_guide_grpc_pb.php';
+require dirname(__FILE__).'/../vendor/autoload.php';
 
 define('COORD_FACTOR', 1e7);
 
@@ -38,9 +35,12 @@
     } else {
         $name_str = "feature called $name";
     }
-    echo sprintf("Found %s \n  at %f, %f\n", $name_str,
+    echo sprintf(
+        "Found %s \n  at %f, %f\n",
+        $name_str,
                  $feature->getLocation()->getLatitude() / COORD_FACTOR,
-                 $feature->getLocation()->getLongitude() / COORD_FACTOR);
+                 $feature->getLocation()->getLongitude() / COORD_FACTOR
+    );
 }
 
 /**
@@ -122,19 +122,24 @@
         $feature_name = $db[$index]['name'];
         $point->setLatitude($lat);
         $point->setLongitude($long);
-        echo sprintf("Visiting point %f, %f,\n  with feature name: %s\n",
-                     $lat / COORD_FACTOR, $long / COORD_FACTOR,
-                     $feature_name ? $feature_name : '<empty>');
+        echo sprintf(
+            "Visiting point %f, %f,\n  with feature name: %s\n",
+                     $lat / COORD_FACTOR,
+            $long / COORD_FACTOR,
+                     $feature_name ? $feature_name : '<empty>'
+        );
         usleep(rand(300000, 800000));
         $call->write($point);
     }
     list($route_summary, $status) = $call->wait();
-    echo sprintf("Finished trip with %d points\nPassed %d features\n".
+    echo sprintf(
+        "Finished trip with %d points\nPassed %d features\n".
                  "Travelled %d meters\nIt took %d seconds\n",
                  $route_summary->getPointCount(),
                  $route_summary->getFeatureCount(),
                  $route_summary->getDistance(),
-                 $route_summary->getElapsedTime());
+                 $route_summary->getElapsedTime()
+    );
 }
 
 /**
@@ -166,8 +171,12 @@
         $route_note->setLocation($point);
         $route_note->setMessage($message = $n[2]);
 
-        echo sprintf("Sending message: '%s' at (%d, %d)\n",
-                     $message, $lat, $long);
+        echo sprintf(
+            "Sending message: '%s' at (%d, %d)\n",
+                     $message,
+            $lat,
+            $long
+        );
         // send a bunch of messages to the server
         $call->write($route_note);
     }
@@ -175,10 +184,12 @@
 
     // read from the server until there's no more
     while ($route_note_reply = $call->read()) {
-        echo sprintf("Previous left message at (%d, %d): '%s'\n",
+        echo sprintf(
+            "Previous left message at (%d, %d): '%s'\n",
                      $route_note_reply->getLocation()->getLatitude(),
                      $route_note_reply->getLocation()->getLongitude(),
-                     $route_note_reply->getMessage());
+                     $route_note_reply->getMessage()
+        );
     }
 }
 
diff --git a/examples/php/route_guide/route_guide_grpc_pb.php b/examples/php/route_guide/route_guide_grpc_pb.php
deleted file mode 100644
index e7a9cd3..0000000
--- a/examples/php/route_guide/route_guide_grpc_pb.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-// GENERATED CODE -- DO NOT EDIT!
-
-// Original file comments:
-// Copyright 2015 gRPC authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-namespace Routeguide {
-
-  // Interface exported by the server.
-  class RouteGuideClient extends \Grpc\BaseStub {
-
-    /**
-     * @param string $hostname hostname
-     * @param array $opts channel options
-     * @param Grpc\Channel $channel (optional) re-use channel object
-     */
-    public function __construct($hostname, $opts, $channel = null) {
-      parent::__construct($hostname, $opts, $channel);
-    }
-
-    /**
-     * A simple RPC.
-     *
-     * Obtains the feature at a given position.
-     *
-     * A feature with an empty name is returned if there's no feature at the given
-     * position.
-     * @param \Routeguide\Point $argument input argument
-     * @param array $metadata metadata
-     * @param array $options call options
-     */
-    public function GetFeature(\Routeguide\Point $argument,
-      $metadata = [], $options = []) {
-      return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature',
-      $argument,
-      ['\Routeguide\Feature', 'decode'],
-      $metadata, $options);
-    }
-
-    /**
-     * A server-to-client streaming RPC.
-     *
-     * Obtains the Features available within the given Rectangle.  Results are
-     * streamed rather than returned at once (e.g. in a response message with a
-     * repeated field), as the rectangle may cover a large area and contain a
-     * huge number of features.
-     * @param \Routeguide\Rectangle $argument input argument
-     * @param array $metadata metadata
-     * @param array $options call options
-     */
-    public function ListFeatures(\Routeguide\Rectangle $argument,
-      $metadata = [], $options = []) {
-      return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures',
-      $argument,
-      ['\Routeguide\Feature', 'decode'],
-      $metadata, $options);
-    }
-
-    /**
-     * A client-to-server streaming RPC.
-     *
-     * Accepts a stream of Points on a route being traversed, returning a
-     * RouteSummary when traversal is completed.
-     * @param array $metadata metadata
-     * @param array $options call options
-     */
-    public function RecordRoute($metadata = [], $options = []) {
-      return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute',
-      ['\Routeguide\RouteSummary','decode'],
-      $metadata, $options);
-    }
-
-    /**
-     * A Bidirectional streaming RPC.
-     *
-     * Accepts a stream of RouteNotes sent while a route is being traversed,
-     * while receiving other RouteNotes (e.g. from other users).
-     * @param array $metadata metadata
-     * @param array $options call options
-     */
-    public function RouteChat($metadata = [], $options = []) {
-      return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat',
-      ['\Routeguide\RouteNote','decode'],
-      $metadata, $options);
-    }
-
-  }
-
-}
diff --git a/examples/php/route_guide/route_guide_proto_gen.sh b/examples/php/route_guide/route_guide_proto_gen.sh
new file mode 100755
index 0000000..bfd7cdb
--- /dev/null
+++ b/examples/php/route_guide/route_guide_proto_gen.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+protoc --proto_path=./../../protos  --php_out=./  --grpc_out=./ --plugin=protoc-gen-grpc=./../../../bins/opt/grpc_php_plugin ./../../protos/route_guide.proto
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h
index 170c562..256dd85 100644
--- a/include/grpc++/impl/codegen/client_unary_call.h
+++ b/include/grpc++/impl/codegen/client_unary_call.h
@@ -41,7 +41,7 @@
   return BlockingUnaryCallImpl<InputMessage, OutputMessage>(
              channel, method, context, request, result)
       .status();
-};
+}
 
 template <class InputMessage, class OutputMessage>
 class BlockingUnaryCallImpl {
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index d6c3a3c..b5ab611 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -112,10 +112,13 @@
 
 @synthesize state = _state;
 
-// TODO(jcanizales): If grpc_init is idempotent, this should be changed from load to initialize.
-+ (void)load {
-  grpc_init();
-  callFlags = [NSMutableDictionary dictionary];
++ (void)initialize {
+  // Guarantees the code in {} block is invoked only once. See ref at:
+  // https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=objc
+  if (self == [GRPCCall self]) {
+    grpc_init();
+    callFlags = [NSMutableDictionary dictionary];
+  }
 }
 
 + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path {
diff --git a/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h b/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h
index 6df044f..0763d07 100644
--- a/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h
+++ b/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h
@@ -278,7 +278,7 @@
 
       void* t;
       bool ok;
-      int need_tags;
+      int expect_tags = 0;
 
       // Send 'max_ping_pongs' number of ping pong messages
       int ping_pong_cnt = 0;
@@ -289,7 +289,7 @@
           request_rw->Write(send_request, tag(2));  // Start client send
         }
 
-        need_tags = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5);
+        int await_tags = (1 << 2);
 
         if (ping_pong_cnt == 0) {
           // wait for the server call structure (call_hook, etc.) to be
@@ -301,8 +301,8 @@
             // In some cases tag:2 comes before tag:0 (write tag comes out
             // first), this while loop is to make sure get tag:0.
             int i = (int)(intptr_t)t;
-            GPR_ASSERT(need_tags & (1 << i));
-            need_tags &= ~(1 << i);
+            GPR_ASSERT(await_tags & (1 << i));
+            await_tags &= ~(1 << i);
             GPR_ASSERT(fixture->cq()->Next(&t, &ok));
           }
         }
@@ -310,7 +310,11 @@
         response_rw.Read(&recv_request, tag(3));   // Start server recv
         request_rw->Read(&recv_response, tag(4));  // Start client recv
 
-        while (need_tags) {
+        await_tags |= (1 << 3) | (1 << 4);
+        expect_tags = await_tags;
+        await_tags |= (1 << 5);
+
+        while (await_tags != 0) {
           GPR_ASSERT(fixture->cq()->Next(&t, &ok));
           GPR_ASSERT(ok);
           int i = (int)(intptr_t)t;
@@ -321,34 +325,39 @@
               if (write_and_finish == 1) {
                 response_rw.WriteAndFinish(send_response, WriteOptions(),
                                            Status::OK, tag(5));
+                expect_tags |= (1 << 5);
               } else {
                 response_rw.WriteLast(send_response, WriteOptions(), tag(5));
-                // WriteLast buffers the write, so neither server write op nor
-                // client read op will finish inside the while loop.
-                need_tags &= ~(1 << 4);
-                need_tags &= ~(1 << 5);
+                // WriteLast buffers the write, so it's possible neither server
+                // write op nor client read op will finish inside the while
+                // loop.
+                await_tags &= ~(1 << 4);
+                await_tags &= ~(1 << 5);
+                expect_tags |= (1 << 5);
               }
             } else {
               response_rw.Write(send_response, tag(5));
+              expect_tags |= (1 << 5);
             }
           }
 
-          GPR_ASSERT(need_tags & (1 << i));
-          need_tags &= ~(1 << i);
+          GPR_ASSERT(expect_tags & (1 << i));
+          expect_tags &= ~(1 << i);
+          await_tags &= ~(1 << i);
         }
 
         ping_pong_cnt++;
       }
 
       if (max_ping_pongs == 0) {
-        need_tags = (1 << 6) | (1 << 7) | (1 << 8);
+        expect_tags |= (1 << 6) | (1 << 7) | (1 << 8);
       } else {
         if (write_and_finish == 1) {
-          need_tags = (1 << 8);
+          expect_tags |= (1 << 8);
         } else {
           // server's buffered write and the client's read of the buffered write
           // tags should come up.
-          need_tags = (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8);
+          expect_tags |= (1 << 7) | (1 << 8);
         }
       }
 
@@ -360,8 +369,8 @@
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
         while ((int)(intptr_t)t != 0) {
           int i = (int)(intptr_t)t;
-          GPR_ASSERT(need_tags & (1 << i));
-          need_tags &= ~(1 << i);
+          GPR_ASSERT(expect_tags & (1 << i));
+          expect_tags &= ~(1 << i);
           GPR_ASSERT(fixture->cq()->Next(&t, &ok));
         }
         response_rw.Finish(Status::OK, tag(7));
@@ -374,11 +383,11 @@
       Status recv_status;
       request_rw->Finish(&recv_status, tag(8));
 
-      while (need_tags) {
+      while (expect_tags) {
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
         int i = (int)(intptr_t)t;
-        GPR_ASSERT(need_tags & (1 << i));
-        need_tags &= ~(1 << i);
+        GPR_ASSERT(expect_tags & (1 << i));
+        expect_tags &= ~(1 << i);
       }
 
       GPR_ASSERT(recv_status.ok());
diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD
index 978e9b1..8cc01b6 100644
--- a/third_party/cares/cares.BUILD
+++ b/third_party/cares/cares.BUILD
@@ -3,6 +3,34 @@
     values = {"cpu": "darwin"},
 )
 
+# Android is not officially supported through C++.
+# This just helps with the build for now.
+config_setting(
+    name = "android",
+    values = {
+      "crosstool_top": "//external:android/crosstool",
+    },
+)
+
+# iOS is not officially supported through C++.
+# This just helps with the build for now.
+config_setting(
+    name = "ios_x86_64",
+    values = {"cpu": "ios_x86_64"},
+)
+config_setting(
+    name = "ios_armv7",
+    values = {"cpu": "ios_armv7"},
+)
+config_setting(
+    name = "ios_armv7s",
+    values = {"cpu": "ios_armv7s"},
+)
+config_setting(
+    name = "ios_arm64",
+    values = {"cpu": "ios_arm64"},
+)
+
 cc_library(
     name = "ares",
     srcs = [
@@ -81,14 +109,24 @@
         "cares/nameser.h",
         "cares/setup_once.h",
     ] + select({
+        ":ios_x86_64": ["config_darwin/ares_config.h"],
+        ":ios_armv7": ["config_darwin/ares_config.h"],
+        ":ios_armv7s": ["config_darwin/ares_config.h"],
+        ":ios_arm64": ["config_darwin/ares_config.h"],
         ":darwin": ["config_darwin/ares_config.h"],
+        ":android": ["config_android/ares_config.h"],
         "//conditions:default": ["config_linux/ares_config.h"],
     }),
     includes = [
         ".",
         "cares"
     ] + select({
+        ":ios_x86_64": ["config_darwin"],
+        ":ios_armv7": ["config_darwin"],
+        ":ios_armv7s": ["config_darwin"],
+        ":ios_arm64": ["config_darwin"],
         ":darwin": ["config_darwin"],
+        ":android": ["config_android"],
         "//conditions:default": ["config_linux"],
     }),
     linkstatic = 1,
diff --git a/third_party/cares/config_android/ares_config.h b/third_party/cares/config_android/ares_config.h
new file mode 100644
index 0000000..2caf1b3
--- /dev/null
+++ b/third_party/cares/config_android/ares_config.h
@@ -0,0 +1,458 @@
+/* Generated from ares_config.h.cmake*/
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* define this if ares is built for a big endian system */
+#undef ARES_BIG_ENDIAN
+
+/* when building as static part of libcurl */
+#undef BUILDING_LIBCURL
+
+/* Defined for build that exposes internal static functions for testing. */
+#undef CARES_EXPOSE_STATICS
+
+/* Defined for build with symbol hiding. */
+#undef CARES_SYMBOL_HIDING
+
+/* Definition to make a library symbol externally visible. */
+#undef CARES_SYMBOL_SCOPE_EXTERN
+
+/* Use resolver library to configure cares */
+/* #undef CARES_USE_LIBRESOLV */
+
+/* if a /etc/inet dir is being used */
+#undef ETC_INET
+
+/* Define to the type of arg 2 for gethostname. */
+#define GETHOSTNAME_TYPE_ARG2 size_t
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 socklen_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS
+
+/* Define to 1 if you have AF_INET6. */
+#define HAVE_AF_INET6
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+#define HAVE_ARPA_NAMESER_COMPAT_H
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H
+
+/* Define to 1 if you have the `bitncmp' function. */
+/* #undef HAVE_BITNCMP */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T
+
+/* Define HAVE_CLOCK_GETTIME_MONOTONIC if you have the clock_gettime
+ * function and monotonic timer.
+ *
+ * IMPORTANT: gRPC MANUAL EDIT HERE!
+ * Note: setting HAVE_CLOCK_GETTIME_MONOTONIC causes use of the clock_gettime
+ * function from glibc, don't set it to support glibc < 2.17 */
+#ifndef GPR_BACKWARDS_COMPATIBILITY_MODE
+  #define HAVE_CLOCK_GETTIME_MONOTONIC
+#endif
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+#define HAVE_CONNECT
+
+/* define if the compiler supports basic C++11 syntax */
+/* #undef HAVE_CXX11 */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+/* #undef HAVE_GETADDRINFO_THREADSAFE */
+
+/* Define to 1 if you have the getenv function. */
+#define HAVE_GETENV
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO
+
+/* Define to 1 if you have the getservbyport_r function. */
+/* #undef HAVE_GETSERVBYPORT_R */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#define HAVE_IF_INDEXTONAME
+
+/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */
+/* #undef HAVE_INET_NET_PTON */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#define HAVE_INET_NTOP
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#define HAVE_INET_PTON
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H
+
+/* if your compiler supports LL */
+#define HAVE_LL
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#define HAVE_MSG_NOSIGNAL
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H
+
+/* Define to 1 if you have PF_INET6. */
+#define HAVE_PF_INET6
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#define HAVE_STROPTS_H
+
+/* Define to 1 if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO
+
+/* Define to 1 if you have struct in6_addr. */
+#define HAVE_STRUCT_IN6_ADDR
+
+/* Define to 1 if you have struct sockaddr_in6. */
+#define HAVE_STRUCT_SOCKADDR_IN6
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* a suitable file/device to read random data from */
+/* #undef RANDOM_FILE */
+
+/* Define to the type qualifier pointed by arg 5 for recvfrom. */
+#define RECVFROM_QUAL_ARG5 
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void *
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 0
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr *
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG5_IS_VOID 0
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t *
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG6_IS_VOID 0
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE 
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME
+
+/* Define to disable non-blocking sockets. */
+#undef USE_BLOCKING_SOCKETS
+
+/* Define to avoid automatic inclusion of winsock.h */
+#undef WIN32_LEAN_AND_MEAN
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+#undef in_addr_t
+
+#ifdef GPR_BACKWARDS_COMPATIBILITY_MODE
+  /* IMPORTANT: gRPC MANUAL EDIT HERE!
+   * Redefine the fd_set macros for GLIBC < 2.15 support.
+   * This is a backwards compatibility hack. At version 2.15, GLIBC introduces
+   * the __fdelt_chk function, and starts using it within its fd_set macros
+   * (which c-ares uses). For compatibility with GLIBC < 2.15, we need to redefine
+   * the fd_set macros to not use __fdelt_chk. */
+  #include <sys/select.h>
+  #undef FD_SET
+  #undef FD_CLR
+  #undef FD_ISSET
+  /* 'FD_ZERO' doesn't use __fdelt_chk, no need to redefine. */
+
+  #ifdef __FDS_BITS
+    #define GRPC_CARES_FDS_BITS(set) __FDS_BITS(set)
+  #else
+    #define GRPC_CARES_FDS_BITS(set) ((set)->fds_bits)
+  #endif
+
+  #define GRPC_CARES_FD_MASK(d) ((long int)(1UL << (d) % NFDBITS))
+
+  #define FD_SET(d, set) \
+      ((void) (GRPC_CARES_FDS_BITS (set)[ (d) / NFDBITS ] |= GRPC_CARES_FD_MASK(d)))
+  #define FD_CLR(d, set) \
+      ((void) (GRPC_CARES_FDS_BITS (set)[ (d) / NFDBITS ] &= ~GRPC_CARES_FD_MASK(d)))
+  #define FD_ISSET(d, set) \
+      ((GRPC_CARES_FDS_BITS (set)[ (d) / NFDBITS ] & GRPC_CARES_FD_MASK(d)) != 0)
+#endif /* GPR_BACKWARDS_COMPATIBILITY_MODE */
diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md
index a3717a5..588afe4 100644
--- a/tools/interop_matrix/README.md
+++ b/tools/interop_matrix/README.md
@@ -24,7 +24,7 @@
 - Create new `Dockerfile.template`, `build_interop.sh.template` for the language/runtime under `template/tools/dockerfile/`.
 - Run `tools/buildgen/generate_projects.sh` to create corresponding files under `tools/dockerfile/`.
 - Add language/runtimes to `client_matrix.py` following existing language/runtimes examples.
-- Run `tools/interop_matrix/create_matrix_images.py` which will build and upload images to GCR.  Unless you are also building images for a gRPC release, make sure not to set `--gcr_tag` (the default tag 'master' is used for testing).
+- Run `tools/interop_matrix/create_matrix_images.py` which will build and upload images to GCR.  Unless you are also building images for a gRPC release, make sure not to set `--release` (the default release 'master' is used for testing).
 
 *: Please delete your docker images at https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing afterwards.  Permissions to access GrpcTesting project is required for this step.
 
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index 23c5ae0..51f04ea 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -27,6 +27,11 @@
     'cxx': ['cxx'],             # This is actually debian8.
     'go': ['go1.7', 'go1.8'],
     'java': ['java_oracle8'],
+    'python': ['python'],
+    'node': ['node'],
+    'ruby': ['ruby'],
+    'php': ['php', 'php7'],
+    'csharp': ['csharp', 'csharpcoreclr'],
 }
 
 # Dictionary of releases per language.  For each language, we need to provide
@@ -59,4 +64,45 @@
         'v1.6.1',
         'v1.7.0',
     ],
+    'python': [
+        #'v1.0.x',  #Fail to run the test. #13230.
+        'v1.1.4',
+        'v1.2.5',
+        'v1.3.9',
+        'v1.4.2',
+        'v1.6.6',
+    ],
+    'node': [
+        'v1.0.1',
+        'v1.1.4',
+        'v1.2.5',
+        'v1.3.9',
+        'v1.4.2',
+        'v1.6.6',
+    ],
+    'ruby': [
+        # Ruby v1.0.x doesn't have the fix #8914, therefore not supported.
+        'v1.1.4',
+        'v1.2.5',
+        'v1.3.9',
+        'v1.4.2',
+        'v1.6.6',
+    ],
+    'php': [
+        'v1.0.1',
+        'v1.1.4',
+        'v1.2.5',
+        'v1.3.9',
+        'v1.4.2',
+        'v1.6.6',
+    ],
+   'csharp': [
+        # Fail to build images due to #13278.
+        #'v1.0.1',
+        #'v1.1.4',
+        #'v1.2.5',
+        #'v1.3.9',
+        'v1.4.2',
+        'v1.6.6',
+    ],
 }
diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py
index 67355e7..21040ea 100755
--- a/tools/interop_matrix/create_matrix_images.py
+++ b/tools/interop_matrix/create_matrix_images.py
@@ -116,12 +116,13 @@
   subprocess.check_output(build_cmd)
   dockerjob.remove_image(orig_tag, skip_nonexistent=True)
 
-def build_image_jobspec(runtime, env, gcr_tag):
+def build_image_jobspec(runtime, env, gcr_tag, stack_base):
   """Build interop docker image for a language with runtime.
 
   runtime: a <lang><version> string, for example go1.8.
   env:     dictionary of env to passed to the build script.
   gcr_tag: the tag for the docker image (i.e. v1.3.0).
+  stack_base: the local gRPC repo path.
   """
   basename = 'grpc_interop_%s' % runtime
   tag = '%s/%s:%s' % (args.gcr_path, basename, gcr_tag)
@@ -132,7 +133,7 @@
   }
   build_env.update(env)
   build_job = jobset.JobSpec(
-          cmdline=[_IMAGE_BUILDER],
+          cmdline=[os.path.join(stack_base, _IMAGE_BUILDER)],
           environ=build_env,
           shortname='build_docker_%s' % runtime,
           timeout_seconds=30*60)
@@ -172,13 +173,14 @@
 
   env = {}
   # If we not using current tree or the sibling for grpc stack, do checkout.
+  stack_base = ''
   if args.git_checkout:
     stack_base = checkout_grpc_stack(lang, release)
     var ={'go': 'GRPC_GO_ROOT', 'java': 'GRPC_JAVA_ROOT', 'node': 'GRPC_NODE_ROOT'}.get(lang, 'GRPC_ROOT')
     env[var] = stack_base
 
   for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]:
-    job = build_image_jobspec(runtime, env, release)
+    job = build_image_jobspec(runtime, env, release, stack_base)
     docker_images.append(job.tag)
     build_jobs.append(job)
 
@@ -225,7 +227,6 @@
   repo_dir = os.path.splitext(os.path.basename(repo))[0]
   stack_base = os.path.join(args.git_checkout_root, repo_dir)
 
-  # Assume the directory is reusable for git checkout.
   if not os.path.exists(stack_base):
     subprocess.check_call(['git', 'clone', '--recursive', repo],
                           cwd=os.path.dirname(stack_base))
@@ -238,7 +239,9 @@
   output = subprocess.check_output(
       ['git', 'checkout', release], cwd=stack_base, stderr=subprocess.STDOUT)
   commit_log = subprocess.check_output(['git', 'log', '-1'], cwd=stack_base)
-  jobset.message('SUCCESS', 'git checkout', output + commit_log, do_newline=True)
+  jobset.message('SUCCESS', 'git checkout', 
+                 '%s: %s' % (str(output), commit_log), 
+                 do_newline=True)
 
   # Write git log to commit_log so it can be packaged with the docker image.
   with open(os.path.join(stack_base, 'commit_log'), 'w') as f:
diff --git a/tools/interop_matrix/create_testcases.sh b/tools/interop_matrix/create_testcases.sh
index 3d34b2e..fa33fa4 100755
--- a/tools/interop_matrix/create_testcases.sh
+++ b/tools/interop_matrix/create_testcases.sh
@@ -31,13 +31,6 @@
 
 echo "Create '$LANG' test cases for gRPC release '${RELEASE:=master}'"
 
-echo $client_lang
-# Invoke run_interop_test in manual mode.
-# TODO(adelez): Add cloud_gateways when we figure out how to skip them if not 
-# running in GCE.
-${GRPC_ROOT}/tools/run_tests/run_interop_tests.py -l $LANG --use_docker \
-  --cloud_to_prod --prod_servers default gateway_v4 --manual_run
-
 # Clean up
 function cleanup {
   [ -z "$testcase" ] && testcase=$CMDS_SH
@@ -54,19 +47,28 @@
   fi
   [ -e "$CMDS_SH" ] && rm $CMDS_SH
 }
+
+function createtests {
+# Invoke run_interop_test in manual mode.
+# TODO(adelez): Add cloud_gateways when we figure out how to skip them if not 
+# running in GCE.
+if [ $1 == "cxx" ]; then
+client_lang="c++"
+else
+client_lang=$1
+fi
+echo $client_lang
+
+${GRPC_ROOT}/tools/run_tests/run_interop_tests.py -l $client_lang --use_docker \
+  --cloud_to_prod --prod_servers default gateway_v4 --manual_run
+
 trap cleanup EXIT
 # TODO(adelez): add test auth tests but do not run if not testing on GCE.
 # Running the testcases as sanity unless we are asked to skip.
 [ -z "$SKIP_TEST" ] && (echo "Running test cases: $CMDS_SH"; sh $CMDS_SH)
 
-# Convert c++ to cxx. 
-if [$LANG == "c++" ]; then
-client_lang="cxx"
-else
-client_lang=$LANG
-fi
 mkdir -p $TESTCASES_DIR
-testcase=$TESTCASES_DIR/${client_lang}__$RELEASE
+testcase=$TESTCASES_DIR/$1__$RELEASE
 if [ -e $testcase ]; then
   echo "Updating: $testcase"
   diff $testcase $CMDS_SH || true
@@ -74,3 +76,11 @@
 mv $CMDS_SH $testcase
 chmod a+x $testcase
 echo "Test cases created: $testcase"
+}
+
+if [ $LANG == "csharp" ]; then
+createtests "csharp"
+createtests "csharpcoreclr"
+else
+createtests $LANG
+fi 
diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py
index bb7a864..491438a 100755
--- a/tools/interop_matrix/run_interop_matrix_tests.py
+++ b/tools/interop_matrix/run_interop_matrix_tests.py
@@ -122,13 +122,16 @@
   return images
 
 # caches test cases (list of JobSpec) loaded from file.  Keyed by lang and runtime.
-def find_test_cases(lang, release, suite_name):
+def find_test_cases(lang, runtime, release, suite_name):
   """Returns the list of test cases from testcase files per lang/release."""
   file_tmpl = os.path.join(os.path.dirname(__file__), 'testcases/%s__%s')
   testcase_release = release
-  if not os.path.exists(file_tmpl % (lang, release)):
+  filename_prefix = lang
+  if lang == 'csharp':
+    filename_prefix = runtime
+  if not os.path.exists(file_tmpl % (filename_prefix, release)):
     testcase_release = 'master'
-  testcases = file_tmpl % (lang, testcase_release)
+  testcases = file_tmpl % (filename_prefix, testcase_release)
 
   job_spec_list=[]
   try:
@@ -169,7 +172,12 @@
     subprocess.check_call(['gcloud', 'docker', '--', 'pull', image])
     _docker_images_cleanup.append(image)
     suite_name = '%s__%s_%s' % (lang, runtime, release)
-    job_spec_list = find_test_cases(lang, release, suite_name)
+    job_spec_list = find_test_cases(lang, runtime, release, suite_name)
+    
+    if not job_spec_list:  
+      jobset.message('FAILED', 'No test cases were found.', do_newline=True)
+      return 1
+
     num_failures, resultset = jobset.run(job_spec_list,
                                          newline_on_success=True,
                                          add_env={'docker_image':image},
diff --git a/tools/interop_matrix/testcases/csharp__master b/tools/interop_matrix/testcases/csharp__master
new file mode 100644
index 0000000..32f6b38
--- /dev/null
+++ b/tools/interop_matrix/testcases/csharp__master
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_csharp:a95229ca-d387-4127-ad48-69a7464e23b8}"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
diff --git a/tools/interop_matrix/testcases/csharpcoreclr__master b/tools/interop_matrix/testcases/csharpcoreclr__master
new file mode 100644
index 0000000..37e4598
--- /dev/null
+++ b/tools/interop_matrix/testcases/csharpcoreclr__master
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
diff --git a/tools/interop_matrix/testcases/node__master b/tools/interop_matrix/testcases/node__master
new file mode 100755
index 0000000..99ea2f0
--- /dev/null
+++ b/tools/interop_matrix/testcases/node__master
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_node:1415ecbf-5d0f-423e-8c2c-e0cb6d154e73}"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
diff --git a/tools/interop_matrix/testcases/node__v1.0.1 b/tools/interop_matrix/testcases/node__v1.0.1
new file mode 100644
index 0000000..fca9821
--- /dev/null
+++ b/tools/interop_matrix/testcases/node__v1.0.1
@@ -0,0 +1,21 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_node:a53aa5e3-b548-4566-b5a8-6d15c1315b32}"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_00c688f2-57da-4023-89f3-46b1f7b5869f $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_d86705d8-14ea-4024-90b6-de74d6e8d19c $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_ebaafacd-1d82-4a75-bea1-a5c64e01fcaf $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_5125241a-fbf6-4c1c-895b-026a5a41f02f $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_3d5e5b82-7205-4eba-b775-8122f05a4760 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_16fa0b49-2083-4932-8f26-79cfdffec940 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_23cee670-2d8d-4f5c-8893-c3c43da8b03a $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_7b6a9454-e3b6-4993-b542-468e268930aa $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_5a7109ed-c065-4b62-98f4-b3ed8f385762 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_1e0ba8dd-4dc1-431b-b202-529e7ace5d1d $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_649de56a-e722-4a59-b265-e9c0e871f068 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_8be512a2-5e1c-4858-8cfc-82f99b678b76 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_d19b6333-e528-48b5-8421-2ae3f7ce9dab $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_4749c80a-21c5-4d81-9df5-3c46ba6480cd $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_b7bee545-4857-4269-a1f2-9553dfc7e4b8 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_4e96db87-6f48-426d-a7f0-97f3a5b6b3f4 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_31a1d58c-f8bf-460a-af60-28969ecaaf80 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_ce64b147-bcfa-44b2-a2f7-4a485380ce30 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+
diff --git a/tools/interop_matrix/testcases/php__master b/tools/interop_matrix/testcases/php__master
new file mode 100755
index 0000000..bce1d30
--- /dev/null
+++ b/tools/interop_matrix/testcases/php__master
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_php:b290f404-9940-4968-8fc2-19f5291c8eb7}"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
diff --git a/tools/interop_matrix/testcases/ruby__master b/tools/interop_matrix/testcases/ruby__master
new file mode 100755
index 0000000..07bfd05
--- /dev/null
+++ b/tools/interop_matrix/testcases/ruby__master
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "Testing ${docker_image:=grpc_interop_ruby:6bd1f0eb-51a4-4ad8-861c-1cbd7a929f33}"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response"
+docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server"