diff --git a/examples/python/multiplex/.gitignore b/examples/python/multiplex/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0d20b6487c61e7d1bde93acf4a14b7a89083a16d
--- /dev/null
+++ b/examples/python/multiplex/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/examples/python/multiplex/README.md b/examples/python/multiplex/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..bad3a42b3704128133f0cb9f75a8cd776ef22f0a
--- /dev/null
+++ b/examples/python/multiplex/README.md
@@ -0,0 +1 @@
+An example showing two stubs sharing a channel and two servicers sharing a server.
diff --git a/examples/python/multiplex/helloworld_pb2.py b/examples/python/multiplex/helloworld_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ce33fbf2bf36f011a2a871ab0d48cc926c60d1d
--- /dev/null
+++ b/examples/python/multiplex/helloworld_pb2.py
@@ -0,0 +1,204 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: helloworld.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='helloworld.proto',
+  package='helloworld',
+  syntax='proto3',
+  serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_HELLOREQUEST = _descriptor.Descriptor(
+  name='HelloRequest',
+  full_name='helloworld.HelloRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='helloworld.HelloRequest.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=32,
+  serialized_end=60,
+)
+
+
+_HELLOREPLY = _descriptor.Descriptor(
+  name='HelloReply',
+  full_name='helloworld.HelloReply',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='message', full_name='helloworld.HelloReply.message', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=62,
+  serialized_end=91,
+)
+
+DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
+DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
+
+HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(
+  DESCRIPTOR = _HELLOREQUEST,
+  __module__ = 'helloworld_pb2'
+  # @@protoc_insertion_point(class_scope:helloworld.HelloRequest)
+  ))
+_sym_db.RegisterMessage(HelloRequest)
+
+HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict(
+  DESCRIPTOR = _HELLOREPLY,
+  __module__ = 'helloworld_pb2'
+  # @@protoc_insertion_point(class_scope:helloworld.HelloReply)
+  ))
+_sym_db.RegisterMessage(HelloReply)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
+import grpc
+from grpc.beta import implementations as beta_implementations
+from grpc.beta import interfaces as beta_interfaces
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+
+class GreeterStub(object):
+  """The greeting service definition.
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.SayHello = channel.unary_unary(
+        '/helloworld.Greeter/SayHello',
+        request_serializer=HelloRequest.SerializeToString,
+        response_deserializer=HelloReply.FromString,
+        )
+
+
+class GreeterServicer(object):
+  """The greeting service definition.
+  """
+
+  def SayHello(self, request, context):
+    """Sends a greeting
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_GreeterServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'SayHello': grpc.unary_unary_rpc_method_handler(
+          servicer.SayHello,
+          request_deserializer=HelloRequest.FromString,
+          response_serializer=HelloReply.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'helloworld.Greeter', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
+
+
+class BetaGreeterServicer(object):
+  """The greeting service definition.
+  """
+  def SayHello(self, request, context):
+    """Sends a greeting
+    """
+    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+class BetaGreeterStub(object):
+  """The greeting service definition.
+  """
+  def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+    """Sends a greeting
+    """
+    raise NotImplementedError()
+  SayHello.future = None
+
+
+def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+  request_deserializers = {
+    ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString,
+  }
+  response_serializers = {
+    ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString,
+  }
+  method_implementations = {
+    ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
+  }
+  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+  return beta_implementations.server(method_implementations, options=server_options)
+
+
+def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+  request_serializers = {
+    ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString,
+  }
+  response_deserializers = {
+    ('helloworld.Greeter', 'SayHello'): HelloReply.FromString,
+  }
+  cardinalities = {
+    'SayHello': cardinality.Cardinality.UNARY_UNARY,
+  }
+  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+  return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
+# @@protoc_insertion_point(module_scope)
diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e8162926b777f3f50b53dd76608e8d404182cde
--- /dev/null
+++ b/examples/python/multiplex/multiplex_client.py
@@ -0,0 +1,139 @@
+# 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.
+
+"""A client that makes both Greeter and RouteGuide RPCs."""
+
+from __future__ import print_function
+
+import random
+import time
+
+import grpc
+
+import helloworld_pb2
+import route_guide_pb2
+import route_guide_resources
+
+
+def make_route_note(message, latitude, longitude):
+  return route_guide_pb2.RouteNote(
+      message=message,
+      location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
+
+
+def guide_get_one_feature(route_guide_stub, point):
+  feature = route_guide_stub.GetFeature(point)
+  if not feature.location:
+    print("Server returned incomplete feature")
+    return
+
+  if feature.name:
+    print("Feature called %s at %s" % (feature.name, feature.location))
+  else:
+    print("Found no feature at %s" % feature.location)
+
+
+def guide_get_feature(route_guide_stub):
+  guide_get_one_feature(
+      route_guide_stub,
+      route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
+  guide_get_one_feature(
+      route_guide_stub, route_guide_pb2.Point(latitude=0, longitude=0))
+
+
+def guide_list_features(route_guide_stub):
+  rectangle = route_guide_pb2.Rectangle(
+      lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
+      hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
+  print("Looking for features between 40, -75 and 42, -73")
+
+  features = route_guide_stub.ListFeatures(rectangle)
+
+  for feature in features:
+    print("Feature called %s at %s" % (feature.name, feature.location))
+
+
+def generate_route(feature_list):
+  for _ in range(0, 10):
+    random_feature = feature_list[random.randint(0, len(feature_list) - 1)]
+    print("Visiting point %s" % random_feature.location)
+    yield random_feature.location
+    time.sleep(random.uniform(0.5, 1.5))
+
+
+def guide_record_route(route_guide_stub):
+  feature_list = route_guide_resources.read_route_guide_database()
+
+  route_iterator = generate_route(feature_list)
+  route_summary = route_guide_stub.RecordRoute(route_iterator)
+  print("Finished trip with %s points " % route_summary.point_count)
+  print("Passed %s features " % route_summary.feature_count)
+  print("Travelled %s meters " % route_summary.distance)
+  print("It took %s seconds " % route_summary.elapsed_time)
+
+
+def generate_messages():
+  messages = [
+      make_route_note("First message", 0, 0),
+      make_route_note("Second message", 0, 1),
+      make_route_note("Third message", 1, 0),
+      make_route_note("Fourth message", 0, 0),
+      make_route_note("Fifth message", 1, 0),
+  ]
+  for msg in messages:
+    print("Sending %s at %s" % (msg.message, msg.location))
+    yield msg
+    time.sleep(random.uniform(0.5, 1.0))
+
+
+def guide_route_chat(route_guide_stub):
+  responses = route_guide_stub.RouteChat(generate_messages())
+  for response in responses:
+    print("Received message %s at %s" % (response.message, response.location))
+
+
+def run():
+  channel = grpc.insecure_channel('localhost:50051')
+  greeter_stub = helloworld_pb2.GreeterStub(channel)
+  route_guide_stub = route_guide_pb2.RouteGuideStub(channel)
+  greeter_response = greeter_stub.SayHello(
+      helloworld_pb2.HelloRequest(name='you'))
+  print("Greeter client received: " + greeter_response.message)
+  print("-------------- GetFeature --------------")
+  guide_get_feature(route_guide_stub)
+  print("-------------- ListFeatures --------------")
+  guide_list_features(route_guide_stub)
+  print("-------------- RecordRoute --------------")
+  guide_record_route(route_guide_stub)
+  print("-------------- RouteChat --------------")
+  guide_route_chat(route_guide_stub)
+
+
+if __name__ == '__main__':
+  run()
diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py
new file mode 100644
index 0000000000000000000000000000000000000000..32a4ee4a4977fb948d684c270268a5ebbd4d49a0
--- /dev/null
+++ b/examples/python/multiplex/multiplex_server.py
@@ -0,0 +1,149 @@
+# 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.
+
+"""A gRPC server servicing both Greeter and RouteGuide RPCs."""
+
+from concurrent import futures
+import time
+import math
+
+import grpc
+
+import helloworld_pb2
+import route_guide_pb2
+import route_guide_resources
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+
+def _get_feature(feature_db, point):
+  """Returns Feature at given location or None."""
+  for feature in feature_db:
+    if feature.location == point:
+      return feature
+  return None
+
+
+def _get_distance(start, end):
+  """Distance between two points."""
+  coord_factor = 10000000.0
+  lat_1 = start.latitude / coord_factor
+  lat_2 = end.latitude / coord_factor
+  lon_1 = start.longitude / coord_factor
+  lon_2 = end.longitude / coord_factor
+  lat_rad_1 = math.radians(lat_1)
+  lat_rad_2 = math.radians(lat_2)
+  delta_lat_rad = math.radians(lat_2 - lat_1)
+  delta_lon_rad = math.radians(lon_2 - lon_1)
+
+  a = (pow(math.sin(delta_lat_rad / 2), 2) +
+       (math.cos(lat_rad_1) * math.cos(lat_rad_2) *
+        pow(math.sin(delta_lon_rad / 2), 2)))
+  c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
+  R = 6371000; # metres
+  return R * c;
+
+
+class _GreeterServicer(helloworld_pb2.GreeterServicer):
+
+  def SayHello(self, request, context):
+    return helloworld_pb2.HelloReply(message='Hello, {}!'.format(request.name))
+
+
+class _RouteGuideServicer(route_guide_pb2.RouteGuideServicer):
+  """Provides methods that implement functionality of route guide server."""
+
+  def __init__(self):
+    self.db = route_guide_resources.read_route_guide_database()
+
+  def GetFeature(self, request, context):
+    feature = _get_feature(self.db, request)
+    if feature is None:
+      return route_guide_pb2.Feature(name="", location=request)
+    else:
+      return feature
+
+  def ListFeatures(self, request, context):
+    left = min(request.lo.longitude, request.hi.longitude)
+    right = max(request.lo.longitude, request.hi.longitude)
+    top = max(request.lo.latitude, request.hi.latitude)
+    bottom = min(request.lo.latitude, request.hi.latitude)
+    for feature in self.db:
+      if (feature.location.longitude >= left and
+          feature.location.longitude <= right and
+          feature.location.latitude >= bottom and
+          feature.location.latitude <= top):
+        yield feature
+
+  def RecordRoute(self, request_iterator, context):
+    point_count = 0
+    feature_count = 0
+    distance = 0.0
+    prev_point = None
+
+    start_time = time.time()
+    for point in request_iterator:
+      point_count += 1
+      if _get_feature(self.db, point):
+        feature_count += 1
+      if prev_point:
+        distance += _get_distance(prev_point, point)
+      prev_point = point
+
+    elapsed_time = time.time() - start_time
+    return route_guide_pb2.RouteSummary(point_count=point_count,
+                                        feature_count=feature_count,
+                                        distance=int(distance),
+                                        elapsed_time=int(elapsed_time))
+
+  def RouteChat(self, request_iterator, context):
+    prev_notes = []
+    for new_note in request_iterator:
+      for prev_note in prev_notes:
+        if prev_note.location == new_note.location:
+          yield prev_note
+      prev_notes.append(new_note)
+
+
+def serve():
+  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+  helloworld_pb2.add_GreeterServicer_to_server(_GreeterServicer(), server)
+  route_guide_pb2.add_RouteGuideServicer_to_server(
+      _RouteGuideServicer(), server)
+  server.add_insecure_port('[::]:50051')
+  server.start()
+  try:
+    while True:
+      time.sleep(_ONE_DAY_IN_SECONDS)
+  except KeyboardInterrupt:
+    server.stop(0)
+
+
+if __name__ == '__main__':
+  serve()
diff --git a/examples/python/multiplex/route_guide_db.json b/examples/python/multiplex/route_guide_db.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d6a980ab7d76163b103a5eccd523a3ffac0ec98
--- /dev/null
+++ b/examples/python/multiplex/route_guide_db.json
@@ -0,0 +1,601 @@
+[{
+    "location": {
+        "latitude": 407838351,
+        "longitude": -746143763
+    },
+    "name": "Patriots Path, Mendham, NJ 07945, USA"
+}, {
+    "location": {
+        "latitude": 408122808,
+        "longitude": -743999179
+    },
+    "name": "101 New Jersey 10, Whippany, NJ 07981, USA"
+}, {
+    "location": {
+        "latitude": 413628156,
+        "longitude": -749015468
+    },
+    "name": "U.S. 6, Shohola, PA 18458, USA"
+}, {
+    "location": {
+        "latitude": 419999544,
+        "longitude": -740371136
+    },
+    "name": "5 Conners Road, Kingston, NY 12401, USA"
+}, {
+    "location": {
+        "latitude": 414008389,
+        "longitude": -743951297
+    },
+    "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
+}, {
+    "location": {
+        "latitude": 419611318,
+        "longitude": -746524769
+    },
+    "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
+}, {
+    "location": {
+        "latitude": 406109563,
+        "longitude": -742186778
+    },
+    "name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
+}, {
+    "location": {
+        "latitude": 416802456,
+        "longitude": -742370183
+    },
+    "name": "352 South Mountain Road, Wallkill, NY 12589, USA"
+}, {
+    "location": {
+        "latitude": 412950425,
+        "longitude": -741077389
+    },
+    "name": "Bailey Turn Road, Harriman, NY 10926, USA"
+}, {
+    "location": {
+        "latitude": 412144655,
+        "longitude": -743949739
+    },
+    "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
+}, {
+    "location": {
+        "latitude": 415736605,
+        "longitude": -742847522
+    },
+    "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
+}, {
+    "location": {
+        "latitude": 413843930,
+        "longitude": -740501726
+    },
+    "name": "162 Merrill Road, Highland Mills, NY 10930, USA"
+}, {
+    "location": {
+        "latitude": 410873075,
+        "longitude": -744459023
+    },
+    "name": "Clinton Road, West Milford, NJ 07480, USA"
+}, {
+    "location": {
+        "latitude": 412346009,
+        "longitude": -744026814
+    },
+    "name": "16 Old Brook Lane, Warwick, NY 10990, USA"
+}, {
+    "location": {
+        "latitude": 402948455,
+        "longitude": -747903913
+    },
+    "name": "3 Drake Lane, Pennington, NJ 08534, USA"
+}, {
+    "location": {
+        "latitude": 406337092,
+        "longitude": -740122226
+    },
+    "name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
+}, {
+    "location": {
+        "latitude": 406421967,
+        "longitude": -747727624
+    },
+    "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
+}, {
+    "location": {
+        "latitude": 416318082,
+        "longitude": -749677716
+    },
+    "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
+}, {
+    "location": {
+        "latitude": 415301720,
+        "longitude": -748416257
+    },
+    "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
+}, {
+    "location": {
+        "latitude": 402647019,
+        "longitude": -747071791
+    },
+    "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
+}, {
+    "location": {
+        "latitude": 412567807,
+        "longitude": -741058078
+    },
+    "name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
+}, {
+    "location": {
+        "latitude": 416855156,
+        "longitude": -744420597
+    },
+    "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
+}, {
+    "location": {
+        "latitude": 404663628,
+        "longitude": -744820157
+    },
+    "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
+}, {
+    "location": {
+        "latitude": 407113723,
+        "longitude": -749746483
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 402133926,
+        "longitude": -743613249
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 400273442,
+        "longitude": -741220915
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411236786,
+        "longitude": -744070769
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411633782,
+        "longitude": -746784970
+    },
+    "name": "211-225 Plains Road, Augusta, NJ 07822, USA"
+}, {
+    "location": {
+        "latitude": 415830701,
+        "longitude": -742952812
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 413447164,
+        "longitude": -748712898
+    },
+    "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
+}, {
+    "location": {
+        "latitude": 405047245,
+        "longitude": -749800722
+    },
+    "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
+}, {
+    "location": {
+        "latitude": 418858923,
+        "longitude": -746156790
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 417951888,
+        "longitude": -748484944
+    },
+    "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
+}, {
+    "location": {
+        "latitude": 407033786,
+        "longitude": -743977337
+    },
+    "name": "26 East 3rd Street, New Providence, NJ 07974, USA"
+}, {
+    "location": {
+        "latitude": 417548014,
+        "longitude": -740075041
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 410395868,
+        "longitude": -744972325
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404615353,
+        "longitude": -745129803
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 406589790,
+        "longitude": -743560121
+    },
+    "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
+}, {
+    "location": {
+        "latitude": 414653148,
+        "longitude": -740477477
+    },
+    "name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
+}, {
+    "location": {
+        "latitude": 405957808,
+        "longitude": -743255336
+    },
+    "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
+}, {
+    "location": {
+        "latitude": 411733589,
+        "longitude": -741648093
+    },
+    "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
+}, {
+    "location": {
+        "latitude": 412676291,
+        "longitude": -742606606
+    },
+    "name": "1270 Lakes Road, Monroe, NY 10950, USA"
+}, {
+    "location": {
+        "latitude": 409224445,
+        "longitude": -748286738
+    },
+    "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
+}, {
+    "location": {
+        "latitude": 406523420,
+        "longitude": -742135517
+    },
+    "name": "652 Garden Street, Elizabeth, NJ 07202, USA"
+}, {
+    "location": {
+        "latitude": 401827388,
+        "longitude": -740294537
+    },
+    "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
+}, {
+    "location": {
+        "latitude": 410564152,
+        "longitude": -743685054
+    },
+    "name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
+}, {
+    "location": {
+        "latitude": 408472324,
+        "longitude": -740726046
+    },
+    "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
+}, {
+    "location": {
+        "latitude": 412452168,
+        "longitude": -740214052
+    },
+    "name": "5 White Oak Lane, Stony Point, NY 10980, USA"
+}, {
+    "location": {
+        "latitude": 409146138,
+        "longitude": -746188906
+    },
+    "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
+}, {
+    "location": {
+        "latitude": 404701380,
+        "longitude": -744781745
+    },
+    "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
+}, {
+    "location": {
+        "latitude": 409642566,
+        "longitude": -746017679
+    },
+    "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
+}, {
+    "location": {
+        "latitude": 408031728,
+        "longitude": -748645385
+    },
+    "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
+}, {
+    "location": {
+        "latitude": 413700272,
+        "longitude": -742135189
+    },
+    "name": "367 Prospect Road, Chester, NY 10918, USA"
+}, {
+    "location": {
+        "latitude": 404310607,
+        "longitude": -740282632
+    },
+    "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
+}, {
+    "location": {
+        "latitude": 409319800,
+        "longitude": -746201391
+    },
+    "name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
+}, {
+    "location": {
+        "latitude": 406685311,
+        "longitude": -742108603
+    },
+    "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
+}, {
+    "location": {
+        "latitude": 419018117,
+        "longitude": -749142781
+    },
+    "name": "43 Dreher Road, Roscoe, NY 12776, USA"
+}, {
+    "location": {
+        "latitude": 412856162,
+        "longitude": -745148837
+    },
+    "name": "Swan Street, Pine Island, NY 10969, USA"
+}, {
+    "location": {
+        "latitude": 416560744,
+        "longitude": -746721964
+    },
+    "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
+}, {
+    "location": {
+        "latitude": 405314270,
+        "longitude": -749836354
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 414219548,
+        "longitude": -743327440
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 415534177,
+        "longitude": -742900616
+    },
+    "name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
+}, {
+    "location": {
+        "latitude": 406898530,
+        "longitude": -749127080
+    },
+    "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
+}, {
+    "location": {
+        "latitude": 407586880,
+        "longitude": -741670168
+    },
+    "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
+}, {
+    "location": {
+        "latitude": 400106455,
+        "longitude": -742870190
+    },
+    "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
+}, {
+    "location": {
+        "latitude": 400066188,
+        "longitude": -746793294
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 418803880,
+        "longitude": -744102673
+    },
+    "name": "40 Mountain Road, Napanoch, NY 12458, USA"
+}, {
+    "location": {
+        "latitude": 414204288,
+        "longitude": -747895140
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 414777405,
+        "longitude": -740615601
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 415464475,
+        "longitude": -747175374
+    },
+    "name": "48 North Road, Forestburgh, NY 12777, USA"
+}, {
+    "location": {
+        "latitude": 404062378,
+        "longitude": -746376177
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 405688272,
+        "longitude": -749285130
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 400342070,
+        "longitude": -748788996
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 401809022,
+        "longitude": -744157964
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404226644,
+        "longitude": -740517141
+    },
+    "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
+}, {
+    "location": {
+        "latitude": 410322033,
+        "longitude": -747871659
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 407100674,
+        "longitude": -747742727
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 418811433,
+        "longitude": -741718005
+    },
+    "name": "213 Bush Road, Stone Ridge, NY 12484, USA"
+}, {
+    "location": {
+        "latitude": 415034302,
+        "longitude": -743850945
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411349992,
+        "longitude": -743694161
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404839914,
+        "longitude": -744759616
+    },
+    "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
+}, {
+    "location": {
+        "latitude": 414638017,
+        "longitude": -745957854
+    },
+    "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
+}, {
+    "location": {
+        "latitude": 412127800,
+        "longitude": -740173578
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 401263460,
+        "longitude": -747964303
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 412843391,
+        "longitude": -749086026
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 418512773,
+        "longitude": -743067823
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404318328,
+        "longitude": -740835638
+    },
+    "name": "42-102 Main Street, Belford, NJ 07718, USA"
+}, {
+    "location": {
+        "latitude": 419020746,
+        "longitude": -741172328
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404080723,
+        "longitude": -746119569
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 401012643,
+        "longitude": -744035134
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404306372,
+        "longitude": -741079661
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 403966326,
+        "longitude": -748519297
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 405002031,
+        "longitude": -748407866
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 409532885,
+        "longitude": -742200683
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 416851321,
+        "longitude": -742674555
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 406411633,
+        "longitude": -741722051
+    },
+    "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
+}, {
+    "location": {
+        "latitude": 413069058,
+        "longitude": -744597778
+    },
+    "name": "261 Van Sickle Road, Goshen, NY 10924, USA"
+}, {
+    "location": {
+        "latitude": 418465462,
+        "longitude": -746859398
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411733222,
+        "longitude": -744228360
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 410248224,
+        "longitude": -747127767
+    },
+    "name": "3 Hasta Way, Newton, NJ 07860, USA"
+}]
diff --git a/examples/python/multiplex/route_guide_pb2.py b/examples/python/multiplex/route_guide_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..924e186e06e4ca1094a3c648bf3748f79393464c
--- /dev/null
+++ b/examples/python/multiplex/route_guide_pb2.py
@@ -0,0 +1,516 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: route_guide.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='route_guide.proto',
+  package='routeguide',
+  syntax='proto3',
+  serialized_pb=_b('\n\x11route_guide.proto\x12\nrouteguide\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"I\n\tRectangle\x12\x1d\n\x02lo\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x1d\n\x02hi\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"<\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x08location\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"A\n\tRouteNote\x12#\n\x08location\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\x85\x02\n\nRouteGuide\x12\x36\n\nGetFeature\x12\x11.routeguide.Point\x1a\x13.routeguide.Feature\"\x00\x12>\n\x0cListFeatures\x12\x15.routeguide.Rectangle\x1a\x13.routeguide.Feature\"\x00\x30\x01\x12>\n\x0bRecordRoute\x12\x11.routeguide.Point\x1a\x18.routeguide.RouteSummary\"\x00(\x01\x12?\n\tRouteChat\x12\x15.routeguide.RouteNote\x1a\x15.routeguide.RouteNote\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.routeguideB\x0fRouteGuideProtoP\x01\xa2\x02\x03RTGb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_POINT = _descriptor.Descriptor(
+  name='Point',
+  full_name='routeguide.Point',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='latitude', full_name='routeguide.Point.latitude', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='longitude', full_name='routeguide.Point.longitude', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=33,
+  serialized_end=77,
+)
+
+
+_RECTANGLE = _descriptor.Descriptor(
+  name='Rectangle',
+  full_name='routeguide.Rectangle',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='lo', full_name='routeguide.Rectangle.lo', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='hi', full_name='routeguide.Rectangle.hi', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=79,
+  serialized_end=152,
+)
+
+
+_FEATURE = _descriptor.Descriptor(
+  name='Feature',
+  full_name='routeguide.Feature',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='routeguide.Feature.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='location', full_name='routeguide.Feature.location', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=154,
+  serialized_end=214,
+)
+
+
+_ROUTENOTE = _descriptor.Descriptor(
+  name='RouteNote',
+  full_name='routeguide.RouteNote',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='location', full_name='routeguide.RouteNote.location', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='routeguide.RouteNote.message', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=216,
+  serialized_end=281,
+)
+
+
+_ROUTESUMMARY = _descriptor.Descriptor(
+  name='RouteSummary',
+  full_name='routeguide.RouteSummary',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='point_count', full_name='routeguide.RouteSummary.point_count', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='feature_count', full_name='routeguide.RouteSummary.feature_count', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='distance', full_name='routeguide.RouteSummary.distance', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='elapsed_time', full_name='routeguide.RouteSummary.elapsed_time', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=283,
+  serialized_end=381,
+)
+
+_RECTANGLE.fields_by_name['lo'].message_type = _POINT
+_RECTANGLE.fields_by_name['hi'].message_type = _POINT
+_FEATURE.fields_by_name['location'].message_type = _POINT
+_ROUTENOTE.fields_by_name['location'].message_type = _POINT
+DESCRIPTOR.message_types_by_name['Point'] = _POINT
+DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE
+DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE
+DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE
+DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY
+
+Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict(
+  DESCRIPTOR = _POINT,
+  __module__ = 'route_guide_pb2'
+  # @@protoc_insertion_point(class_scope:routeguide.Point)
+  ))
+_sym_db.RegisterMessage(Point)
+
+Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict(
+  DESCRIPTOR = _RECTANGLE,
+  __module__ = 'route_guide_pb2'
+  # @@protoc_insertion_point(class_scope:routeguide.Rectangle)
+  ))
+_sym_db.RegisterMessage(Rectangle)
+
+Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict(
+  DESCRIPTOR = _FEATURE,
+  __module__ = 'route_guide_pb2'
+  # @@protoc_insertion_point(class_scope:routeguide.Feature)
+  ))
+_sym_db.RegisterMessage(Feature)
+
+RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict(
+  DESCRIPTOR = _ROUTENOTE,
+  __module__ = 'route_guide_pb2'
+  # @@protoc_insertion_point(class_scope:routeguide.RouteNote)
+  ))
+_sym_db.RegisterMessage(RouteNote)
+
+RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict(
+  DESCRIPTOR = _ROUTESUMMARY,
+  __module__ = 'route_guide_pb2'
+  # @@protoc_insertion_point(class_scope:routeguide.RouteSummary)
+  ))
+_sym_db.RegisterMessage(RouteSummary)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG'))
+import grpc
+from grpc.beta import implementations as beta_implementations
+from grpc.beta import interfaces as beta_interfaces
+from grpc.framework.common import cardinality
+from grpc.framework.interfaces.face import utilities as face_utilities
+
+
+class RouteGuideStub(object):
+  """Interface exported by the server.
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.GetFeature = channel.unary_unary(
+        '/routeguide.RouteGuide/GetFeature',
+        request_serializer=Point.SerializeToString,
+        response_deserializer=Feature.FromString,
+        )
+    self.ListFeatures = channel.unary_stream(
+        '/routeguide.RouteGuide/ListFeatures',
+        request_serializer=Rectangle.SerializeToString,
+        response_deserializer=Feature.FromString,
+        )
+    self.RecordRoute = channel.stream_unary(
+        '/routeguide.RouteGuide/RecordRoute',
+        request_serializer=Point.SerializeToString,
+        response_deserializer=RouteSummary.FromString,
+        )
+    self.RouteChat = channel.stream_stream(
+        '/routeguide.RouteGuide/RouteChat',
+        request_serializer=RouteNote.SerializeToString,
+        response_deserializer=RouteNote.FromString,
+        )
+
+
+class RouteGuideServicer(object):
+  """Interface exported by the server.
+  """
+
+  def GetFeature(self, request, context):
+    """A simple RPC.
+
+    Obtains the feature at a given position.
+
+    A feature with an empty name is returned if there's no feature at the given
+    position.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def ListFeatures(self, request, context):
+    """A server-to-client streaming RPC.
+
+    Obtains the Features available within the given Rectangle.  Results are
+    streamed rather than returned at once (e.g. in a response message with a
+    repeated field), as the rectangle may cover a large area and contain a
+    huge number of features.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def RecordRoute(self, request_iterator, context):
+    """A client-to-server streaming RPC.
+
+    Accepts a stream of Points on a route being traversed, returning a
+    RouteSummary when traversal is completed.
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def RouteChat(self, request_iterator, context):
+    """A Bidirectional streaming RPC.
+
+    Accepts a stream of RouteNotes sent while a route is being traversed,
+    while receiving other RouteNotes (e.g. from other users).
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_RouteGuideServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'GetFeature': grpc.unary_unary_rpc_method_handler(
+          servicer.GetFeature,
+          request_deserializer=Point.FromString,
+          response_serializer=Feature.SerializeToString,
+      ),
+      'ListFeatures': grpc.unary_stream_rpc_method_handler(
+          servicer.ListFeatures,
+          request_deserializer=Rectangle.FromString,
+          response_serializer=Feature.SerializeToString,
+      ),
+      'RecordRoute': grpc.stream_unary_rpc_method_handler(
+          servicer.RecordRoute,
+          request_deserializer=Point.FromString,
+          response_serializer=RouteSummary.SerializeToString,
+      ),
+      'RouteChat': grpc.stream_stream_rpc_method_handler(
+          servicer.RouteChat,
+          request_deserializer=RouteNote.FromString,
+          response_serializer=RouteNote.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'routeguide.RouteGuide', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
+
+
+class BetaRouteGuideServicer(object):
+  """Interface exported by the server.
+  """
+  def GetFeature(self, request, context):
+    """A simple RPC.
+
+    Obtains the feature at a given position.
+
+    A feature with an empty name is returned if there's no feature at the given
+    position.
+    """
+    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+  def ListFeatures(self, request, context):
+    """A server-to-client streaming RPC.
+
+    Obtains the Features available within the given Rectangle.  Results are
+    streamed rather than returned at once (e.g. in a response message with a
+    repeated field), as the rectangle may cover a large area and contain a
+    huge number of features.
+    """
+    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+  def RecordRoute(self, request_iterator, context):
+    """A client-to-server streaming RPC.
+
+    Accepts a stream of Points on a route being traversed, returning a
+    RouteSummary when traversal is completed.
+    """
+    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+  def RouteChat(self, request_iterator, context):
+    """A Bidirectional streaming RPC.
+
+    Accepts a stream of RouteNotes sent while a route is being traversed,
+    while receiving other RouteNotes (e.g. from other users).
+    """
+    context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+class BetaRouteGuideStub(object):
+  """Interface exported by the server.
+  """
+  def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+    """A simple RPC.
+
+    Obtains the feature at a given position.
+
+    A feature with an empty name is returned if there's no feature at the given
+    position.
+    """
+    raise NotImplementedError()
+  GetFeature.future = None
+  def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+    """A server-to-client streaming RPC.
+
+    Obtains the Features available within the given Rectangle.  Results are
+    streamed rather than returned at once (e.g. in a response message with a
+    repeated field), as the rectangle may cover a large area and contain a
+    huge number of features.
+    """
+    raise NotImplementedError()
+  def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+    """A client-to-server streaming RPC.
+
+    Accepts a stream of Points on a route being traversed, returning a
+    RouteSummary when traversal is completed.
+    """
+    raise NotImplementedError()
+  RecordRoute.future = None
+  def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+    """A Bidirectional streaming RPC.
+
+    Accepts a stream of RouteNotes sent while a route is being traversed,
+    while receiving other RouteNotes (e.g. from other users).
+    """
+    raise NotImplementedError()
+
+
+def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+  request_deserializers = {
+    ('routeguide.RouteGuide', 'GetFeature'): Point.FromString,
+    ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString,
+    ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString,
+    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
+  }
+  response_serializers = {
+    ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString,
+    ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString,
+    ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString,
+    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
+  }
+  method_implementations = {
+    ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature),
+    ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures),
+    ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute),
+    ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat),
+  }
+  server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+  return beta_implementations.server(method_implementations, options=server_options)
+
+
+def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+  request_serializers = {
+    ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString,
+    ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString,
+    ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString,
+    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
+  }
+  response_deserializers = {
+    ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString,
+    ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString,
+    ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString,
+    ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
+  }
+  cardinalities = {
+    'GetFeature': cardinality.Cardinality.UNARY_UNARY,
+    'ListFeatures': cardinality.Cardinality.UNARY_STREAM,
+    'RecordRoute': cardinality.Cardinality.STREAM_UNARY,
+    'RouteChat': cardinality.Cardinality.STREAM_STREAM,
+  }
+  stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+  return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options)
+# @@protoc_insertion_point(module_scope)
diff --git a/examples/python/multiplex/route_guide_resources.py b/examples/python/multiplex/route_guide_resources.py
new file mode 100644
index 0000000000000000000000000000000000000000..30c7711019fb6a220bb50093a223c4da28b766e6
--- /dev/null
+++ b/examples/python/multiplex/route_guide_resources.py
@@ -0,0 +1,53 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Common resources used in the gRPC route guide example."""
+
+import json
+
+import route_guide_pb2
+
+
+def read_route_guide_database():
+  """Reads the route guide database.
+
+  Returns:
+    The full contents of the route guide database as a sequence of
+      route_guide_pb2.Features.
+  """
+  feature_list = []
+  with open("route_guide_db.json") as route_guide_db_file:
+    for item in json.load(route_guide_db_file):
+      feature = route_guide_pb2.Feature(
+          name=item["name"],
+          location=route_guide_pb2.Point(
+              latitude=item["location"]["latitude"],
+              longitude=item["location"]["longitude"]))
+      feature_list.append(feature)
+  return feature_list
diff --git a/examples/python/multiplex/run_codegen.py b/examples/python/multiplex/run_codegen.py
new file mode 100755
index 0000000000000000000000000000000000000000..7922a0f5c7f5109671b2b0a96d4e9cdc00d29401
--- /dev/null
+++ b/examples/python/multiplex/run_codegen.py
@@ -0,0 +1,51 @@
+# 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.
+
+"""Generates protocol messages and gRPC stubs."""
+
+from grpc.tools import protoc
+
+protoc.main(
+    (
+        '',
+        '-I../../protos',
+        '--python_out=.',
+        '--grpc_python_out=.',
+        '../../protos/helloworld.proto',
+    )
+)
+protoc.main(
+    (
+        '',
+        '-I../../protos',
+        '--python_out=.',
+        '--grpc_python_out=.',
+        '../../protos/route_guide.proto',
+    )
+)