Merge branch 'error' of github.com:ctiller/grpc into error
diff --git a/doc/command_line_tool.md b/doc/command_line_tool.md
new file mode 100644
index 0000000..89a7054
--- /dev/null
+++ b/doc/command_line_tool.md
@@ -0,0 +1,77 @@
+# gRPC command line tool
+
+## Overview
+
+This document describes the command line tool that comes with gRPC repository. It is desireable to have command line
+tools written in other languages to roughly follow the same syntax and flags.
+
+At this point, the tool needs to be built from source, and it should be moved out to grpc-tools repository as a stand
+alone application once it is mature enough.
+
+## Core functionality
+
+The command line tool can do the following things:
+
+- Send unary rpc.
+- Attach metadata and display received metadata.
+- Handle common authentication to server.
+- Find the request/response types from a given proto file.
+- Read proto request in text form.
+- Read request in wire form (for protobuf messages, this means serialized binary form).
+- Display proto response in text form.
+- Write response in wire form to a file.
+
+The command line tool should support the following things:
+
+- List server services and methods through server reflection.
+- Infer request/response types from server reflection result.
+- Fine-grained auth control (such as, use this oauth token to talk to the server).
+- Send streaming rpc.
+
+## Code location
+
+To use the tool, you need to get the grpc repository and in the grpc directory execute
+
+```
+$ make grpc_cli
+```
+
+The main file can be found at
+https://github.com/grpc/grpc/blob/master/test/cpp/util/grpc_cli.cc
+
+## Usage
+
+### Basic usage
+
+Send a rpc to a helloworld server at `localhost:50051`:
+
+```
+$ bins/opt/grpc_cli call localhost:50051 SayHello examples/protos/helloworld.proto \
+    "name: 'world'"  --enable_ssl=false
+```
+
+On success, the tool will print out
+
+```
+Rpc succeeded with OK status
+Response: 
+ message: "Hello world"
+```
+
+The `localhost:50051` part indicates the server you are connecting to. `SayHello` is (part of) the
+gRPC method string. Then there is the path to the proto file containing the service definition,
+if it is not under current directory, you can use `--proto_path` to specify a new search root.
+`"name: 'world'"` is the text format of the request proto message. 
+We are not using ssl here by `--enable_ssl=false`. For information on more
+flags, look at the comments of `grpc_cli.cc`.
+
+### Send non-proto rpc
+
+For using gRPC with protocols other than probobuf, you will need the exact method name string
+and a file containing the raw bytes to be sent on the wire
+
+```
+$ bins/opt/grpc_cli call localhost:50051 /helloworld.Greeter/SayHello --input_binary_file=input.bin \
+    --output_binary_file=output.bin
+```
+On success, you will need to read or decode the response from the `output.bin` file.
diff --git a/examples/php/greeter_client.php b/examples/php/greeter_client.php
index 718ef88..a5c0865 100644
--- a/examples/php/greeter_client.php
+++ b/examples/php/greeter_client.php
@@ -32,19 +32,21 @@
  *
  */
 
-require dirname(__FILE__) . '/vendor/autoload.php';
-require dirname(__FILE__) . '/helloworld.php';
+require dirname(__FILE__).'/vendor/autoload.php';
+require dirname(__FILE__).'/helloworld.php';
 
-function greet($name) {
-  $client = new helloworld\GreeterClient('localhost:50051', [
-    'credentials' => Grpc\ChannelCredentials::createInsecure()
-  ]);
-  $request = new helloworld\HelloRequest();
-  $request->setName($name);
-  list($reply, $status) = $client->SayHello($request)->wait();
-  $message = $reply->getMessage();
-  return $message;
+function greet($name)
+{
+    $client = new helloworld\GreeterClient('localhost:50051', [
+        'credentials' => Grpc\ChannelCredentials::createInsecure(),
+    ]);
+    $request = new helloworld\HelloRequest();
+    $request->setName($name);
+    list($reply, $status) = $client->SayHello($request)->wait();
+    $message = $reply->getMessage();
+
+    return $message;
 }
 
 $name = !empty($argv[1]) ? $argv[1] : 'world';
-print(greet($name)."\n");
+echo greet($name)."\n";
diff --git a/examples/php/helloworld.php b/examples/php/helloworld.php
index 50923e6..697f52a 100644
--- a/examples/php/helloworld.php
+++ b/examples/php/helloworld.php
@@ -5,154 +5,164 @@
 
 namespace helloworld {
 
-  class HelloRequest extends \DrSlump\Protobuf\Message {
-
-    /**  @var string */
+  class HelloRequest extends \DrSlump\Protobuf\Message
+  {
+      /**  @var string */
     public $name = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloRequest');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloRequest');
 
       // OPTIONAL STRING name = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "name";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'name';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <name> has a value.
+     *
+     * @return bool
+     */
+    public function hasName()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <name> has a value
-     *
-     * @return boolean
-     */
-    public function hasName(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <name> value
+     * Clear <name> value.
      *
      * @return \helloworld\HelloRequest
      */
-    public function clearName(){
-      return $this->_clear(1);
+    public function clearName()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <name> value
+     * Get <name> value.
      *
      * @return string
      */
-    public function getName(){
-      return $this->_get(1);
+    public function getName()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <name> value
+     * Set <name> value.
      *
      * @param string $value
+     *
      * @return \helloworld\HelloRequest
      */
-    public function setName( $value){
-      return $this->_set(1, $value);
+    public function setName($value)
+    {
+        return $this->_set(1, $value);
     }
   }
 }
 
 namespace helloworld {
 
-  class HelloReply extends \DrSlump\Protobuf\Message {
-
-    /**  @var string */
+  class HelloReply extends \DrSlump\Protobuf\Message
+  {
+      /**  @var string */
     public $message = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply');
 
       // OPTIONAL STRING message = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "message";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'message';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <message> has a value.
+     *
+     * @return bool
+     */
+    public function hasMessage()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <message> has a value
-     *
-     * @return boolean
-     */
-    public function hasMessage(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <message> value
+     * Clear <message> value.
      *
      * @return \helloworld\HelloReply
      */
-    public function clearMessage(){
-      return $this->_clear(1);
+    public function clearMessage()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <message> value
+     * Get <message> value.
      *
      * @return string
      */
-    public function getMessage(){
-      return $this->_get(1);
+    public function getMessage()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <message> value
+     * Set <message> value.
      *
      * @param string $value
+     *
      * @return \helloworld\HelloReply
      */
-    public function setMessage( $value){
-      return $this->_set(1, $value);
+    public function setMessage($value)
+    {
+        return $this->_set(1, $value);
     }
   }
 }
 
 namespace helloworld {
 
-  class GreeterClient extends \Grpc\BaseStub {
-
-    public function __construct($hostname, $opts) {
-      parent::__construct($hostname, $opts);
-    }
+  class GreeterClient extends \Grpc\BaseStub
+  {
+      public function __construct($hostname, $opts)
+      {
+          parent::__construct($hostname, $opts);
+      }
     /**
      * @param helloworld\HelloRequest $input
      */
-    public function SayHello(\helloworld\HelloRequest $argument, $metadata = array(), $options = array()) {
-      return $this->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata, $options);
+    public function SayHello(\helloworld\HelloRequest $argument, $metadata = array(), $options = array())
+    {
+        return $this->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata, $options);
     }
   }
 }
diff --git a/examples/php/route_guide/route_guide.php b/examples/php/route_guide/route_guide.php
index 0de3198..65045d0 100644
--- a/examples/php/route_guide/route_guide.php
+++ b/examples/php/route_guide/route_guide.php
@@ -5,725 +5,785 @@
 
 namespace routeguide {
 
-  class Point extends \DrSlump\Protobuf\Message {
+  class Point extends \DrSlump\Protobuf\Message
+  {
+      /**  @var int */
+    public $latitude = 0;
 
     /**  @var int */
-    public $latitude = 0;
-    
-    /**  @var int */
     public $longitude = 0;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Point');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Point');
 
       // OPTIONAL INT32 latitude = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "latitude";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'latitude';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 longitude = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "longitude";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'longitude';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <latitude> has a value.
+     *
+     * @return bool
+     */
+    public function hasLatitude()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <latitude> has a value
-     *
-     * @return boolean
-     */
-    public function hasLatitude(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <latitude> value
+     * Clear <latitude> value.
      *
      * @return \routeguide\Point
      */
-    public function clearLatitude(){
-      return $this->_clear(1);
+    public function clearLatitude()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <latitude> value
+     * Get <latitude> value.
      *
      * @return int
      */
-    public function getLatitude(){
-      return $this->_get(1);
+    public function getLatitude()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <latitude> value
+     * Set <latitude> value.
      *
      * @param int $value
-     * @return \routeguide\Point
-     */
-    public function setLatitude( $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <longitude> has a value
-     *
-     * @return boolean
-     */
-    public function hasLongitude(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <longitude> value
      *
      * @return \routeguide\Point
      */
-    public function clearLongitude(){
-      return $this->_clear(2);
+    public function setLatitude($value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <longitude> value
+     * Check if <longitude> has a value.
+     *
+     * @return bool
+     */
+    public function hasLongitude()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <longitude> value.
+     *
+     * @return \routeguide\Point
+     */
+    public function clearLongitude()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <longitude> value.
      *
      * @return int
      */
-    public function getLongitude(){
-      return $this->_get(2);
+    public function getLongitude()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <longitude> value
+     * Set <longitude> value.
      *
      * @param int $value
+     *
      * @return \routeguide\Point
      */
-    public function setLongitude( $value){
-      return $this->_set(2, $value);
+    public function setLongitude($value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class Rectangle extends \DrSlump\Protobuf\Message {
+  class Rectangle extends \DrSlump\Protobuf\Message
+  {
+      /**  @var \routeguide\Point */
+    public $lo = null;
 
     /**  @var \routeguide\Point */
-    public $lo = null;
-    
-    /**  @var \routeguide\Point */
     public $hi = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Rectangle');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Rectangle');
 
       // OPTIONAL MESSAGE lo = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "lo";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'lo';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
       // OPTIONAL MESSAGE hi = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "hi";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'hi';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <lo> has a value.
+     *
+     * @return bool
+     */
+    public function hasLo()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <lo> has a value
-     *
-     * @return boolean
-     */
-    public function hasLo(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <lo> value
+     * Clear <lo> value.
      *
      * @return \routeguide\Rectangle
      */
-    public function clearLo(){
-      return $this->_clear(1);
+    public function clearLo()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <lo> value
+     * Get <lo> value.
      *
      * @return \routeguide\Point
      */
-    public function getLo(){
-      return $this->_get(1);
+    public function getLo()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <lo> value
+     * Set <lo> value.
      *
      * @param \routeguide\Point $value
-     * @return \routeguide\Rectangle
-     */
-    public function setLo(\routeguide\Point $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <hi> has a value
-     *
-     * @return boolean
-     */
-    public function hasHi(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <hi> value
      *
      * @return \routeguide\Rectangle
      */
-    public function clearHi(){
-      return $this->_clear(2);
+    public function setLo(\routeguide\Point $value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <hi> value
+     * Check if <hi> has a value.
+     *
+     * @return bool
+     */
+    public function hasHi()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <hi> value.
+     *
+     * @return \routeguide\Rectangle
+     */
+    public function clearHi()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <hi> value.
      *
      * @return \routeguide\Point
      */
-    public function getHi(){
-      return $this->_get(2);
+    public function getHi()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <hi> value
+     * Set <hi> value.
      *
      * @param \routeguide\Point $value
+     *
      * @return \routeguide\Rectangle
      */
-    public function setHi(\routeguide\Point $value){
-      return $this->_set(2, $value);
+    public function setHi(\routeguide\Point $value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class Feature extends \DrSlump\Protobuf\Message {
-
-    /**  @var string */
+  class Feature extends \DrSlump\Protobuf\Message
+  {
+      /**  @var string */
     public $name = null;
-    
+
     /**  @var \routeguide\Point */
     public $location = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Feature');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Feature');
 
       // OPTIONAL STRING name = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "name";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'name';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
       // OPTIONAL MESSAGE location = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "location";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'location';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <name> has a value.
+     *
+     * @return bool
+     */
+    public function hasName()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <name> has a value
-     *
-     * @return boolean
-     */
-    public function hasName(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <name> value
+     * Clear <name> value.
      *
      * @return \routeguide\Feature
      */
-    public function clearName(){
-      return $this->_clear(1);
+    public function clearName()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <name> value
+     * Get <name> value.
      *
      * @return string
      */
-    public function getName(){
-      return $this->_get(1);
+    public function getName()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <name> value
+     * Set <name> value.
      *
      * @param string $value
-     * @return \routeguide\Feature
-     */
-    public function setName( $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <location> has a value
-     *
-     * @return boolean
-     */
-    public function hasLocation(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <location> value
      *
      * @return \routeguide\Feature
      */
-    public function clearLocation(){
-      return $this->_clear(2);
+    public function setName($value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <location> value
+     * Check if <location> has a value.
+     *
+     * @return bool
+     */
+    public function hasLocation()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <location> value.
+     *
+     * @return \routeguide\Feature
+     */
+    public function clearLocation()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <location> value.
      *
      * @return \routeguide\Point
      */
-    public function getLocation(){
-      return $this->_get(2);
+    public function getLocation()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <location> value
+     * Set <location> value.
      *
      * @param \routeguide\Point $value
+     *
      * @return \routeguide\Feature
      */
-    public function setLocation(\routeguide\Point $value){
-      return $this->_set(2, $value);
+    public function setLocation(\routeguide\Point $value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class RouteNote extends \DrSlump\Protobuf\Message {
-
-    /**  @var \routeguide\Point */
+  class RouteNote extends \DrSlump\Protobuf\Message
+  {
+      /**  @var \routeguide\Point */
     public $location = null;
-    
+
     /**  @var string */
     public $message = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteNote');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteNote');
 
       // OPTIONAL MESSAGE location = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "location";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'location';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
       // OPTIONAL STRING message = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "message";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'message';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <location> has a value.
+     *
+     * @return bool
+     */
+    public function hasLocation()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <location> has a value
-     *
-     * @return boolean
-     */
-    public function hasLocation(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <location> value
+     * Clear <location> value.
      *
      * @return \routeguide\RouteNote
      */
-    public function clearLocation(){
-      return $this->_clear(1);
+    public function clearLocation()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <location> value
+     * Get <location> value.
      *
      * @return \routeguide\Point
      */
-    public function getLocation(){
-      return $this->_get(1);
+    public function getLocation()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <location> value
+     * Set <location> value.
      *
      * @param \routeguide\Point $value
-     * @return \routeguide\RouteNote
-     */
-    public function setLocation(\routeguide\Point $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <message> has a value
-     *
-     * @return boolean
-     */
-    public function hasMessage(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <message> value
      *
      * @return \routeguide\RouteNote
      */
-    public function clearMessage(){
-      return $this->_clear(2);
+    public function setLocation(\routeguide\Point $value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <message> value
+     * Check if <message> has a value.
+     *
+     * @return bool
+     */
+    public function hasMessage()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <message> value.
+     *
+     * @return \routeguide\RouteNote
+     */
+    public function clearMessage()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <message> value.
      *
      * @return string
      */
-    public function getMessage(){
-      return $this->_get(2);
+    public function getMessage()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <message> value
+     * Set <message> value.
      *
      * @param string $value
+     *
      * @return \routeguide\RouteNote
      */
-    public function setMessage( $value){
-      return $this->_set(2, $value);
+    public function setMessage($value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class RouteSummary extends \DrSlump\Protobuf\Message {
+  class RouteSummary extends \DrSlump\Protobuf\Message
+  {
+      /**  @var int */
+    public $point_count = 0;
 
     /**  @var int */
-    public $point_count = 0;
-    
-    /**  @var int */
     public $feature_count = 0;
-    
+
     /**  @var int */
     public $distance = 0;
-    
+
     /**  @var int */
     public $elapsed_time = 0;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteSummary');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteSummary');
 
       // OPTIONAL INT32 point_count = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "point_count";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'point_count';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 feature_count = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "feature_count";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'feature_count';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 distance = 3
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 3;
-      $f->name      = "distance";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 3;
+          $f->name = 'distance';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 elapsed_time = 4
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 4;
-      $f->name      = "elapsed_time";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 4;
+          $f->name = 'elapsed_time';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <point_count> has a value.
+     *
+     * @return bool
+     */
+    public function hasPointCount()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <point_count> has a value
-     *
-     * @return boolean
-     */
-    public function hasPointCount(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <point_count> value
+     * Clear <point_count> value.
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearPointCount(){
-      return $this->_clear(1);
+    public function clearPointCount()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <point_count> value
+     * Get <point_count> value.
      *
      * @return int
      */
-    public function getPointCount(){
-      return $this->_get(1);
+    public function getPointCount()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <point_count> value
+     * Set <point_count> value.
      *
      * @param int $value
-     * @return \routeguide\RouteSummary
-     */
-    public function setPointCount( $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <feature_count> has a value
-     *
-     * @return boolean
-     */
-    public function hasFeatureCount(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <feature_count> value
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearFeatureCount(){
-      return $this->_clear(2);
+    public function setPointCount($value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <feature_count> value
+     * Check if <feature_count> has a value.
+     *
+     * @return bool
+     */
+    public function hasFeatureCount()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <feature_count> value.
+     *
+     * @return \routeguide\RouteSummary
+     */
+    public function clearFeatureCount()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <feature_count> value.
      *
      * @return int
      */
-    public function getFeatureCount(){
-      return $this->_get(2);
+    public function getFeatureCount()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <feature_count> value
+     * Set <feature_count> value.
      *
      * @param int $value
-     * @return \routeguide\RouteSummary
-     */
-    public function setFeatureCount( $value){
-      return $this->_set(2, $value);
-    }
-    
-    /**
-     * Check if <distance> has a value
-     *
-     * @return boolean
-     */
-    public function hasDistance(){
-      return $this->_has(3);
-    }
-    
-    /**
-     * Clear <distance> value
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearDistance(){
-      return $this->_clear(3);
+    public function setFeatureCount($value)
+    {
+        return $this->_set(2, $value);
     }
-    
+
     /**
-     * Get <distance> value
+     * Check if <distance> has a value.
+     *
+     * @return bool
+     */
+    public function hasDistance()
+    {
+        return $this->_has(3);
+    }
+
+    /**
+     * Clear <distance> value.
+     *
+     * @return \routeguide\RouteSummary
+     */
+    public function clearDistance()
+    {
+        return $this->_clear(3);
+    }
+
+    /**
+     * Get <distance> value.
      *
      * @return int
      */
-    public function getDistance(){
-      return $this->_get(3);
+    public function getDistance()
+    {
+        return $this->_get(3);
     }
-    
+
     /**
-     * Set <distance> value
+     * Set <distance> value.
      *
      * @param int $value
-     * @return \routeguide\RouteSummary
-     */
-    public function setDistance( $value){
-      return $this->_set(3, $value);
-    }
-    
-    /**
-     * Check if <elapsed_time> has a value
-     *
-     * @return boolean
-     */
-    public function hasElapsedTime(){
-      return $this->_has(4);
-    }
-    
-    /**
-     * Clear <elapsed_time> value
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearElapsedTime(){
-      return $this->_clear(4);
+    public function setDistance($value)
+    {
+        return $this->_set(3, $value);
     }
-    
+
     /**
-     * Get <elapsed_time> value
+     * Check if <elapsed_time> has a value.
+     *
+     * @return bool
+     */
+    public function hasElapsedTime()
+    {
+        return $this->_has(4);
+    }
+
+    /**
+     * Clear <elapsed_time> value.
+     *
+     * @return \routeguide\RouteSummary
+     */
+    public function clearElapsedTime()
+    {
+        return $this->_clear(4);
+    }
+
+    /**
+     * Get <elapsed_time> value.
      *
      * @return int
      */
-    public function getElapsedTime(){
-      return $this->_get(4);
+    public function getElapsedTime()
+    {
+        return $this->_get(4);
     }
-    
+
     /**
-     * Set <elapsed_time> value
+     * Set <elapsed_time> value.
      *
      * @param int $value
+     *
      * @return \routeguide\RouteSummary
      */
-    public function setElapsedTime( $value){
-      return $this->_set(4, $value);
+    public function setElapsedTime($value)
+    {
+        return $this->_set(4, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class RouteGuideClient extends \Grpc\BaseStub {
-
-    public function __construct($hostname, $opts) {
-      parent::__construct($hostname, $opts);
-    }
+  class RouteGuideClient extends \Grpc\BaseStub
+  {
+      public function __construct($hostname, $opts)
+      {
+          parent::__construct($hostname, $opts);
+      }
     /**
      * @param routeguide\Point $input
      */
-    public function GetFeature(\routeguide\Point $argument, $metadata = array(), $options = array()) {
-      return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
+    public function GetFeature(\routeguide\Point $argument, $metadata = array(), $options = array())
+    {
+        return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
     }
     /**
      * @param routeguide\Rectangle $input
      */
-    public function ListFeatures($argument, $metadata = array(), $options = array()) {
-      return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
+    public function ListFeatures($argument, $metadata = array(), $options = array())
+    {
+        return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
     }
     /**
      * @param routeguide\Point $input
      */
-    public function RecordRoute($metadata = array()) {
-      return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute', '\routeguide\RouteSummary::deserialize', $metadata);
+    public function RecordRoute($metadata = array())
+    {
+        return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute', '\routeguide\RouteSummary::deserialize', $metadata);
     }
     /**
      * @param routeguide\RouteNote $input
      */
-    public function RouteChat($metadata = array()) {
-      return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat', '\routeguide\RouteNote::deserialize', $metadata);
+    public function RouteChat($metadata = array())
+    {
+        return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat', '\routeguide\RouteNote::deserialize', $metadata);
     }
   }
 }
diff --git a/examples/php/route_guide/route_guide_client.php b/examples/php/route_guide/route_guide_client.php
index 2f9533b..b3cd606 100644
--- a/examples/php/route_guide/route_guide_client.php
+++ b/examples/php/route_guide/route_guide_client.php
@@ -32,48 +32,50 @@
  *
  */
 
-require dirname(__FILE__) . '/../vendor/autoload.php';
-require dirname(__FILE__) . '/route_guide.php';
+require dirname(__FILE__).'/../vendor/autoload.php';
+require dirname(__FILE__).'/route_guide.php';
 
 define('COORD_FACTOR', 1e7);
 
 $client = new routeguide\RouteGuideClient('localhost:50051', [
-  'credentials' => Grpc\ChannelCredentials::createInsecure()
+    'credentials' => Grpc\ChannelCredentials::createInsecure(),
 ]);
 
-function printFeature($feature) {
-  $name = $feature->getName();
-  if (!$name) {
-    $name_str = "no feature";
-  } else {
-    $name_str = "feature called $name";
-  }
-  print sprintf("Found %s \n  at %f, %f\n", $name_str,
-                $feature->getLocation()->getLatitude() / COORD_FACTOR,
-                $feature->getLocation()->getLongitude() / COORD_FACTOR);
+function printFeature($feature)
+{
+    $name = $feature->getName();
+    if (!$name) {
+        $name_str = 'no feature';
+    } else {
+        $name_str = "feature called $name";
+    }
+    echo sprintf("Found %s \n  at %f, %f\n", $name_str,
+                 $feature->getLocation()->getLatitude() / COORD_FACTOR,
+                 $feature->getLocation()->getLongitude() / COORD_FACTOR);
 }
 
 /**
  * Run the getFeature demo. Calls getFeature with a point known to have a
  * feature and a point known not to have a feature.
  */
-function runGetFeature() {
-  print "Running GetFeature...\n";
-  global $client;
+function runGetFeature()
+{
+    echo "Running GetFeature...\n";
+    global $client;
 
-  $point = new routeguide\Point();
-  $points = array(
-    array(409146138, -746188906),
-    array(0, 0),
-  );
+    $point = new routeguide\Point();
+    $points = array(
+        array(409146138, -746188906),
+        array(0, 0),
+    );
 
-  foreach ($points as $p) {
-    $point->setLatitude($p[0]);
-    $point->setLongitude($p[1]);
-    // make a unary grpc call
-    list($feature, $status) = $client->GetFeature($point)->wait();
-    printFeature($feature);
-  }
+    foreach ($points as $p) {
+        $point->setLatitude($p[0]);
+        $point->setLongitude($p[1]);
+        // make a unary grpc call
+        list($feature, $status) = $client->GetFeature($point)->wait();
+        printFeature($feature);
+    }
 }
 
 /**
@@ -81,29 +83,30 @@
  * containing all of the features in the pre-generated
  * database. Prints each response as it comes in.
  */
-function runListFeatures() {
-  print "Running ListFeatures...\n";
-  global $client;
+function runListFeatures()
+{
+    echo "Running ListFeatures...\n";
+    global $client;
 
-  $lo_point = new routeguide\Point();
-  $hi_point = new routeguide\Point();
+    $lo_point = new routeguide\Point();
+    $hi_point = new routeguide\Point();
 
-  $lo_point->setLatitude(400000000);
-  $lo_point->setLongitude(-750000000);
-  $hi_point->setLatitude(420000000);
-  $hi_point->setLongitude(-730000000);
+    $lo_point->setLatitude(400000000);
+    $lo_point->setLongitude(-750000000);
+    $hi_point->setLatitude(420000000);
+    $hi_point->setLongitude(-730000000);
 
-  $rectangle = new routeguide\Rectangle();
-  $rectangle->setLo($lo_point);
-  $rectangle->setHi($hi_point);
+    $rectangle = new routeguide\Rectangle();
+    $rectangle->setLo($lo_point);
+    $rectangle->setHi($hi_point);
 
-  // start the server streaming call
-  $call = $client->ListFeatures($rectangle);
-  // an iterator over the server streaming responses
-  $features = $call->responses();
-  foreach ($features as $feature) {
-    printFeature($feature);
-  }
+    // start the server streaming call
+    $call = $client->ListFeatures($rectangle);
+    // an iterator over the server streaming responses
+    $features = $call->responses();
+    foreach ($features as $feature) {
+        printFeature($feature);
+    }
 }
 
 /**
@@ -111,96 +114,99 @@
  * pre-generated feature database with a variable delay in between. Prints
  * the statistics when they are sent from the server.
  */
-function runRecordRoute() {
-  print "Running RecordRoute...\n";
-  global $client, $argv;
+function runRecordRoute()
+{
+    echo "Running RecordRoute...\n";
+    global $client, $argv;
 
-  // start the client streaming call
-  $call = $client->RecordRoute();
+    // start the client streaming call
+    $call = $client->RecordRoute();
 
-  $db = json_decode(file_get_contents($argv[1]), true);
-  $num_points_in_db = count($db);
-  $num_points = 10;
-  for ($i = 0; $i < $num_points; $i++) {
-    $point = new routeguide\Point();
-    $index = rand(0, $num_points_in_db - 1);
-    $lat = $db[$index]['location']['latitude'];
-    $long = $db[$index]['location']['longitude'];
-    $feature_name = $db[$index]['name'];
-    $point->setLatitude($lat);
-    $point->setLongitude($long);
-    print 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();
-  print 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());
+    $db = json_decode(file_get_contents($argv[1]), true);
+    $num_points_in_db = count($db);
+    $num_points = 10;
+    for ($i = 0; $i < $num_points; ++$i) {
+        $point = new routeguide\Point();
+        $index = rand(0, $num_points_in_db - 1);
+        $lat = $db[$index]['location']['latitude'];
+        $long = $db[$index]['location']['longitude'];
+        $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>');
+        usleep(rand(300000, 800000));
+        $call->write($point);
+    }
+    list($route_summary, $status) = $call->wait();
+    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());
 }
 
 /**
  * Run the routeChat demo. Send some chat messages, and print any chat
  * messages that are sent from the server.
  */
-function runRouteChat() {
-  print "Running RouteChat...\n";
-  global $client;
+function runRouteChat()
+{
+    echo "Running RouteChat...\n";
+    global $client;
 
-  // start the bidirectional streaming call
-  $call = $client->RouteChat();
+    // start the bidirectional streaming call
+    $call = $client->RouteChat();
 
-  $notes = array(
-    array(1, 1, 'first message'),
-    array(1, 2, 'second message'),
-    array(2, 1, 'third message'),
-    array(1, 1, 'fourth message'),
-    array(1, 1, 'fifth message'),
-  );
+    $notes = array(
+        array(1, 1, 'first message'),
+        array(1, 2, 'second message'),
+        array(2, 1, 'third message'),
+        array(1, 1, 'fourth message'),
+        array(1, 1, 'fifth message'),
+    );
 
-  foreach ($notes as $n) {
-    $point = new routeguide\Point();
-    $point->setLatitude($lat = $n[0]);
-    $point->setLongitude($long = $n[1]);
+    foreach ($notes as $n) {
+        $point = new routeguide\Point();
+        $point->setLatitude($lat = $n[0]);
+        $point->setLongitude($long = $n[1]);
 
-    $route_note = new routeguide\RouteNote();
-    $route_note->setLocation($point);
-    $route_note->setMessage($message = $n[2]);
+        $route_note = new routeguide\RouteNote();
+        $route_note->setLocation($point);
+        $route_note->setMessage($message = $n[2]);
 
-    print sprintf("Sending message: '%s' at (%d, %d)\n",
-                  $message, $lat, $long);
-    // send a bunch of messages to the server
-    $call->write($route_note);
-  }
-  $call->writesDone();
+        echo sprintf("Sending message: '%s' at (%d, %d)\n",
+                     $message, $lat, $long);
+        // send a bunch of messages to the server
+        $call->write($route_note);
+    }
+    $call->writesDone();
 
-  // read from the server until there's no more
-  while ($route_note_reply = $call->read()) {
-    print sprintf("Previous left message at (%d, %d): '%s'\n",
-                  $route_note_reply->getLocation()->getLatitude(),
-                  $route_note_reply->getLocation()->getLongitude(),
-                  $route_note_reply->getMessage());
-  }
+    // 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",
+                     $route_note_reply->getLocation()->getLatitude(),
+                     $route_note_reply->getLocation()->getLongitude(),
+                     $route_note_reply->getMessage());
+    }
 }
 
 /**
- * Run all of the demos in order
+ * Run all of the demos in order.
  */
-function main() {
-  runGetFeature();
-  runListFeatures();
-  runRecordRoute();
-  runRouteChat();
+function main()
+{
+    runGetFeature();
+    runListFeatures();
+    runRecordRoute();
+    runRouteChat();
 }
 
 if (empty($argv[1])) {
-  print "Usage: php -d extension=grpc.so route_guide_client.php " .
+    echo 'Usage: php -d extension=grpc.so route_guide_client.php '.
         "<path to route_guide_db.json>\n";
-  exit(1);
+    exit(1);
 }
 main();
diff --git a/setup.py b/setup.py
index 018d047..e2de96d 100644
--- a/setup.py
+++ b/setup.py
@@ -33,9 +33,11 @@
 import os.path
 import shutil
 import sys
+import sysconfig
 
 from distutils import core as _core
 from distutils import extension as _extension
+import pkg_resources
 import setuptools
 from setuptools.command import egg_info
 
@@ -110,6 +112,16 @@
   DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
 
 
+# By default, Python3 distutils enforces compatibility of
+# c plugins (.so files) with the OSX version Python3 was built with.
+# For Python3.4, this is OSX 10.6, but we need Thread Local Support (__thread)
+if 'darwin' in sys.platform and PY3:
+  mac_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+  if mac_target and (pkg_resources.parse_version(mac_target) <
+                     pkg_resources.parse_version('10.7.0')):
+    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
+
+
 def cython_extensions(module_names, extra_sources, include_dirs,
                       libraries, define_macros, build_with_cython=False):
   # Set compiler directives linetrace argument only if we care about tracing;
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 565bfce..c5bb7c4 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -477,7 +477,8 @@
     return $stub;
 }
 
-function interop_main($args, $stub = false) {
+function interop_main($args, $stub = false)
+{
     if (!$stub) {
         $stub = _makeStub($args);
     }
diff --git a/src/php/tests/interop/metrics_client.php b/src/php/tests/interop/metrics_client.php
index 46f4212..19510dc 100644
--- a/src/php/tests/interop/metrics_client.php
+++ b/src/php/tests/interop/metrics_client.php
@@ -39,11 +39,11 @@
 
 $socket = socket_create(AF_INET, SOCK_STREAM, 0);
 if (@!socket_connect($socket, $server_host, $server_port)) {
-  echo "Cannot connect to merics server...\n";
-  exit(1);
+    echo "Cannot connect to merics server...\n";
+    exit(1);
 }
 socket_write($socket, 'qps');
 while ($out = socket_read($socket, 1024)) {
-  echo "$out\n";
+    echo "$out\n";
 }
 socket_close($socket);
diff --git a/src/php/tests/interop/stress_client.php b/src/php/tests/interop/stress_client.php
index 2339f0d..419ef5b 100644
--- a/src/php/tests/interop/stress_client.php
+++ b/src/php/tests/interop/stress_client.php
@@ -32,50 +32,52 @@
  *
  */
 
-include_once('interop_client.php');
+include_once 'interop_client.php';
 
-function stress_main($args) {
-  mt_srand();
-  set_time_limit(0);
+function stress_main($args)
+{
+    mt_srand();
+    set_time_limit(0);
 
-  // open socket to listen as metrics server
-  $socket = socket_create(AF_INET, SOCK_STREAM, 0);
-  socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
-  if (@!socket_bind($socket, 'localhost', $args['metrics_port'])) {
-    echo "Cannot create socket for metrics server...\n";
-    exit(1);
-  }
-  socket_listen($socket);
-  socket_set_nonblock($socket);
-
-  $start_time = microtime(true);
-  $count = 0;
-  $deadline = $args['test_duration_secs'] ?
-              ($start_time + $args['test_duration_secs']) : false;
-  $num_test_cases = count($args['test_cases']);
-  $stub = false;
-
-  while (true) {
-    $current_time = microtime(true);
-    if ($deadline && $current_time > $deadline) {
-      break;
+    // open socket to listen as metrics server
+    $socket = socket_create(AF_INET, SOCK_STREAM, 0);
+    socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
+    if (@!socket_bind($socket, 'localhost', $args['metrics_port'])) {
+        echo "Cannot create socket for metrics server...\n";
+        exit(1);
     }
-    if ($client_connection = socket_accept($socket)) {
-      // there is an incoming request, respond with qps metrics
-      $input = socket_read($client_connection, 1024);
-      $qps = round($count / ($current_time - $start_time));
-      socket_write($client_connection, "qps: $qps");
-      socket_close($client_connection);
-    } else {
-      // do actual work, run one interop test case
-      $args['test_case'] =
-          $args['test_cases'][mt_rand(0, $num_test_cases - 1)];
-      $stub = @interop_main($args, $stub);
-      $count++;
+    socket_listen($socket);
+    socket_set_nonblock($socket);
+
+    $start_time = microtime(true);
+    $count = 0;
+    $deadline = $args['test_duration_secs'] ?
+                ($start_time + $args['test_duration_secs']) : false;
+    $num_test_cases = count($args['test_cases']);
+    $stub = false;
+
+    while (true) {
+        $current_time = microtime(true);
+        if ($deadline && $current_time > $deadline) {
+            break;
+        }
+        if ($client_connection = socket_accept($socket)) {
+            // there is an incoming request, respond with qps metrics
+            $input = socket_read($client_connection, 1024);
+            $qps = round($count / ($current_time - $start_time));
+            socket_write($client_connection, "qps: $qps");
+            socket_close($client_connection);
+        } else {
+            // do actual work, run one interop test case
+            $args['test_case'] =
+                $args['test_cases'][mt_rand(0, $num_test_cases - 1)];
+            $stub = @interop_main($args, $stub);
+            ++$count;
+        }
     }
-  }
-  socket_close($socket);
-  echo "Number of interop tests run in $args[test_duration_secs] seconds: $count.\n";
+    socket_close($socket);
+    echo "Number of interop tests run in $args[test_duration_secs] ".
+        "seconds: $count.\n";
 }
 
 // process command line arguments
@@ -85,31 +87,32 @@
    'metrics_port::',
    'test_duration_secs::',
    'num_channels_per_server::',
-   'num_stubs_per_channel::']);
+   'num_stubs_per_channel::',
+  ]);
 
 $args = [];
 
 if (empty($raw_args['server_addresses'])) {
-  $args['server_host'] = 'localhost';
-  $args['server_port'] = '8080';
+    $args['server_host'] = 'localhost';
+    $args['server_port'] = '8080';
 } else {
-  $parts = explode(':', $raw_args['server_addresses']);
-  $args['server_host'] = $parts[0];
-  $args['server_port'] = (count($parts) == 2) ? $parts[1] : '';
+    $parts = explode(':', $raw_args['server_addresses']);
+    $args['server_host'] = $parts[0];
+    $args['server_port'] = (count($parts) == 2) ? $parts[1] : '';
 }
 
 $args['metrics_port'] = empty($raw_args['metrics_port']) ?
-  '8081' : $args['metrics_port'];
+    '8081' : $args['metrics_port'];
 
 $args['test_duration_secs'] = empty($raw_args['test_duration_secs']) ||
-  $raw_args['test_duration_secs'] == -1 ?
-  false : $raw_args['test_duration_secs'];
+    $raw_args['test_duration_secs'] == -1 ?
+    false : $raw_args['test_duration_secs'];
 
 $test_cases = [];
 $test_case_strs = explode(',', $raw_args['test_cases']);
 foreach ($test_case_strs as $test_case_str) {
-  $parts = explode(':', $test_case_str);
-  $test_cases = array_merge($test_cases, array_fill(0, $parts[1], $parts[0]));
+    $parts = explode(':', $test_case_str);
+    $test_cases = array_merge($test_cases, array_fill(0, $parts[1], $parts[0]));
 }
 $args['test_cases'] = $test_cases;
 
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index 295dab2..3e974eb 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -191,7 +191,7 @@
       except subprocess.CalledProcessError as e:
         sys.stderr.write(
             'warning: Command:\n{}\nMessage:\n{}\nOutput:\n{}'.format(
-                command, e.message, e.output))
+                command, str(e), e.output))
 
     # Generated proto directories dont include __init__.py, but
     # these are needed for python package resolution
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index d9eb5a4..d9315d2 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -85,7 +85,7 @@
 
 
 def _unknown_code_details(unknown_cygrpc_code, details):
-  return b'Server sent unknown code {} and details "{}"'.format(
+  return 'Server sent unknown code {} and details "{}"'.format(
       unknown_cygrpc_code, details)
 
 
@@ -134,19 +134,19 @@
   for batch_operation in event.batch_operations:
     operation_type = batch_operation.type
     state.due.remove(operation_type)
-    if operation_type is cygrpc.OperationType.receive_initial_metadata:
+    if operation_type == cygrpc.OperationType.receive_initial_metadata:
       state.initial_metadata = batch_operation.received_metadata
-    elif operation_type is cygrpc.OperationType.receive_message:
+    elif operation_type == cygrpc.OperationType.receive_message:
       serialized_response = batch_operation.received_message.bytes()
       if serialized_response is not None:
         response = _common.deserialize(
             serialized_response, response_deserializer)
         if response is None:
-          details = b'Exception deserializing response!'
+          details = 'Exception deserializing response!'
           _abort(state, grpc.StatusCode.INTERNAL, details)
         else:
           state.response = response
-    elif operation_type is cygrpc.OperationType.receive_status_on_client:
+    elif operation_type == cygrpc.OperationType.receive_status_on_client:
       state.trailing_metadata = batch_operation.received_metadata
       if state.code is None:
         code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
@@ -186,7 +186,7 @@
         if state.code is None and not state.cancelled:
           if serialized_request is None:
             call.cancel()
-            details = b'Exception serializing request!'
+            details = 'Exception serializing request!'
             _abort(state, grpc.StatusCode.INTERNAL, details)
             return
           else:
@@ -230,7 +230,7 @@
       if self._state.code is None:
         self._call.cancel()
         self._state.cancelled = True
-        _abort(self._state, grpc.StatusCode.CANCELLED, b'Cancelled!')
+        _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
         self._state.condition.notify_all()
       return False
 
@@ -402,7 +402,7 @@
   if serialized_request is None:
     state = _RPCState(
         (), _EMPTY_METADATA, _EMPTY_METADATA, grpc.StatusCode.INTERNAL,
-        b'Exception serializing request!')
+        'Exception serializing request!')
     rendezvous = _Rendezvous(state, None, None, deadline)
     return deadline, deadline_timespec, None, rendezvous
   else:
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index a3fb66c..b8688a0 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -97,3 +97,16 @@
 def deserialize(serialized_message, deserializer):
   return _transform(serialized_message, deserializer,
                     'Exception deserializing message!')
+
+
+def _encode(s):
+  if isinstance(s, bytes):
+    return s
+  else:
+    return s.encode('ascii')
+
+
+def fully_qualified_method(group, method):
+  group = _encode(group)
+  method = _encode(method)
+  return b'/' + group + b'/' + method
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
index 1bfe634..a09bbc7 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
@@ -55,6 +55,7 @@
   def cancel(
       self, grpc_status_code error_code=GRPC_STATUS__DO_NOT_USE,
       details=None):
+    details = str_to_bytes(details)
     if not self.is_valid:
       raise ValueError("invalid call object cannot be used from Python")
     if (details is None) != (error_code == GRPC_STATUS__DO_NOT_USE):
@@ -63,12 +64,6 @@
     cdef grpc_call_error result
     cdef char *c_details = NULL
     if error_code != GRPC_STATUS__DO_NOT_USE:
-      if isinstance(details, bytes):
-        pass
-      elif isinstance(details, basestring):
-        details = details.encode()
-      else:
-        raise TypeError("expected details to be str or bytes")
       self.references.append(details)
       c_details = details
       with nogil:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index c26bc08..866cff0 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -34,18 +34,13 @@
 
   def __cinit__(self, target, ChannelArgs arguments=None,
                 ChannelCredentials channel_credentials=None):
+    target = str_to_bytes(target)
     cdef grpc_channel_args *c_arguments = NULL
     cdef char *c_target = NULL
     self.c_channel = NULL
     self.references = []
     if arguments is not None:
       c_arguments = &arguments.c_args
-    if isinstance(target, bytes):
-      pass
-    elif isinstance(target, basestring):
-      target = target.encode()
-    else:
-      raise TypeError("expected target to be str or bytes")
     c_target = target
     if channel_credentials is None:
       with nogil:
@@ -62,25 +57,14 @@
   def create_call(self, Call parent, int flags,
                   CompletionQueue queue not None,
                   method, host, Timespec deadline not None):
+    method = str_to_bytes(method)
+    host = str_to_bytes(host)
     if queue.is_shutting_down:
       raise ValueError("queue must not be shutting down or shutdown")
-    if isinstance(method, bytes):
-      pass
-    elif isinstance(method, basestring):
-      method = method.encode()
-    else:
-      raise TypeError("expected method to be str or bytes")
     cdef char *method_c_string = method
     cdef char *host_c_string = NULL
-    if host is None:
-      pass
-    elif isinstance(host, bytes):
+    if host is not None:
       host_c_string = host
-    elif isinstance(host, basestring):
-      host = host.encode()
-      host_c_string = host
-    else:
-      raise TypeError("expected host to be str, bytes, or None")
     cdef Call operation_call = Call()
     operation_call.references = [self, method, host, queue]
     cdef grpc_call *parent_call = NULL
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
index 19a59e0..d377a67 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
@@ -54,7 +54,7 @@
 cdef class CredentialsMetadataPlugin:
 
   cdef object plugin_callback
-  cdef str plugin_name
+  cdef bytes plugin_name
 
   cdef grpc_metadata_credentials_plugin make_c_plugin(self)
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 1ba8645..470382d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -82,7 +82,7 @@
 
 cdef class CredentialsMetadataPlugin:
 
-  def __cinit__(self, object plugin_callback, str name):
+  def __cinit__(self, object plugin_callback, name):
     """
     Args:
       plugin_callback (callable): Callback accepting a service URL (str/bytes)
@@ -93,6 +93,7 @@
         successful).
       name (str): Plugin name.
     """
+    name = str_to_bytes(name)
     if not callable(plugin_callback):
       raise ValueError('expected callable plugin_callback')
     self.plugin_callback = plugin_callback
@@ -129,7 +130,8 @@
     grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil:
   def python_callback(
       Metadata metadata, grpc_status_code status,
-      const char *error_details):
+      error_details):
+    error_details = str_to_bytes(error_details)
     cb(user_data, metadata.c_metadata_array.metadata,
        metadata.c_metadata_array.count, status, error_details)
   cdef CredentialsMetadataPlugin self = <CredentialsMetadataPlugin>state
@@ -148,14 +150,7 @@
 
 def channel_credentials_ssl(pem_root_certificates,
                             SslPemKeyCertPair ssl_pem_key_cert_pair):
-  if pem_root_certificates is None:
-    pass
-  elif isinstance(pem_root_certificates, bytes):
-    pass
-  elif isinstance(pem_root_certificates, basestring):
-    pem_root_certificates = pem_root_certificates.encode()
-  else:
-    raise TypeError("expected str or bytes for pem_root_certificates")
+  pem_root_certificates = str_to_bytes(pem_root_certificates)
   cdef ChannelCredentials credentials = ChannelCredentials()
   cdef const char *c_pem_root_certificates = NULL
   if pem_root_certificates is not None:
@@ -207,12 +202,7 @@
 
 def call_credentials_service_account_jwt_access(
     json_key, Timespec token_lifetime not None):
-  if isinstance(json_key, bytes):
-    pass
-  elif isinstance(json_key, basestring):
-    json_key = json_key.encode()
-  else:
-    raise TypeError("expected json_key to be str or bytes")
+  json_key = str_to_bytes(json_key)
   cdef CallCredentials credentials = CallCredentials()
   cdef char *json_key_c_string = json_key
   with nogil:
@@ -223,12 +213,7 @@
   return credentials
 
 def call_credentials_google_refresh_token(json_refresh_token):
-  if isinstance(json_refresh_token, bytes):
-    pass
-  elif isinstance(json_refresh_token, basestring):
-    json_refresh_token = json_refresh_token.encode()
-  else:
-    raise TypeError("expected json_refresh_token to be str or bytes")
+  json_refresh_token = str_to_bytes(json_refresh_token)
   cdef CallCredentials credentials = CallCredentials()
   cdef char *json_refresh_token_c_string = json_refresh_token
   with nogil:
@@ -238,18 +223,8 @@
   return credentials
 
 def call_credentials_google_iam(authorization_token, authority_selector):
-  if isinstance(authorization_token, bytes):
-    pass
-  elif isinstance(authorization_token, basestring):
-    authorization_token = authorization_token.encode()
-  else:
-    raise TypeError("expected authorization_token to be str or bytes")
-  if isinstance(authority_selector, bytes):
-    pass
-  elif isinstance(authority_selector, basestring):
-    authority_selector = authority_selector.encode()
-  else:
-    raise TypeError("expected authority_selector to be str or bytes")
+  authorization_token = str_to_bytes(authorization_token)
+  authority_selector = str_to_bytes(authority_selector)
   cdef CallCredentials credentials = CallCredentials()
   cdef char *authorization_token_c_string = authorization_token
   cdef char *authority_selector_c_string = authority_selector
@@ -272,16 +247,10 @@
 
 def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
                            bint force_client_auth):
+  pem_root_certs = str_to_bytes(pem_root_certs)
   cdef char *c_pem_root_certs = NULL
-  if pem_root_certs is None:
-    pass
-  elif isinstance(pem_root_certs, bytes):
+  if pem_root_certs is not None: 
     c_pem_root_certs = pem_root_certs
-  elif isinstance(pem_root_certs, basestring):
-    pem_root_certs = pem_root_certs.encode()
-    c_pem_root_certs = pem_root_certs
-  else:
-    raise TypeError("expected pem_root_certs to be str or bytes")
   pem_key_cert_pairs = list(pem_key_cert_pairs)
   for pair in pem_key_cert_pairs:
     if not isinstance(pair, SslPemKeyCertPair):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
new file mode 100644
index 0000000..274f038
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
@@ -0,0 +1,39 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+# This function will ascii encode unicode string inputs if neccesary.
+# In Python3, unicode strings are the default str type.
+cdef bytes str_to_bytes(object s):
+  if s is None or isinstance(s, bytes):
+    return s
+  elif isinstance(s, unicode):
+    return s.encode('ascii')
+  else:
+    raise TypeError('Expected bytes, str, or unicode, not {}'.format(type(s)))
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index e0219b0..2e52953 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -235,18 +235,13 @@
     if data is None:
       self.c_byte_buffer = NULL
       return
-    if isinstance(data, bytes):
-      pass
-    elif isinstance(data, basestring):
-      data = data.encode()
-    elif isinstance(data, ByteBuffer):
+    if isinstance(data, ByteBuffer):
       data = (<ByteBuffer>data).bytes()
       if data is None:
         self.c_byte_buffer = NULL
         return
     else:
-      raise TypeError("expected value to be of type str, bytes, or "
-                      "ByteBuffer, not {}".format(type(data)))
+      data = str_to_bytes(data)
 
     cdef char *c_data = data
     cdef gpr_slice data_slice
@@ -302,19 +297,8 @@
 cdef class SslPemKeyCertPair:
 
   def __cinit__(self, private_key, certificate_chain):
-    if isinstance(private_key, bytes):
-      self.private_key = private_key
-    elif isinstance(private_key, basestring):
-      self.private_key = private_key.encode()
-    else:
-      raise TypeError("expected private_key to be of type str or bytes")
-    if isinstance(certificate_chain, bytes):
-      self.certificate_chain = certificate_chain
-    elif isinstance(certificate_chain, basestring):
-      self.certificate_chain = certificate_chain.encode()
-    else:
-      raise TypeError("expected certificate_chain to be of type str or bytes "
-                      "or int")
+    self.private_key = str_to_bytes(private_key)
+    self.certificate_chain = str_to_bytes(certificate_chain)
     self.c_pair.private_key = self.private_key
     self.c_pair.certificate_chain = self.certificate_chain
 
@@ -322,27 +306,16 @@
 cdef class ChannelArg:
 
   def __cinit__(self, key, value):
-    if isinstance(key, bytes):
-      self.key = key
-    elif isinstance(key, basestring):
-      self.key = key.encode()
-    else:
-      raise TypeError("expected key to be of type str or bytes")
-    if isinstance(value, bytes):
-      self.value = value
-      self.c_arg.type = GRPC_ARG_STRING
-      self.c_arg.value.string = self.value
-    elif isinstance(value, basestring):
-      self.value = value.encode()
-      self.c_arg.type = GRPC_ARG_STRING
-      self.c_arg.value.string = self.value
-    elif isinstance(value, int):
+    self.key = str_to_bytes(key)
+    self.c_arg.key = self.key
+    if isinstance(value, int):
       self.value = int(value)
       self.c_arg.type = GRPC_ARG_INTEGER
       self.c_arg.value.integer = self.value
     else:
-      raise TypeError("expected value to be of type str or bytes or int")
-    self.c_arg.key = self.key
+      self.value = str_to_bytes(value)
+      self.c_arg.type = GRPC_ARG_STRING
+      self.c_arg.value.string = self.value
 
 
 cdef class ChannelArgs:
@@ -375,18 +348,8 @@
 cdef class Metadatum:
 
   def __cinit__(self, key, value):
-    if isinstance(key, bytes):
-      self._key = key
-    elif isinstance(key, basestring):
-      self._key = key.encode()
-    else:
-      raise TypeError("expected key to be of type str or bytes")
-    if isinstance(value, bytes):
-      self._value = value
-    elif isinstance(value, basestring):
-      self._value = value.encode()
-    else:
-      raise TypeError("expected value to be of type str or bytes")
+    self._key = str_to_bytes(key)
+    self._value = str_to_bytes(value)
     self.c_metadata.key = self._key
     self.c_metadata.value = self._value
     self.c_metadata.value_length = len(self._value)
@@ -601,12 +564,7 @@
 
 def operation_send_status_from_server(
     Metadata metadata, grpc_status_code code, details, int flags):
-  if isinstance(details, bytes):
-    pass
-  elif isinstance(details, basestring):
-    details = details.encode()
-  else:
-    raise TypeError("expected a str or bytes object for details")
+  details = str_to_bytes(details)
   cdef Operation op = Operation()
   op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
   op.c_op.flags = flags
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 5594875..c8a73e6 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -103,12 +103,7 @@
 
   def add_http2_port(self, address,
                      ServerCredentials server_credentials=None):
-    if isinstance(address, bytes):
-      pass
-    elif isinstance(address, basestring):
-      address = address.encode()
-    else:
-      raise TypeError("expected address to be a str or bytes")
+    address = str_to_bytes(address)
     self.references.append(address)
     cdef int result
     cdef char *address_c_string = address
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 8823ea5..cf146f5 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -35,6 +35,7 @@
 
 # TODO(atash): figure out why the coverage tool gets confused about the Cython
 # coverage plugin when the following files don't have a '.pxi' suffix.
+include "grpc/_cython/_cygrpc/grpc_string.pyx.pxi"
 include "grpc/_cython/_cygrpc/call.pyx.pxi"
 include "grpc/_cython/_cygrpc/channel.pyx.pxi"
 include "grpc/_cython/_cygrpc/credentials.pyx.pxi"
diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py
index 11310e2..5fc4994 100644
--- a/src/python/grpcio/grpc/_links/service.py
+++ b/src/python/grpcio/grpc/_links/service.py
@@ -33,6 +33,7 @@
 import enum
 import logging
 import threading
+import six
 import time
 
 from grpc._adapter import _intermediary_low
@@ -177,7 +178,10 @@
     call = service_acceptance.call
     call.accept(self._completion_queue, call)
     try:
-      group, method = service_acceptance.method.split(b'/')[1:3]
+      service_method = service_acceptance.method
+      if six.PY3:
+          service_method = service_method.decode('latin1')
+      group, method = service_method.split('/')[1:3]
     except ValueError:
       logging.info('Illegal path "%s"!', service_acceptance.method)
       return
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index aae9f48..f4f6720 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -85,7 +85,7 @@
 
 
 def _details(state):
-  return b'' if state.details is None else state.details
+  return '' if state.details is None else state.details
 
 
 class _HandlerCallDetails(
@@ -189,7 +189,7 @@
         if request is None:
           _abort(
               state, call, cygrpc.StatusCode.internal,
-              b'Exception deserializing request!')
+              'Exception deserializing request!')
         else:
           state.request = request
         state.condition.notify_all()
@@ -340,7 +340,7 @@
           state.condition.wait()
           if state.request is None:
             if state.client is _CLOSED:
-              details = b'"{}" requires exactly one request message.'.format(
+              details = '"{}" requires exactly one request message.'.format(
                   rpc_event.request_call_details.method)
               # TODO(5992#issuecomment-220761992): really, what status code?
               _abort(
@@ -363,7 +363,7 @@
   except Exception as e:  # pylint: disable=broad-except
     with state.condition:
       if e not in state.rpc_errors:
-        details = b'Exception calling application: {}'.format(e)
+        details = 'Exception calling application: {}'.format(e)
         logging.exception(details)
         _abort(
             state, rpc_event.operation_call, cygrpc.StatusCode.unknown, details)
@@ -378,7 +378,7 @@
   except Exception as e:  # pylint: disable=broad-except
     with state.condition:
       if e not in state.rpc_errors:
-        details = b'Exception iterating responses: {}'.format(e)
+        details = 'Exception iterating responses: {}'.format(e)
         logging.exception(details)
         _abort(
             state, rpc_event.operation_call, cygrpc.StatusCode.unknown, details)
@@ -391,7 +391,7 @@
     with state.condition:
       _abort(
           state, rpc_event.operation_call, cygrpc.StatusCode.internal,
-          b'Failed to serialize response!')
+          'Failed to serialize response!')
     return None
   else:
     return serialized_response
@@ -544,7 +544,7 @@
       cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
       cygrpc.operation_send_status_from_server(
           _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
-          b'Method not found!', _EMPTY_FLAGS),
+          'Method not found!', _EMPTY_FLAGS),
   )
   rpc_state = _RPCState()
   rpc_event.operation_call.start_batch(
diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py
index 621fcf2..024808c 100644
--- a/src/python/grpcio/grpc/beta/_client_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_client_adaptations.py
@@ -30,6 +30,7 @@
 """Translates gRPC's client-side API into gRPC's client-side Beta API."""
 
 import grpc
+from grpc import _common
 from grpc._cython import cygrpc
 from grpc.beta import interfaces
 from grpc.framework.common import cardinality
@@ -48,10 +49,6 @@
 }
 
 
-def _fully_qualified_method(group, method):
-  return b'/{}/{}'.format(group, method)
-
-
 def _effective_metadata(metadata, metadata_transformer):
   non_none_metadata = () if metadata is None else metadata
   if metadata_transformer is None:
@@ -184,7 +181,7 @@
     metadata_transformer, request, request_serializer, response_deserializer):
   try:
     multi_callable = channel.unary_unary(
-        _fully_qualified_method(group, method),
+        _common.fully_qualified_method(group, method),
         request_serializer=request_serializer,
         response_deserializer=response_deserializer)
     effective_metadata = _effective_metadata(metadata, metadata_transformer)
@@ -205,7 +202,7 @@
     channel, group, method, timeout, protocol_options, metadata,
     metadata_transformer, request, request_serializer, response_deserializer):
   multi_callable = channel.unary_unary(
-      _fully_qualified_method(group, method),
+      _common.fully_qualified_method(group, method),
       request_serializer=request_serializer,
       response_deserializer=response_deserializer)
   effective_metadata = _effective_metadata(metadata, metadata_transformer)
@@ -219,7 +216,7 @@
     channel, group, method, timeout, protocol_options, metadata,
     metadata_transformer, request, request_serializer, response_deserializer):
   multi_callable = channel.unary_stream(
-      _fully_qualified_method(group, method),
+      _common.fully_qualified_method(group, method),
       request_serializer=request_serializer,
       response_deserializer=response_deserializer)
   effective_metadata = _effective_metadata(metadata, metadata_transformer)
@@ -235,7 +232,7 @@
     response_deserializer):
   try:
     multi_callable = channel.stream_unary(
-        _fully_qualified_method(group, method),
+        _common.fully_qualified_method(group, method),
         request_serializer=request_serializer,
         response_deserializer=response_deserializer)
     effective_metadata = _effective_metadata(metadata, metadata_transformer)
@@ -257,7 +254,7 @@
     metadata_transformer, request_iterator, request_serializer,
     response_deserializer):
   multi_callable = channel.stream_unary(
-      _fully_qualified_method(group, method),
+      _common.fully_qualified_method(group, method),
       request_serializer=request_serializer,
       response_deserializer=response_deserializer)
   effective_metadata = _effective_metadata(metadata, metadata_transformer)
@@ -272,7 +269,7 @@
     metadata_transformer, request_iterator, request_serializer,
     response_deserializer):
   multi_callable = channel.stream_stream(
-      _fully_qualified_method(group, method),
+      _common.fully_qualified_method(group, method),
       request_serializer=request_serializer,
       response_deserializer=response_deserializer)
   effective_metadata = _effective_metadata(metadata, metadata_transformer)
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index 52eadf2..79e6ca8 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -33,6 +33,7 @@
 import threading
 
 import grpc
+from grpc import _common
 from grpc.beta import interfaces
 from grpc.framework.common import cardinality
 from grpc.framework.common import style
@@ -287,36 +288,43 @@
           None, _adapt_stream_stream_event(implementation.stream_stream_event))
 
 
+def _flatten_method_pair_map(method_pair_map):
+  method_pair_map = method_pair_map or {}
+  flat_map = {}
+  for method_pair in method_pair_map:
+    method = _common.fully_qualified_method(method_pair[0], method_pair[1])
+    flat_map[method] = method_pair_map[method_pair]
+  return flat_map
+
+
 class _GenericRpcHandler(grpc.GenericRpcHandler):
 
   def __init__(
       self, method_implementations, multi_method_implementation,
       request_deserializers, response_serializers):
-    self._method_implementations = method_implementations
+    self._method_implementations = _flatten_method_pair_map(
+        method_implementations)
+    self._request_deserializers = _flatten_method_pair_map(
+        request_deserializers)
+    self._response_serializers = _flatten_method_pair_map(
+        response_serializers)
     self._multi_method_implementation = multi_method_implementation
-    self._request_deserializers = request_deserializers or {}
-    self._response_serializers = response_serializers or {}
 
   def service(self, handler_call_details):
-    try:
-      group_name, method_name = handler_call_details.method.split(b'/')[1:3]
-    except ValueError:
+    method_implementation = self._method_implementations.get(
+        handler_call_details.method)
+    if method_implementation is not None:
+      return _simple_method_handler(
+          method_implementation,
+          self._request_deserializers.get(handler_call_details.method),
+          self._response_serializers.get(handler_call_details.method))
+    elif self._multi_method_implementation is None:
       return None
     else:
-      method_implementation = self._method_implementations.get(
-          (group_name, method_name,))
-      if method_implementation is not None:
-        return _simple_method_handler(
-            method_implementation,
-            self._request_deserializers.get((group_name, method_name,)),
-            self._response_serializers.get((group_name, method_name,)))
-      elif self._multi_method_implementation is None:
+      try:
+        return None  #TODO(nathaniel): call the multimethod.
+      except face.NoSuchMethodError:
         return None
-      else:
-        try:
-          return None  #TODO(nathaniel): call the multimethod.
-        except face.NoSuchMethodError:
-          return None
 
 
 class _Server(interfaces.Server):
diff --git a/src/python/grpcio/tests/qps/benchmark_client.py b/src/python/grpcio/tests/qps/benchmark_client.py
index e292234..1b100bb 100644
--- a/src/python/grpcio/tests/qps/benchmark_client.py
+++ b/src/python/grpcio/tests/qps/benchmark_client.py
@@ -31,12 +31,9 @@
 
 import abc
 import time
-try:
-  import Queue as queue  # Python 2.x
-except ImportError:
-  import queue  # Python 3
 
 from concurrent import futures
+from six.moves import queue
 
 from grpc.beta import implementations
 from grpc.framework.interfaces.face import face
diff --git a/src/python/grpcio/tests/qps/client_runner.py b/src/python/grpcio/tests/qps/client_runner.py
index 2d1d981..1fd5868 100644
--- a/src/python/grpcio/tests/qps/client_runner.py
+++ b/src/python/grpcio/tests/qps/client_runner.py
@@ -34,7 +34,7 @@
 """
 
 import abc
-import thread
+import threading
 import time
 
 
@@ -61,15 +61,18 @@
     super(OpenLoopClientRunner, self).__init__(client)
     self._is_running = False
     self._interval_generator = interval_generator
+    self._dispatch_thread = threading.Thread(
+        target=self._dispatch_requests, args=())
 
   def start(self):
     self._is_running = True
     self._client.start()
-    thread.start_new_thread(self._dispatch_requests, ())
-
+    self._dispatch_thread.start()
+   
   def stop(self):
     self._is_running = False
     self._client.stop()
+    self._dispatch_thread.join()
     self._client = None
 
   def _dispatch_requests(self):
diff --git a/src/python/grpcio/tests/stress/client.py b/src/python/grpcio/tests/stress/client.py
index e2e0167..0de2532 100644
--- a/src/python/grpcio/tests/stress/client.py
+++ b/src/python/grpcio/tests/stress/client.py
@@ -30,10 +30,10 @@
 """Entry point for running stress tests."""
 
 import argparse
-import Queue
 import threading
 
 from grpc.beta import implementations
+from six.moves import queue
 from src.proto.grpc.testing import metrics_pb2
 from src.proto.grpc.testing import test_pb2
 
@@ -94,7 +94,7 @@
   test_cases = _parse_weighted_test_cases(args.test_cases)
   test_servers = args.server_addresses.split(',')
   # Propagate any client exceptions with a queue
-  exception_queue = Queue.Queue()
+  exception_queue = queue.Queue()
   stop_event = threading.Event()
   hist = histogram.Histogram(1, 1)
   runners = []
@@ -121,7 +121,7 @@
     if timeout_secs < 0:
       timeout_secs = None
     raise exception_queue.get(block=True, timeout=timeout_secs)
-  except Queue.Empty:
+  except queue.Empty:
     # No exceptions thrown, success
     pass
   finally:
diff --git a/src/python/grpcio/tests/tests.json b/src/python/grpcio/tests/tests.json
index 8dc47bf..53b2998 100644
--- a/src/python/grpcio/tests/tests.json
+++ b/src/python/grpcio/tests/tests.json
@@ -28,6 +28,7 @@
   "_crust_over_core_over_links_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest", 
   "_crust_over_core_over_links_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", 
   "_crust_over_core_over_links_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest", 
+  "_empty_message_test.EmptyMessageTest",
   "_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest", 
   "_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest", 
   "_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest", 
diff --git a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
index 22d4b01..09ebdef 100644
--- a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
+++ b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
@@ -164,15 +164,15 @@
     self.assertIsNotNone(service_accepted)
     self.assertIs(service_accepted.kind, _low.Event.Kind.SERVICE_ACCEPTED)
     self.assertIs(service_accepted.tag, service_tag)
-    self.assertEqual(method, service_accepted.service_acceptance.method)
-    self.assertEqual(self.host, service_accepted.service_acceptance.host)
+    self.assertEqual(method.encode(), service_accepted.service_acceptance.method)
+    self.assertEqual(self.host.encode(), service_accepted.service_acceptance.host)
     self.assertIsNotNone(service_accepted.service_acceptance.call)
     metadata = dict(service_accepted.metadata)
-    self.assertIn(client_metadata_key, metadata)
-    self.assertEqual(client_metadata_value, metadata[client_metadata_key])
-    self.assertIn(client_binary_metadata_key, metadata)
+    self.assertIn(client_metadata_key.encode(), metadata)
+    self.assertEqual(client_metadata_value.encode(), metadata[client_metadata_key.encode()])
+    self.assertIn(client_binary_metadata_key.encode(), metadata)
     self.assertEqual(client_binary_metadata_value,
-                     metadata[client_binary_metadata_key])
+                     metadata[client_binary_metadata_key.encode()])
     server_call = service_accepted.service_acceptance.call
     server_call.accept(self.server_completion_queue, finish_tag)
     server_call.add_metadata(server_leading_metadata_key,
@@ -186,12 +186,12 @@
     self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind)
     self.assertEqual(metadata_tag, metadata_accepted.tag)
     metadata = dict(metadata_accepted.metadata)
-    self.assertIn(server_leading_metadata_key, metadata)
-    self.assertEqual(server_leading_metadata_value,
-                     metadata[server_leading_metadata_key])
-    self.assertIn(server_leading_binary_metadata_key, metadata)
+    self.assertIn(server_leading_metadata_key.encode(), metadata)
+    self.assertEqual(server_leading_metadata_value.encode(),
+                     metadata[server_leading_metadata_key.encode()])
+    self.assertIn(server_leading_binary_metadata_key.encode(), metadata)
     self.assertEqual(server_leading_binary_metadata_value,
-                     metadata[server_leading_binary_metadata_key])
+                     metadata[server_leading_binary_metadata_key.encode()])
 
     for datum in test_data:
       client_call.write(datum, write_tag, _low.WriteFlags.WRITE_NO_COMPRESS)
@@ -277,17 +277,17 @@
     self.assertIsNone(read_accepted.bytes)
     self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind)
     self.assertEqual(finish_tag, finish_accepted.tag)
-    self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status)
+    self.assertEqual(_low.Status(_low.Code.OK, details.encode()), finish_accepted.status)
     metadata = dict(finish_accepted.metadata)
-    self.assertIn(server_trailing_metadata_key, metadata)
-    self.assertEqual(server_trailing_metadata_value,
-                     metadata[server_trailing_metadata_key])
-    self.assertIn(server_trailing_binary_metadata_key, metadata)
+    self.assertIn(server_trailing_metadata_key.encode(), metadata)
+    self.assertEqual(server_trailing_metadata_value.encode(),
+                     metadata[server_trailing_metadata_key.encode()])
+    self.assertIn(server_trailing_binary_metadata_key.encode(), metadata)
     self.assertEqual(server_trailing_binary_metadata_value,
-                     metadata[server_trailing_binary_metadata_key])
+                     metadata[server_trailing_binary_metadata_key.encode()])
     self.assertSetEqual(set(key for key, _ in finish_accepted.metadata),
-                        set((server_trailing_metadata_key,
-                             server_trailing_binary_metadata_key,)))
+                        set((server_trailing_metadata_key.encode(),
+                             server_trailing_binary_metadata_key.encode(),)))
 
     self.assertSequenceEqual(test_data, server_data)
     self.assertSequenceEqual(test_data, client_data)
@@ -302,7 +302,8 @@
     self._perform_echo_test([_BYTE_SEQUENCE])
 
   def testManyOneByteEchoes(self):
-    self._perform_echo_test(_BYTE_SEQUENCE)
+    self._perform_echo_test(
+        [_BYTE_SEQUENCE[i:i+1] for i in range(len(_BYTE_SEQUENCE))])
 
   def testManyManyByteEchoes(self):
     self._perform_echo_test(_BYTE_SEQUENCE_SEQUENCE)
@@ -409,7 +410,7 @@
 
     finish_event = self.client_events.get()
     self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind)
-    self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'),
+    self.assertEqual(_low.Status(_low.Code.CANCELLED, b'Cancelled'),
                                  finish_event.status)
 
     self.assertSequenceEqual(test_data, server_data)
diff --git a/src/python/grpcio/tests/unit/_adapter/_low_test.py b/src/python/grpcio/tests/unit/_adapter/_low_test.py
index ec46617..e09a1f2 100644
--- a/src/python/grpcio/tests/unit/_adapter/_low_test.py
+++ b/src/python/grpcio/tests/unit/_adapter/_low_test.py
@@ -148,11 +148,11 @@
     # Check that Python's user agent string is a part of the full user agent
     # string
     received_initial_metadata_dict = dict(received_initial_metadata)
-    self.assertIn('user-agent', received_initial_metadata_dict)
-    self.assertIn('Python-gRPC-{}'.format(_grpcio_metadata.__version__),
-                  received_initial_metadata_dict['user-agent'])
-    self.assertEqual(method, request_event.call_details.method)
-    self.assertEqual(host, request_event.call_details.host)
+    self.assertIn(b'user-agent', received_initial_metadata_dict)
+    self.assertIn('Python-gRPC-{}'.format(_grpcio_metadata.__version__).encode(),
+                  received_initial_metadata_dict[b'user-agent'])
+    self.assertEqual(method.encode(), request_event.call_details.method)
+    self.assertEqual(host.encode(), request_event.call_details.host)
     self.assertLess(abs(deadline - request_event.call_details.deadline),
                     deadline_tolerance)
 
@@ -198,12 +198,12 @@
             test_common.metadata_transmitted(server_initial_metadata,
                                              client_result.initial_metadata))
       elif client_result.type == _types.OpType.RECV_MESSAGE:
-        self.assertEqual(response, client_result.message)
+        self.assertEqual(response.encode(), client_result.message)
       elif client_result.type == _types.OpType.RECV_STATUS_ON_CLIENT:
         self.assertTrue(
             test_common.metadata_transmitted(server_trailing_metadata,
                                              client_result.trailing_metadata))
-        self.assertEqual(server_status_details, client_result.status.details)
+        self.assertEqual(server_status_details.encode(), client_result.status.details)
         self.assertEqual(server_status_code, client_result.status.code)
     self.assertEqual(set([
           _types.OpType.SEND_INITIAL_METADATA,
@@ -220,7 +220,7 @@
       self.assertNotIn(client_result.type, found_server_op_types)
       found_server_op_types.add(server_result.type)
       if server_result.type == _types.OpType.RECV_MESSAGE:
-        self.assertEqual(request, server_result.message)
+        self.assertEqual(request.encode(), server_result.message)
       elif server_result.type == _types.OpType.RECV_CLOSE_ON_SERVER:
         self.assertFalse(server_result.cancelled)
     self.assertEqual(set([
diff --git a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
index 4039c1b..a006a20 100644
--- a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
@@ -37,7 +37,7 @@
 from tests.unit import resources
 
 
-_SSL_HOST_OVERRIDE = 'foo.test.google.fr'
+_SSL_HOST_OVERRIDE = b'foo.test.google.fr'
 _CALL_CREDENTIALS_METADATA_KEY = 'call-creds-key'
 _CALL_CREDENTIALS_METADATA_VALUE = 'call-creds-value'
 _EMPTY_FLAGS = 0
diff --git a/src/python/grpcio/tests/unit/_empty_message_test.py b/src/python/grpcio/tests/unit/_empty_message_test.py
new file mode 100644
index 0000000..f324f62
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_empty_message_test.py
@@ -0,0 +1,137 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+import grpc
+from grpc.framework.foundation import logging_pool
+
+from tests.unit.framework.common import test_constants
+
+_REQUEST = b''
+_RESPONSE = b''
+
+_UNARY_UNARY = b'/test/UnaryUnary'
+_UNARY_STREAM = b'/test/UnaryStream'
+_STREAM_UNARY = b'/test/StreamUnary'
+_STREAM_STREAM = b'/test/StreamStream'
+
+
+def handle_unary_unary(request, servicer_context):
+  return _RESPONSE
+
+
+def handle_unary_stream(request, servicer_context):
+  for _ in range(test_constants.STREAM_LENGTH):
+    yield _RESPONSE
+
+
+def handle_stream_unary(request_iterator, servicer_context):
+  for request in request_iterator:
+    pass
+  return _RESPONSE
+
+
+def handle_stream_stream(request_iterator, servicer_context):
+  for request in request_iterator:
+    yield _RESPONSE
+
+
+class _MethodHandler(grpc.RpcMethodHandler):
+
+  def __init__(self, request_streaming, response_streaming):
+    self.request_streaming = request_streaming
+    self.response_streaming = response_streaming
+    self.request_deserializer = None
+    self.response_serializer = None
+    self.unary_unary = None
+    self.unary_stream = None
+    self.stream_unary = None
+    self.stream_stream = None
+    if self.request_streaming and self.response_streaming:
+      self.stream_stream = handle_stream_stream
+    elif self.request_streaming:
+      self.stream_unary = handle_stream_unary
+    elif self.response_streaming:
+      self.unary_stream = handle_unary_stream
+    else:
+      self.unary_unary = handle_unary_unary
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+  def service(self, handler_call_details):
+    if handler_call_details.method == _UNARY_UNARY:
+      return _MethodHandler(False, False)
+    elif handler_call_details.method == _UNARY_STREAM:
+      return _MethodHandler(False, True)
+    elif handler_call_details.method == _STREAM_UNARY:
+      return _MethodHandler(True, False)
+    elif handler_call_details.method == _STREAM_STREAM:
+      return _MethodHandler(True, True)
+    else:
+      return None
+
+
+class EmptyMessageTest(unittest.TestCase):
+
+  def setUp(self):
+    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+    self._server = grpc.server((_GenericHandler(),), self._server_pool)
+    port = self._server.add_insecure_port('[::]:0')
+    self._server.start()
+    self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+  def tearDown(self):
+    self._server.stop(0)
+
+  def testUnaryUnary(self):
+    response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST)
+    self.assertEqual(_RESPONSE, response)
+
+  def testUnaryStream(self):
+    response_iterator = self._channel.unary_stream(_UNARY_STREAM)(_REQUEST)
+    self.assertSequenceEqual(
+        [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
+
+  def testStreamUnary(self):
+    response = self._channel.stream_unary(_STREAM_UNARY)(
+        [_REQUEST] * test_constants.STREAM_LENGTH)
+    self.assertEqual(_RESPONSE, response)
+
+  def testStreamStream(self):
+    response_iterator = self._channel.stream_stream(_STREAM_STREAM)(
+        [_REQUEST] * test_constants.STREAM_LENGTH)
+    self.assertSequenceEqual(
+        [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
+
diff --git a/src/python/grpcio/tests/unit/_links/_transmission_test.py b/src/python/grpcio/tests/unit/_links/_transmission_test.py
index 888684d..1f6edd1 100644
--- a/src/python/grpcio/tests/unit/_links/_transmission_test.py
+++ b/src/python/grpcio/tests/unit/_links/_transmission_test.py
@@ -153,7 +153,7 @@
         invocation_mate.tickets()[-1].termination,
         links.Ticket.Termination.COMPLETION)
     self.assertIs(invocation_mate.tickets()[-1].code, test_code)
-    self.assertEqual(invocation_mate.tickets()[-1].message, test_message)
+    self.assertEqual(invocation_mate.tickets()[-1].message, test_message.encode())
 
   def _perform_scenario_test(self, scenario):
     test_operation_id = object()
diff --git a/src/python/grpcio/tests/unit/_rpc_test.py b/src/python/grpcio/tests/unit/_rpc_test.py
index 1c7a14c..b33bff4 100644
--- a/src/python/grpcio/tests/unit/_rpc_test.py
+++ b/src/python/grpcio/tests/unit/_rpc_test.py
@@ -29,6 +29,8 @@
 
 """Test of gRPC Python's application-layer API."""
 
+from __future__ import division
+
 import itertools
 import threading
 import unittest
@@ -41,9 +43,9 @@
 from tests.unit.framework.common import test_control
 
 _SERIALIZE_REQUEST = lambda bytestring: bytestring * 2
-_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) / 2:]
+_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) // 2:]
 _SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
-_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) / 3]
+_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
 
 _UNARY_UNARY = b'/test/UnaryUnary'
 _UNARY_STREAM = b'/test/UnaryStream'
@@ -189,7 +191,7 @@
     self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
     self._server.start()
 
-    self._channel = grpc.insecure_channel(b'localhost:%d' % port)
+    self._channel = grpc.insecure_channel('localhost:%d' % port)
 
   # TODO(nathaniel): Why is this necessary, and only in some development
   # environments?
diff --git a/src/python/grpcio/tests/unit/beta/_beta_features_test.py b/src/python/grpcio/tests/unit/beta/_beta_features_test.py
index bb2893a..3a9701b 100644
--- a/src/python/grpcio/tests/unit/beta/_beta_features_test.py
+++ b/src/python/grpcio/tests/unit/beta/_beta_features_test.py
@@ -42,8 +42,8 @@
 
 _SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
 
-_PER_RPC_CREDENTIALS_METADATA_KEY = 'my-call-credentials-metadata-key'
-_PER_RPC_CREDENTIALS_METADATA_VALUE = 'my-call-credentials-metadata-value'
+_PER_RPC_CREDENTIALS_METADATA_KEY = b'my-call-credentials-metadata-key'
+_PER_RPC_CREDENTIALS_METADATA_VALUE = b'my-call-credentials-metadata-value'
 
 _GROUP = 'group'
 _UNARY_UNARY = 'unary-unary'
diff --git a/src/python/grpcio/tests/unit/beta/_not_found_test.py b/src/python/grpcio/tests/unit/beta/_not_found_test.py
index 44fcd1e..37b8c49 100644
--- a/src/python/grpcio/tests/unit/beta/_not_found_test.py
+++ b/src/python/grpcio/tests/unit/beta/_not_found_test.py
@@ -61,7 +61,7 @@
 
   def test_future_stream_unary_not_found(self):
     rpc_future = self._generic_stub.future_stream_unary(
-        'grupe', 'mevvod', b'def', test_constants.LONG_TIMEOUT)
+        'grupe', 'mevvod', [b'def'], test_constants.LONG_TIMEOUT)
     with self.assertRaises(face.LocalError) as exception_assertion_context:
       rpc_future.result()
     self.assertIs(
diff --git a/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py b/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py
index 4f8e26c..5d16bf9 100644
--- a/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py
+++ b/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py
@@ -29,6 +29,8 @@
 
 """Tests of the base interface of RPC Framework."""
 
+from __future__ import division
+
 import logging
 import random
 import threading
@@ -54,13 +56,13 @@
     return request + request
 
   def deserialize_request(self, serialized_request):
-    return serialized_request[:len(serialized_request) / 2]
+    return serialized_request[:len(serialized_request) // 2]
 
   def serialize_response(self, response):
     return response * 3
 
   def deserialize_response(self, serialized_response):
-    return serialized_response[2 * len(serialized_response) / 3:]
+    return serialized_response[2 * len(serialized_response) // 3:]
 
 
 def _advance(quadruples, operator, controller):
diff --git a/src/python/grpcio/tests/unit/test_common.py b/src/python/grpcio/tests/unit/test_common.py
index 7b4d20d..b779f65 100644
--- a/src/python/grpcio/tests/unit/test_common.py
+++ b/src/python/grpcio/tests/unit/test_common.py
@@ -61,6 +61,10 @@
   original = collections.defaultdict(list)
   for key_value_pair in original_metadata:
     key, value = tuple(key_value_pair)
+    if not isinstance(key, bytes):
+      key = key.encode()
+    if not isinstance(value, bytes):
+      value = value.encode()
     original[key].append(value)
   transmitted = collections.defaultdict(list)
   for key_value_pair in transmitted_metadata:
diff --git a/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
index c11cefd..e395379 100644
--- a/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
@@ -34,6 +34,12 @@
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../cxx_deps.include"/>
   <%include file="../../run_tests_addons.include"/>
+  
+  # The clang-3.6 symlink for the default clang version was added
+  # to Ubuntu 16.04 recently, so make sure it's installed.
+  # Also install clang3.7.
+  RUN apt-get update && apt-get -y install clang-3.6 clang-3.7 && apt-get clean
+  
   # Define the default command.
   CMD ["bash"]
   
\ No newline at end of file
diff --git a/test/core/client_config/uri_fuzzer_test.c b/test/core/client_config/uri_fuzzer_test.c
index eb976fc..f297140 100644
--- a/test/core/client_config/uri_fuzzer_test.c
+++ b/test/core/client_config/uri_fuzzer_test.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -38,6 +39,9 @@
 
 #include "src/core/ext/client_config/uri_parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   char *s = gpr_malloc(size + 1);
   memcpy(s, data, size);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index d013dae..13b8bf7 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -50,7 +50,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // logging
 
-static const bool squelch = true;
+bool squelch = true;
+bool leak_check = true;
 
 static void dont_log(gpr_log_func_args *args) {}
 
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index 6cb0dcc..0610194 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -41,7 +41,8 @@
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
-static const bool squelch = !true;
+bool squelch = true;
+bool leak_check = true;
 
 static void discard_write(gpr_slice slice) {}
 
@@ -51,9 +52,10 @@
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_metadata_hash_seed(0);
-  // struct grpc_memory_counters counters;
+  struct grpc_memory_counters counters;
   if (squelch) gpr_set_log_function(dont_log);
-  // grpc_memory_counters_init();
+  grpc_memory_counters_init();
+  if (leak_check) grpc_memory_counters_init();
   grpc_init();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -156,8 +158,10 @@
     grpc_byte_buffer_destroy(response_payload_recv);
   }
   grpc_shutdown();
-  // counters = grpc_memory_counters_snapshot();
-  // grpc_memory_counters_destroy();
-  // GPR_ASSERT(counters.total_size_relative == 0);
+  if (leak_check) {
+    counters = grpc_memory_counters_snapshot();
+    grpc_memory_counters_destroy();
+    GPR_ASSERT(counters.total_size_relative == 0);
+  }
   return 0;
 }
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 1c36d32..80f568a 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -38,7 +38,8 @@
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
-static const bool squelch = !true;
+bool squelch = true;
+bool leak_check = true;
 
 static void discard_write(gpr_slice slice) {}
 
@@ -49,9 +50,9 @@
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_metadata_hash_seed(0);
-  // struct grpc_memory_counters counters;
+  struct grpc_memory_counters counters;
   if (squelch) gpr_set_log_function(dont_log);
-  // grpc_memory_counters_init();
+  if (leak_check) grpc_memory_counters_init();
   grpc_init();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -120,8 +121,10 @@
   grpc_server_destroy(server);
   grpc_completion_queue_destroy(cq);
   grpc_shutdown();
-  // counters = grpc_memory_counters_snapshot();
-  // grpc_memory_counters_destroy();
-  // GPR_ASSERT(counters.total_size_relative == 0);
+  if (leak_check) {
+    counters = grpc_memory_counters_snapshot();
+    grpc_memory_counters_destroy();
+    GPR_ASSERT(counters.total_size_relative == 0);
+  }
   return 0;
 }
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436 b/test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436
new file mode 100644
index 0000000..c61aff8
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24 b/test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24
new file mode 100644
index 0000000..d480552
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2 b/test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2
new file mode 100644
index 0000000..20b4cf8
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72 b/test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72
new file mode 100644
index 0000000..c832262
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528 b/test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528
new file mode 100644
index 0000000..56a2f93
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714 b/test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714
new file mode 100644
index 0000000..18d908f
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24 b/test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24
new file mode 100644
index 0000000..cc5d498
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce b/test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce
new file mode 100644
index 0000000..1ac7cc9
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95 b/test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95
new file mode 100644
index 0000000..17b8d7d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3 b/test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3
new file mode 100644
index 0000000..a82790d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701 b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701
new file mode 100644
index 0000000..8bc2de9
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a b/test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a
new file mode 100644
index 0000000..e6ea532
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2
new file mode 100644
index 0000000..e3eab9e
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e
new file mode 100644
index 0000000..b8fa2c0
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0
new file mode 100644
index 0000000..54411c4
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5
new file mode 100644
index 0000000..4364289
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72
new file mode 100644
index 0000000..c832262
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0
new file mode 100644
index 0000000..70b2eec
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe
new file mode 100644
index 0000000..0063c63
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342
new file mode 100644
index 0000000..3a231db
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275
new file mode 100644
index 0000000..1a21346
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b
new file mode 100644
index 0000000..c00d51d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65
new file mode 100644
index 0000000..171446c
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65
Binary files differ
diff --git a/test/core/http/request_fuzzer.c b/test/core/http/request_fuzzer.c
index aac6cbb..5941401 100644
--- a/test/core/http/request_fuzzer.c
+++ b/test/core/http/request_fuzzer.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -38,6 +39,9 @@
 
 #include "src/core/lib/http/parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_http_parser parser;
   grpc_http_request request;
diff --git a/test/core/http/response_fuzzer.c b/test/core/http/response_fuzzer.c
index c453e1d..acde7c8 100644
--- a/test/core/http/response_fuzzer.c
+++ b/test/core/http/response_fuzzer.c
@@ -38,6 +38,9 @@
 
 #include "src/core/lib/http/parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_http_parser parser;
   grpc_http_response response;
diff --git a/test/core/json/fuzzer.c b/test/core/json/fuzzer.c
index e94b41c..26c5c25 100644
--- a/test/core/json/fuzzer.c
+++ b/test/core/json/fuzzer.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -40,6 +41,9 @@
 #include "src/core/lib/json/json.h"
 #include "test/core/util/memory_counters.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   char *s;
   struct grpc_memory_counters counters;
diff --git a/test/core/nanopb/fuzzer_response.c b/test/core/nanopb/fuzzer_response.c
index b4e3860..21a5d7b 100644
--- a/test/core/nanopb/fuzzer_response.c
+++ b/test/core/nanopb/fuzzer_response.c
@@ -38,6 +38,9 @@
 
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size);
   grpc_grpclb_response *response;
diff --git a/test/core/nanopb/fuzzer_serverlist.c b/test/core/nanopb/fuzzer_serverlist.c
index d4ec74f..df2044d 100644
--- a/test/core/nanopb/fuzzer_serverlist.c
+++ b/test/core/nanopb/fuzzer_serverlist.c
@@ -38,6 +38,9 @@
 
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size);
   grpc_grpclb_serverlist *serverlist;
diff --git a/test/core/surface/sequential_connectivity_test.c b/test/core/surface/sequential_connectivity_test.c
index 0354cfa..2fba392 100644
--- a/test/core/surface/sequential_connectivity_test.c
+++ b/test/core/surface/sequential_connectivity_test.c
@@ -33,6 +33,7 @@
 
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
@@ -127,6 +128,7 @@
   grpc_completion_queue_destroy(cq);
 
   grpc_shutdown();
+  gpr_free(addr);
 }
 
 static void insecure_test_add_port(grpc_server *server, const char *addr) {
@@ -147,6 +149,7 @@
   grpc_server_credentials *ssl_creds =
       grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
   grpc_server_add_secure_http2_port(server, addr, ssl_creds);
+  grpc_server_credentials_release(ssl_creds);
 }
 
 static grpc_channel *secure_test_create_channel(const char *addr) {
@@ -160,6 +163,7 @@
   grpc_channel *channel =
       grpc_secure_channel_create(ssl_creds, addr, new_client_args, NULL);
   grpc_channel_args_destroy(new_client_args);
+  grpc_channel_credentials_release(ssl_creds);
   return channel;
 }
 
diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
index 7c2efc3..b7f68e0 100644
--- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
+++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
@@ -40,12 +40,15 @@
 
 #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 static void onhdr(void *ud, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); }
 static void dont_log(gpr_log_func_args *args) {}
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_metadata_hash_seed(0);
-  gpr_set_log_function(dont_log);
+  if (squelch) gpr_set_log_function(dont_log);
   grpc_init();
   grpc_chttp2_hpack_parser parser;
   grpc_chttp2_hpack_parser_init(&parser);
diff --git a/test/core/util/one_corpus_entry_fuzzer.c b/test/core/util/one_corpus_entry_fuzzer.c
index 2a23d00..95ae4cf 100644
--- a/test/core/util/one_corpus_entry_fuzzer.c
+++ b/test/core/util/one_corpus_entry_fuzzer.c
@@ -31,13 +31,20 @@
  *
  */
 
+#include <stdbool.h>
+
 #include <grpc/support/log.h>
 #include "src/core/lib/iomgr/load_file.h"
 
 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
 
+extern bool squelch;
+extern bool leak_check;
+
 int main(int argc, char **argv) {
   gpr_slice buffer;
+  squelch = false;
+  leak_check = false;
   GPR_ASSERT(
       GRPC_LOG_IF_ERROR("load_file", grpc_load_file(argv[1], 0, &buffer)));
   LLVMFuzzerTestOneInput(GPR_SLICE_START_PTR(buffer), GPR_SLICE_LENGTH(buffer));
diff --git a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
index 02d3c0d..d356433 100644
--- a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
@@ -82,5 +82,11 @@
 
 RUN mkdir /var/local/jenkins
 
+
+# The clang-3.6 symlink for the default clang version was added
+# to Ubuntu 16.04 recently, so make sure it's installed.
+# Also install clang3.7.
+RUN apt-get update && apt-get -y install clang-3.6 clang-3.7 && apt-get clean
+
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index dc47842..9b8d1d1 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -69,6 +69,10 @@
   python-pip \
   python-setuptools \
   python-yaml \
+  python3-dev \
+  python3-pip \
+  python3-setuptools \
+  python3-yaml \
   telnet \
   unzip \
   wget \
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index 4cc6881..b1c90df 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -34,6 +34,7 @@
 cd $(dirname $0)/../..
 
 TOX_PYTHON_ENV="$1"
+PY_VERSION="${TOX_PYTHON_ENV: -2}"
 
 ROOT=`pwd`
 export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG
@@ -51,11 +52,25 @@
 
 tox -e ${TOX_PYTHON_ENV} --notest
 
+# We force the .so naming convention in PEP 3149 for side by side installation support
+# Note this is the default in Python3, but explicitly disabled for Darwin, so we only
+# use this hack for our testing environment.
+if [ "$PY_VERSION" -gt "27" ]
+then
+  mv $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so.backup || true
+fi
+
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py build
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py build_py
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py build_ext --inplace
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py gather --test
 
+if [ "$PY_VERSION" -gt "27" ]
+then
+  mv $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so $ROOT/src/python/grpcio/grpc/_cython/cygrpc.cpython-${PY_VERSION}m.so || true
+  mv $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so.backup $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so || true
+fi
+
 # Build the health checker
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/src/python/grpcio_health_checking/setup.py build
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/src/python/grpcio_health_checking/setup.py build_py
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index 7a3ce6b..8059059 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -55,3 +55,4 @@
 mkdir -p $ROOT/reports
 rm -rf $ROOT/reports/python-coverage
 (mv -T $ROOT/htmlcov $ROOT/reports/python-coverage) || true
+
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index cbf77ae..1b4d1b7 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -246,11 +246,17 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def _clang_make_options(self):
-    return ['CC=clang', 'CXX=clang++', 'LD=clang', 'LDXX=clang++']
+  def _clang_make_options(self, version_suffix=''):
+    return ['CC=clang%s' % version_suffix,
+            'CXX=clang++%s' % version_suffix,
+            'LD=clang%s' % version_suffix,
+            'LDXX=clang++%s' % version_suffix]
 
-  def _gcc44_make_options(self):
-    return ['CC=gcc-4.4', 'CXX=g++-4.4', 'LD=gcc-4.4', 'LDXX=g++-4.4']
+  def _gcc_make_options(self, version_suffix):
+    return ['CC=gcc%s' % version_suffix,
+            'CXX=g++%s' % version_suffix,
+            'LD=gcc%s' % version_suffix,
+            'LDXX=g++%s' % version_suffix]
 
   def _compiler_options(self, use_docker, compiler):
     """Returns docker distro and make options to use for given compiler."""
@@ -260,13 +266,20 @@
     if compiler == 'gcc4.9' or compiler == 'default':
       return ('jessie', [])
     elif compiler == 'gcc4.4':
-      return ('wheezy', self._gcc44_make_options())
+      return ('wheezy', self._gcc_make_options(version_suffix='-4.4'))
+    elif compiler == 'gcc4.6':
+      return ('wheezy', self._gcc_make_options(version_suffix='-4.6'))
     elif compiler == 'gcc5.3':
       return ('ubuntu1604', [])
     elif compiler == 'clang3.4':
+      # on ubuntu1404, clang-3.4 alias doesn't exist, just use 'clang'
       return ('ubuntu1404', self._clang_make_options())
+    elif compiler == 'clang3.5':
+      return ('jessie', self._clang_make_options(version_suffix='-3.5'))
     elif compiler == 'clang3.6':
-      return ('ubuntu1604', self._clang_make_options())
+      return ('ubuntu1604', self._clang_make_options(version_suffix='-3.6'))
+    elif compiler == 'clang3.7':
+      return ('ubuntu1604', self._clang_make_options(version_suffix='-3.7'))
     else:
       raise Exception('Compiler %s not supported.' % compiler)
 
@@ -374,7 +387,7 @@
   def configure(self, config, args):
     self.config = config
     self.args = args
-    self._tox_env = self._get_tox_env(self.args.compiler)
+    self._tox_envs = self._get_tox_envs(self.args.compiler)
 
   def test_specs(self):
     # load list of known test suites
@@ -386,19 +399,21 @@
       os.path.abspath('src/python/grpcio_health_checking'))
     if self.config.build_config != 'gcov':
       return [self.config.job_spec(
-          ['tools/run_tests/run_python.sh', self._tox_env],
+          ['tools/run_tests/run_python.sh', tox_env],
           None,
           environ=dict(environment.items() +
                        [('GRPC_PYTHON_TESTRUNNER_FILTER', suite_name)]),
-          shortname='py.test.%s' % suite_name,
+          shortname='%s.test.%s' % (tox_env, suite_name),
           timeout_seconds=5*60)
-          for suite_name in tests_json]
+          for suite_name in tests_json
+          for tox_env in self._tox_envs]
     else:
-      return [self.config.job_spec(['tools/run_tests/run_python.sh'],
+      return [self.config.job_spec(['tools/run_tests/run_python.sh', tox_env],
                                    None,
                                    environ=environment,
-                                   shortname='py.test.coverage',
-                                   timeout_seconds=15*60)]
+                                   shortname='%s.test.coverage' % tox_env,
+                                   timeout_seconds=15*60)
+                                   for tox_env in self._tox_envs]
 
 
   def pre_build_steps(self):
@@ -411,7 +426,8 @@
     return []
 
   def build_steps(self):
-    return [['tools/run_tests/build_python.sh', self._tox_env]]
+    return [['tools/run_tests/build_python.sh', tox_env] 
+            for tox_env in self._tox_envs]
 
   def post_tests_steps(self):
     return []
@@ -422,12 +438,14 @@
   def dockerfile_dir(self):
     return 'tools/dockerfile/test/python_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
-  def _get_tox_env(self, compiler):
+  def _get_tox_envs(self, compiler):
     """Returns name of tox environment based on selected compiler."""
-    if compiler == 'python2.7' or compiler == 'default':
-      return 'py27'
+    if compiler == 'default':
+      return ('py27', 'py34')
+    elif compiler == 'python2.7':
+      return ('py27',)
     elif compiler == 'python3.4':
-      return 'py34'
+      return ('py34',)
     else:
       raise Exception('Compiler %s not supported.' % compiler)
 
@@ -816,8 +834,8 @@
                   help='Selects architecture to target. For some platforms "default" is the only supported choice.')
 argp.add_argument('--compiler',
                   choices=['default',
-                           'gcc4.4', 'gcc4.9', 'gcc5.3',
-                           'clang3.4', 'clang3.6',
+                           'gcc4.4', 'gcc4.6', 'gcc4.9', 'gcc5.3',
+                           'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
                            'vs2010', 'vs2013', 'vs2015',
                            'python2.7', 'python3.4',
                            'node0.12', 'node4', 'node5'],
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index dfc7bc3..114e085 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -75033,6 +75033,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/05c3a0390d0f52d241728926fa901599a47e4606"
     ], 
     "ci_platforms": [
@@ -75067,6 +75084,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/06bd2f82fefb9943787d63ea359f9b77072380c2"
     ], 
     "ci_platforms": [
@@ -75866,6 +75900,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206"
     ], 
     "ci_platforms": [
@@ -76495,6 +76546,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/39ea47bb.bin"
     ], 
     "ci_platforms": [
@@ -76682,6 +76750,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/407607d2.bin"
     ], 
     "ci_platforms": [
@@ -76716,6 +76801,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/418f392319c44d06a018ce4c62569d527829177a"
     ], 
     "ci_platforms": [
@@ -77073,6 +77175,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/4f97bd97ab5dc6b4c0f62f8459be8a9593dc83b3"
     ], 
     "ci_platforms": [
@@ -77617,6 +77736,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/61e798bdd49b339983fea4ccfe18efe44afbd69b"
     ], 
     "ci_platforms": [
@@ -78416,6 +78552,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/8b186384.bin"
     ], 
     "ci_platforms": [
@@ -78790,6 +78943,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/9a176b6f7e0dc5f681a1788d8954f76fabd08cad"
     ], 
     "ci_platforms": [
@@ -80065,6 +80235,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809"
     ], 
     "ci_platforms": [
@@ -80558,6 +80745,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/ed8da77f.bin"
     ], 
     "ci_platforms": [
@@ -81051,6 +81255,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-082763e16153cb6b8f3f5308cd060e822f475e5a"
     ], 
     "ci_platforms": [
@@ -81068,6 +81289,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0aa52e00ddd54f8e129430852c2da95650c354b0"
     ], 
     "ci_platforms": [
@@ -81170,6 +81408,57 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-3991c873ba814d0cd03a67d25fff0c8fe8713aca"
     ], 
     "ci_platforms": [
@@ -81204,6 +81493,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-4c6da955e4c101b81a62b2f8e934d94a62ae534b"
     ], 
     "ci_platforms": [
@@ -81255,6 +81561,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-63ebf780ee6c2003eba622686a4bf94c503ad96e"
     ], 
     "ci_platforms": [
@@ -81408,6 +81731,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9a176b6f7e0dc5f681a1788d8954f76fabd08cad"
     ], 
     "ci_platforms": [
@@ -81442,6 +81782,40 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a61a28cf78149518466b87e5463ec5c771dc504e"
     ], 
     "ci_platforms": [
@@ -81714,6 +82088,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f67be653815f6c2c10eea55c8009e1167ac9c20b"
     ], 
     "ci_platforms": [