Merge pull request #1222 from ctiller/mac-fixes

Mac fixes
diff --git a/Makefile b/Makefile
index 753bbfb..c50eb8c 100644
--- a/Makefile
+++ b/Makefile
@@ -455,7 +455,7 @@
 
 .SECONDARY = %.pb.h %.pb.cc
 
-PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
 ifeq ($(DEP_MISSING),)
 all: static shared plugins
 dep_error:
@@ -631,6 +631,7 @@
 generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
 grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli
 grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
+grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
 grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
 grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
@@ -2000,92 +2001,152 @@
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/examples/pubsub/empty.pb.cc: protoc_dep_error
+$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/examples/pubsub/empty.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/examples/pubsub/label.pb.cc: protoc_dep_error
+$(GENDIR)/examples/pubsub/label.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/examples/pubsub/label.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/examples/pubsub/label.grpc.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/examples/pubsub/pubsub.pb.cc: protoc_dep_error
+$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/examples/pubsub/pubsub.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/interop/empty.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/interop/empty.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/interop/messages.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/interop/messages.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/interop/test.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/interop/test.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/qps/qpstest.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/qps/qpstest.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/util/echo.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/util/echo.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/cpp/util/messages.pb.cc: protoc_dep_error
+$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/test/cpp/util/messages.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 
@@ -2162,10 +2223,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(prefix)/lib/gpr.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing libgpr.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so
 endif
 endif
@@ -2175,10 +2236,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(prefix)/lib/grpc.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing libgrpc.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so
 endif
 endif
@@ -2188,10 +2249,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc_unsecure.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing libgrpc_unsecure.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so
 endif
 endif
@@ -2209,10 +2270,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(prefix)/lib/grpc++.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing libgrpc++.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
 endif
 endif
@@ -2222,10 +2283,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so
 endif
 endif
@@ -2243,10 +2304,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
 endif
 endif
@@ -2265,6 +2326,8 @@
 	$(Q) $(INSTALL) -d $(prefix)/bin
 	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(prefix)/bin/grpc_cpp_plugin
 	$(Q) $(INSTALL) -d $(prefix)/bin
+	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(prefix)/bin/grpc_objective_c_plugin
+	$(Q) $(INSTALL) -d $(prefix)/bin
 	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_python_plugin $(prefix)/bin/grpc_python_plugin
 	$(Q) $(INSTALL) -d $(prefix)/bin
 	$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin
@@ -2387,7 +2450,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgpr.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS)
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.0 -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS)
 	$(Q) ln -sf libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.so.0
@@ -2777,7 +2840,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr
 	$(Q) ln -sf libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.so.0
@@ -3117,7 +3180,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr
 	$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.so.0
@@ -3367,7 +3430,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc
 	$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0
@@ -3414,9 +3477,9 @@
 
 
 LIBGRPC++_TEST_UTIL_SRC = \
-    $(GENDIR)/test/cpp/util/messages.pb.cc \
-    $(GENDIR)/test/cpp/util/echo.pb.cc \
-    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc \
+    $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc \
+    $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc \
+    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \
     test/cpp/util/cli_call.cc \
     test/cpp/util/create_test_channel.cc \
 
@@ -3477,8 +3540,8 @@
 
 
 
-$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o:     $(GENDIR)/test/cpp/util/messages.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o:     $(GENDIR)/test/cpp/util/messages.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o:     $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o:     $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc    $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc    $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
 
 
 LIBGRPC++_UNSECURE_SRC = \
@@ -3572,7 +3635,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 else
 	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 	$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0
@@ -3614,6 +3677,7 @@
 
 LIBGRPC_PLUGIN_SUPPORT_SRC = \
     src/compiler/cpp_generator.cc \
+    src/compiler/objective_c_generator.cc \
     src/compiler/python_generator.cc \
     src/compiler/ruby_generator.cc \
 
@@ -3648,14 +3712,15 @@
 endif
 
 $(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o: 
+$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_generator.o: 
 $(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: 
 $(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o: 
 
 
 LIBPUBSUB_CLIENT_LIB_SRC = \
-    $(GENDIR)/examples/pubsub/label.pb.cc \
-    $(GENDIR)/examples/pubsub/empty.pb.cc \
-    $(GENDIR)/examples/pubsub/pubsub.pb.cc \
+    $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc \
+    $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc \
+    $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc \
     examples/pubsub/publisher.cc \
     examples/pubsub/subscriber.cc \
 
@@ -3716,12 +3781,12 @@
 
 
 
-$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o:     $(GENDIR)/examples/pubsub/label.pb.cc    $(GENDIR)/examples/pubsub/empty.pb.cc    $(GENDIR)/examples/pubsub/pubsub.pb.cc
-$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o:     $(GENDIR)/examples/pubsub/label.pb.cc    $(GENDIR)/examples/pubsub/empty.pb.cc    $(GENDIR)/examples/pubsub/pubsub.pb.cc
+$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o:     $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc    $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc    $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o:     $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc    $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc    $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc
 
 
 LIBQPS_SRC = \
-    $(GENDIR)/test/cpp/qps/qpstest.pb.cc \
+    $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \
     test/cpp/qps/driver.cc \
     test/cpp/qps/timer.cc \
 
@@ -3778,8 +3843,8 @@
 endif
 
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o:     $(GENDIR)/test/cpp/qps/qpstest.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o:     $(GENDIR)/test/cpp/qps/qpstest.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o:     $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o:     $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
 
 
 LIBGRPC_CSHARP_EXT_SRC = \
@@ -3831,7 +3896,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_csharp_ext.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
 else
 	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc
 	$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0
@@ -8330,6 +8395,36 @@
 endif
 
 
+GRPC_OBJECTIVE_C_PLUGIN_SRC = \
+    src/compiler/objective_c_plugin.cc \
+
+GRPC_OBJECTIVE_C_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_OBJECTIVE_C_PLUGIN_SRC))))
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: $(PROTOBUF_DEP) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+	$(E) "[HOSTLD]  Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+
+deps_grpc_objective_c_plugin: $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep)
+endif
+
+
 GRPC_PYTHON_PLUGIN_SRC = \
     src/compiler/python_plugin.cc \
 
@@ -8391,9 +8486,9 @@
 
 
 INTEROP_CLIENT_SRC = \
-    $(GENDIR)/test/cpp/interop/empty.pb.cc \
-    $(GENDIR)/test/cpp/interop/messages.pb.cc \
-    $(GENDIR)/test/cpp/interop/test.pb.cc \
+    $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \
+    $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \
+    $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \
     test/cpp/interop/client.cc \
 
 INTEROP_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_CLIENT_SRC))))
@@ -8439,9 +8534,9 @@
 
 
 INTEROP_SERVER_SRC = \
-    $(GENDIR)/test/cpp/interop/empty.pb.cc \
-    $(GENDIR)/test/cpp/interop/messages.pb.cc \
-    $(GENDIR)/test/cpp/interop/test.pb.cc \
+    $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \
+    $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \
+    $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \
     test/cpp/interop/server.cc \
 
 INTEROP_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_SERVER_SRC))))
diff --git a/build.json b/build.json
index d814e4c..f8f23e0 100644
--- a/build.json
+++ b/build.json
@@ -514,6 +514,8 @@
         "src/compiler/cpp_generator.h",
         "src/compiler/cpp_generator_helpers.h",
         "src/compiler/generator_helpers.h",
+        "src/compiler/objective_c_generator.h",
+        "src/compiler/objective_c_generator_helpers.h",
         "src/compiler/python_generator.h",
         "src/compiler/ruby_generator.h",
         "src/compiler/ruby_generator_helpers-inl.h",
@@ -522,6 +524,7 @@
       ],
       "src": [
         "src/compiler/cpp_generator.cc",
+        "src/compiler/objective_c_generator.cc",
         "src/compiler/python_generator.cc",
         "src/compiler/ruby_generator.cc"
       ],
@@ -1818,6 +1821,18 @@
       "secure": "no"
     },
     {
+      "name": "grpc_objective_c_plugin",
+      "build": "protoc",
+      "language": "c++",
+      "src": [
+        "src/compiler/objective_c_plugin.cc"
+      ],
+      "deps": [
+        "grpc_plugin_support"
+      ],
+      "secure": "no"
+    },
+    {
       "name": "grpc_python_plugin",
       "build": "protoc",
       "language": "c++",
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
new file mode 100644
index 0000000..3f5ce37
--- /dev/null
+++ b/doc/interop-test-descriptions.md
@@ -0,0 +1,685 @@
+Interoperability Test Case Descriptions
+=======================================
+
+Client and server use
+[test.proto](https://github.com/grpc/grpc/blob/master/test/cpp/interop/test.proto)
+and the [gRPC over HTTP/2 v2
+protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md).
+
+Client
+------
+
+Clients implement test cases that test certain functionally. Each client is
+provided the test case it is expected to run as a command-line parameter. Names
+should be lowercase and without spaces.
+
+Clients should accept these arguments:
+* --server_host=HOSTNAME
+    * The server host to connect to. For example, "localhost" or "127.0.0.1"
+* --server_host_override=HOSTNAME
+    * The server host to claim to be connecting to, for use in TLS and HTTP/2
+      :authority header. If unspecified, the value of --server_host will be
+      used
+* --server_port=PORT
+    * The server port to connect to. For example, "8080"
+* --test_case=TESTCASE
+    * The name of the test case to execute. For example, "empty_unary"
+* --use_tls=BOOLEAN
+    * Whether to use a plaintext or encrypted connection
+* --use_test_ca=BOOLEAN
+    * Whether to replace platform root CAs with
+      [ca.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/ca.pem)
+      as the CA root
+
+Clients must support TLS with ALPN. Clients must not disable certificate
+checking.
+
+### empty_unary
+
+This test verifies that implementations support zero-size messages. Ideally,
+client implementations would verify that the request and response were zero
+bytes serialized, but this is generally prohibitive to perform, so is not
+required.
+
+Server features:
+* [EmptyCall][]
+
+Procedure:
+ 1. Client calls EmptyCall with the default Empty message
+
+Asserts:
+* call was successful
+* response is non-null
+
+*It may be possible to use UnaryCall instead of EmptyCall, but it is harder to
+ensure that the proto serialized to zero bytes.*
+
+### large_unary
+
+This test verifies unary calls succeed in sending messages, and touches on flow
+control (even if compression is enabled on the channel).
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls UnaryCall with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+
+Asserts:
+* call was successful
+* response payload type is COMPRESSABLE
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response message against a golden response
+
+### client_streaming
+
+This test verifies that client-only streaming succeeds.
+
+Server features:
+* [StreamingInputCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls StreamingInputCall
+ 2. Client sends:
+
+    ```
+    {
+      payload:{
+        body: 27182 bytes of zeros
+      }
+    }
+    ```
+ 3. Client then sends:
+
+    ```
+    {
+      payload:{
+        body: 8 bytes of zeros
+      }
+    }
+    ```
+ 4. Client then sends:
+
+    ```
+    {
+      payload:{
+        body: 1828 bytes of zeros
+      }
+    }
+    ```
+ 5. Client then sends:
+
+    ```
+    {
+      payload:{
+        body: 45904 bytes of zeros
+      }
+    }
+    ```
+ 6. Client halfCloses
+
+Asserts:
+* call was successful
+* response aggregated_payload_size is 74922
+
+### server_streaming
+
+This test verifies that server-only streaming succeeds.
+
+Server features:
+* [StreamingOutputCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls StreamingOutputCall with:
+
+    ```
+    {
+      response_type:COMPRESSABLE
+      response_parameters:{
+        size: 31415
+      }
+      response_parameters:{
+        size: 9
+      }
+      response_parameters:{
+        size: 2653
+      }
+      response_parameters:{
+        size: 58979
+      }
+    }
+    ```
+
+Asserts:
+* call was successful
+* exactly four responses
+* response payloads are COMPRESSABLE
+* response payload bodies are sized (in order): 31415, 9, 2653, 58979
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response messages against golden responses
+
+### ping_pong
+
+This test verifies that full duplex bidi is supported.
+
+Server features:
+* [FullDuplexCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client calls FullDuplexCall with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_parameters:{
+        size: 31415
+      }
+      payload:{
+        body: 27182 bytes of zeros
+      }
+    }
+    ```
+ 2. After getting a reply, it sends:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_parameters:{
+        size: 9
+      }
+      payload:{
+        body: 8 bytes of zeros
+      }
+    }
+    ```
+ 3. After getting a reply, it sends:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_parameters:{
+        size: 2653
+      }
+      payload:{
+        body: 1828 bytes of zeros
+      }
+    }
+    ```
+ 4. After getting a reply, it sends:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_parameters:{
+        size: 58979
+      }
+      payload:{
+        body: 45904 bytes of zeros
+      }
+    }
+    ```
+
+Asserts:
+* call was successful
+* exactly four responses
+* response payloads are COMPRESSABLE
+* response payload bodies are sized (in order): 31415, 9, 2653, 58979
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response messages against golden responses
+
+### empty_stream
+
+This test verifies that streams support having zero-messages in both
+directions.
+
+Server features:
+* [FullDuplexCall][]
+
+Procedure:
+ 1. Client calls FullDuplexCall and then half-closes
+
+Asserts:
+* call was successful
+* exactly zero responses
+
+### compute_engine_creds
+
+Status: Not yet implementable
+
+This test is only for cloud-to-prod path.
+
+This test verifies unary calls succeed in sending messages while using Service
+Credentials from GCE metadata server. The client instance needs to be created
+with desired oauth scope.
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* SimpeResponse.username
+* SimpleResponse.oauth_scope
+
+Procedure:
+ 1. Client sets flags default_service_account with GCE service account name and
+    oauth_scope with the oauth scope to use.
+ 2. Client configures channel to use GCECredentials
+ 3. Client calls UnaryCall on the channel with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+      fill_username: true
+      fill_oauth_scope: true
+    }
+    ```
+
+Asserts:
+* call was successful
+* received SimpleResponse.username equals FLAGS_default_service_account
+* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response message against a golden response
+
+### service_account_creds
+
+Status: Not yet implementable
+
+This test is only for cloud-to-prod path.
+
+This test verifies unary calls succeed in sending messages while using JWT
+signing keys (redeemed for OAuth2 access tokens by the auth implementation)
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* SimpleResponse.username
+* SimpleResponse.oauth_scope
+
+Procedure:
+ 1. Client sets flags service_account_key_file with the path to json key file,
+    oauth_scope to the oauth scope.
+ 2. Client configures the channel to use ServiceAccountCredentials.
+ 3. Client calls UnaryCall with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+      fill_username: true
+      fill_oauth_scope: true
+    }
+    ```
+
+Asserts:
+* call was successful
+* received SimpleResponse.username is in the json key file read from
+  FLAGS_service_account_key_file
+* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response message against a golden response
+
+### jwt_token_creds
+
+Status: Not yet implementable
+
+This test is only for cloud-to-prod path.
+
+This test verifies unary calls succeed in sending messages while using JWT
+token (created by the project's key file)
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* SimpleResponse.username
+* SimpleResponse.oauth_scope
+
+Procedure:
+ 1. Client sets flags service_account_key_file with the path to json key file
+ 2. Client configures the channel to use JWTTokenCredentials.
+ 3. Client calls UnaryCall with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+      fill_username: true
+    }
+    ```
+
+Asserts:
+* call was successful
+* received SimpleResponse.username is in the json key file read from
+  FLAGS_service_account_key_file
+* response payload body is 314159 bytes in size
+* clients are free to assert that the response payload body contents are zero
+  and comparing the entire response message against a golden response
+
+### Metadata (TODO: fix name)
+
+Status: Not yet implementable
+
+This test verifies that custom metadata in either binary or ascii format can be
+sent in header and trailer.
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* Ability to receive custom metadata from client in header and send custom data
+  back to client in both header and trailer. (TODO: this is not defined)
+
+Procedure:
+ 1. While sending custom metadata (ascii + binary) in the header, client calls UnaryCall with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+
+Asserts:
+* call was successful
+* custom metadata is echoed back in the response header.
+* custom metadata is echoed back in the response trailer.
+
+### status_code_and_message
+
+Status: Not yet implementable
+
+This test verifies unary calls succeed in sending messages, and propagates back
+status code and message sent along with the messages.
+
+Server features:
+* [UnaryCall][]
+
+Procedure:
+ 1. Client calls UnaryCall with:
+
+    ```
+    {
+      response_status:{
+        code: 2
+        message: "test status message"
+      }
+    }
+    ```
+
+Asserts:
+* received status code is the same with sent code
+* received status message is the same with sent message
+
+### unimplemented_method
+
+Status: Not yet implementable
+
+This test verifies calling unimplemented RPC method returns unimplemented
+status.
+
+Procedure:
+* Client calls UnimplementedCall with:
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+
+Asserts:
+* received status code is 12 (UNIMPLEMENTED)
+* received status message is empty or null/unset
+
+### cancel_after_begin
+
+This test verifies that a request can be cancelled after metadata has been sent
+but before payloads are sent.
+
+Server features:
+* [StreamingInputCall][]
+
+Procedure:
+ 1. Client starts StreamingInputCall
+ 2. Client immediately cancels request
+
+Asserts:
+* Call completed with status CANCELLED
+
+### cancel_after_first_response
+
+This test verifies that a request can be cancelled after receiving a message
+from the server.
+
+Server features:
+* [FullDuplexCall][]
+* [Compressable Payload][]
+
+Procedure:
+ 1. Client starts FullDuplexCall with
+
+    ```
+    {
+      response_type: COMPRESSABLE
+      response_parameters:{
+        size: 31415
+      }
+      payload:{
+        body: 27182 bytes of zeros
+      }
+    }
+    ```
+ 2. After receiving a response, client cancels request
+
+Asserts:
+* Call completed with status CANCELLED
+
+### concurrent_large_unary
+
+Status: TODO
+
+Client performs 1000 large_unary tests in parallel on the same channel.
+
+### Flow control. Pushback at client for large messages (TODO: fix name)
+
+Status: TODO
+
+This test verifies that a client sending faster than a server can drain sees
+pushback (i.e., attempts to send succeed only after appropriate delays).
+
+### TODO Tests
+
+High priority:
+
+Propagation of status code and message (yangg)
+
+Cancel after sent headers (ctiller - done)
+
+Cancel after received first message (ctiller - done)
+
+Timeout after expire (zhaoq)
+
+Zero-message streams (ejona)
+
+Multiple thousand simultaneous calls on same Channel (ctiller - done)
+
+OAuth2 tokens + Service Credentials from GCE metadata server (GCE->prod only)
+(abhishek)
+
+OAuth2 tokens + JWT signing key (GCE->prod only) (abhishek)
+
+Metadata: client headers, server headers + trailers, binary+ascii (chenw)
+
+Normal priority:
+
+Cancel before start (ctiller)
+
+Cancel after sent first message (ctiller)
+
+Cancel after received headers (ctiller)
+
+Timeout but completed before expire (zhaoq)
+
+Multiple thousand simultaneous calls timeout on same Channel (ctiller)
+
+Lower priority:
+
+Flow control. Pushback at client for large messages (abhishek)
+
+Flow control. Pushback at server for large messages (abhishek)
+
+Going over max concurrent streams doesn't fail (client controls itself)
+(abhishek)
+
+RPC method not implemented (yangg)
+
+Multiple thousand simultaneous calls on different Channels (ctiller)
+
+Failed TLS hostname verification (ejona?)
+
+To priorize:
+
+Start streaming RPC but don't send any requests, server responds
+
+### Postponed Tests
+
+Resilience to buggy servers: These tests would verify that a client application
+isn't affected negatively by the responses put on the wire by a buggy server
+(e.g. the client library won't make the application crash).
+
+Reconnect after transport failure
+
+Reconnect backoff
+
+Fuzz testing
+
+
+Server
+------
+
+Servers implement various named features for clients to test with. Server
+features are orthogonal. If a server implements a feature, it is always
+available for clients. Names are simple descriptions for developer
+communication and tracking.
+
+Servers should accept these arguments:
+
+* --port=PORT
+
+    * The port to listen on. For example, "8080"
+
+* --use_tls=BOOLEAN
+
+    * Whether to use a plaintext or encrypted connection
+
+Servers must support TLS with ALPN. They should use
+[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/server1.pem)
+for their certificate.
+
+### EmptyCall
+[EmptyCall]: #emptycall
+
+Server implements EmptyCall which immediately returns the empty message.
+
+### UnaryCall
+[UnaryCall]: #unarycall
+
+Server implements UnaryCall which immediately returns a SimpleResponse with a
+payload body of size SimpleRequest.response_size bytes and type as appropriate
+for the SimpleRequest.response_type. If the server does not support the
+response_type, then it should fail the RPC with INVALID_ARGUMENT.
+
+If the request sets fill_username, the server should return the client username
+it sees in field SimpleResponse.username. If the request sets fill_oauth_scope,
+the server should return the oauth scope of the rpc in the form of "xapi_zoo"
+in field SimpleResponse.oauth_scope.
+
+### StreamingInputCall
+[StreamingInputCall]: #streaminginputcall
+
+Server implements StreamingInputCall which upon half close immediately returns
+a StreamingInputCallResponse where aggregated_payload_size is the sum of all
+request payload bodies received.
+
+### StreamingOutputCall
+[StreamingOutputCall]: #streamingoutputcall
+
+Server implements StreamingOutputCall by replying, in order, with one
+StreamingOutputCallResponses for each ResponseParameters in
+StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a
+payload body of size ResponseParameters.size bytes, as specified by its
+respective ResponseParameters. After sending all responses, it closes with OK.
+
+### FullDuplexCall
+[FullDuplexCall]: #fullduplexcall
+
+Server implements FullDuplexCall by replying, in order, with one
+StreamingOutputCallResponses for each ResponseParameters in each
+StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a
+payload body of size ResponseParameters.size bytes, as specified by its
+respective ResponseParameters. After receiving half close and sending all
+responses, it closes with OK.
+
+### Compressable Payload
+[Compressable Payload]: #compressable-payload
+
+When the client requests COMPRESSABLE payload, the response includes a payload
+of the size requested containing all zeros and the payload type is
+COMPRESSABLE.
+
+### Observe ResponseParameters.interval_us
+[Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us
+
+In StreamingOutputCall and FullDuplexCall, server delays sending a
+StreamingOutputCallResponse by the ResponseParameters's interval_us for that
+particular response, relative to the last response sent. That is, interval_us
+acts like a sleep *before* sending the response and accumulates from one
+response to the next.
+
+Interaction with flow control is unspecified.
+
+### Echo Auth Information
+
+Status: Pending
+
+If a SimpleRequest has fill_username=true and that request was successfully
+authenticated, then the SimpleResponse should have username filled with the
+canonical form of the authenticated source. The canonical form is dependent on
+the authentication method, but is likely to be a base 10 integer identifier or
+an email address.
+
+Discussion:
+
+Ideally, this would be communicated via metadata and not in the
+request/response, but we want to use this test in code paths that don't yet
+fully communicate metadata.
diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h
index c90406f..33bcf98 100644
--- a/examples/pubsub/publisher.h
+++ b/examples/pubsub/publisher.h
@@ -37,7 +37,7 @@
 #include <grpc++/channel_interface.h>
 #include <grpc++/status.h>
 
-#include "examples/pubsub/pubsub.pb.h"
+#include "examples/pubsub/pubsub.grpc.pb.h"
 
 namespace grpc {
 namespace examples {
diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h
index c587c01..40ab454 100644
--- a/examples/pubsub/subscriber.h
+++ b/examples/pubsub/subscriber.h
@@ -37,7 +37,7 @@
 #include <grpc++/channel_interface.h>
 #include <grpc++/status.h>
 
-#include "examples/pubsub/pubsub.pb.h"
+#include "examples/pubsub/pubsub.grpc.pb.h"
 
 namespace grpc {
 namespace examples {
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 0a84c73..c78f033 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -109,8 +109,47 @@
   }
   return false;
 }
+
+grpc::string FilenameIdentifier(const grpc::string& filename) {
+  grpc::string result;
+  for (unsigned i = 0; i < filename.size(); i++) {
+    char c = filename[i];
+    if (isalnum(c)) {
+      result.push_back(c);
+    } else {
+      static char hex[] = "0123456789abcdef";
+      result.push_back('_');
+      result.push_back(hex[(c >> 4) & 0xf]);
+      result.push_back(hex[c & 0xf]);
+    }
+  }
+  return result;
+}
 }  // namespace
 
+grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
+  grpc::string output;
+  grpc::protobuf::io::StringOutputStream output_stream(&output);
+  grpc::protobuf::io::Printer printer(&output_stream, '$');
+  std::map<grpc::string, grpc::string> vars;
+
+  vars["filename"] = file->name();
+  vars["filename_identifier"] = FilenameIdentifier(file->name());
+  vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+  printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+  printer.Print(vars, "// If you make any local change, they will be lost.\n");
+  printer.Print(vars, "// source: $filename$\n");
+  printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+  printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+  printer.Print(vars, "\n");
+  printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+  printer.Print(vars, "\n");
+
+  return output;
+}
+
 grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params) {
   grpc::string temp =
@@ -156,17 +195,21 @@
         "class ServerAsyncReaderWriter;\n");
   }
   temp.append("}  // namespace grpc\n");
-  return temp;
-}
 
-grpc::string GetSourceIncludes(const Parameters &param) {
-  return "#include <grpc++/async_unary_call.h>\n"
-         "#include <grpc++/channel_interface.h>\n"
-         "#include <grpc++/impl/client_unary_call.h>\n"
-         "#include <grpc++/impl/rpc_method.h>\n"
-         "#include <grpc++/impl/rpc_service_method.h>\n"
-         "#include <grpc++/impl/service_type.h>\n"
-         "#include <grpc++/stream.h>\n";
+  temp.append("\n");
+
+  std::vector<grpc::string> parts =
+    grpc_generator::tokenize(file->package(), ".");
+
+  for (auto part = parts.begin(); part != parts.end(); part++) {
+    temp.append("namespace ");
+    temp.append(*part);
+    temp.append(" {\n");
+  }
+
+  temp.append("\n");
+
+  return temp;
 }
 
 void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
@@ -378,6 +421,78 @@
   return output;
 }
 
+grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
+  grpc::string output;
+  grpc::protobuf::io::StringOutputStream output_stream(&output);
+  grpc::protobuf::io::Printer printer(&output_stream, '$');
+  std::map<grpc::string, grpc::string> vars;
+
+  vars["filename"] = file->name();
+  vars["filename_identifier"] = FilenameIdentifier(file->name());
+
+  std::vector<grpc::string> parts =
+    grpc_generator::tokenize(file->package(), ".");
+
+  for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+    vars["part"] = *part;
+    printer.Print(vars, "}  // namespace $part$\n");
+  }
+
+  printer.Print(vars, "\n\n");
+  printer.Print(vars, "#endif  // GRPC_$filename_identifier$__INCLUDED\n");
+
+  return output;
+}
+
+grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
+  grpc::string output;
+  grpc::protobuf::io::StringOutputStream output_stream(&output);
+  grpc::protobuf::io::Printer printer(&output_stream, '$');
+  std::map<grpc::string, grpc::string> vars;
+
+  vars["filename"] = file->name();
+  vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+  printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+  printer.Print(vars, "// If you make any local change, they will be lost.\n");
+  printer.Print(vars, "// source: $filename$\n\n");
+  printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+  printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
+  printer.Print(vars, "\n");
+
+  return output;
+}
+
+grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &param) {
+  grpc::string output;
+  grpc::protobuf::io::StringOutputStream output_stream(&output);
+  grpc::protobuf::io::Printer printer(&output_stream, '$');
+  std::map<grpc::string, grpc::string> vars;
+
+  printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
+  printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
+  printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
+  printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n");
+  printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
+  printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
+  printer.Print(vars, "#include <grpc++/stream.h>\n");
+
+  std::vector<grpc::string> parts =
+    grpc_generator::tokenize(file->package(), ".");
+
+  for (auto part = parts.begin(); part != parts.end(); part++) {
+    vars["part"] = *part;
+    printer.Print(vars, "namespace $part$ {\n");
+  }
+
+  printer.Print(vars, "\n");
+
+  return output;
+}
+
 void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
                              const grpc::protobuf::MethodDescriptor *method,
                              std::map<grpc::string, grpc::string> *vars) {
@@ -741,4 +856,22 @@
   return output;
 }
 
+grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params) {
+  grpc::string temp;
+
+  std::vector<grpc::string> parts =
+    grpc_generator::tokenize(file->package(), ".");
+
+  for (auto part = parts.begin(); part != parts.end(); part++) {
+    temp.append("}  // namespace ");
+    temp.append(*part);
+    temp.append("\n");
+  }
+
+  temp.append("\n");
+
+  return temp;
+}
+
 }  // namespace grpc_cpp_generator
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index 04ad71c..70c2e98 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -44,12 +44,25 @@
   grpc::string services_namespace;
 };
 
+// Return the prologue of the generated header file.
+grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
+
 // Return the includes needed for generated header file.
 grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params);
 
 // Return the includes needed for generated source file.
-grpc::string GetSourceIncludes(const Parameters &params);
+grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
+
+// Return the epilogue of the generated header file.
+grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
+
+// Return the prologue of the generated source file.
+grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
 
 // Return the services for generated header file.
 grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
@@ -59,6 +72,10 @@
 grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
                                const Parameters &params);
 
+// Return the epilogue of the generated source file.
+grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
+                               const Parameters &params);
+
 }  // namespace grpc_cpp_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index acbe128..88c7049 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -58,11 +58,6 @@
       return false;
     }
 
-    if (file->service_count() == 0) {
-      // No services.  Do nothing.
-      return true;
-    }
-
     grpc_cpp_generator::Parameters generator_parameters;
 
     if (!parameter.empty()) {
@@ -84,16 +79,27 @@
 
     grpc::string file_name = grpc_generator::StripProto(file->name());
 
-    // Generate .pb.h
-    Insert(context, file_name + ".pb.h", "includes",
-           grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters));
-    Insert(context, file_name + ".pb.h", "namespace_scope",
-           grpc_cpp_generator::GetHeaderServices(file, generator_parameters));
-    // Generate .pb.cc
-    Insert(context, file_name + ".pb.cc", "includes",
-           grpc_cpp_generator::GetSourceIncludes(generator_parameters));
-    Insert(context, file_name + ".pb.cc", "namespace_scope",
-           grpc_cpp_generator::GetSourceServices(file, generator_parameters));
+    grpc::string header_code =
+        grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) +
+        grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) +
+        grpc_cpp_generator::GetHeaderServices(file, generator_parameters) +
+        grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters);
+    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
+        context->Open(file_name + ".grpc.pb.h"));
+    grpc::protobuf::io::CodedOutputStream header_coded_out(
+        header_output.get());
+    header_coded_out.WriteRaw(header_code.data(), header_code.size());
+
+    grpc::string source_code =
+        grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) +
+        grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) +
+        grpc_cpp_generator::GetSourceServices(file, generator_parameters) +
+        grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters);
+    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
+        context->Open(file_name + ".grpc.pb.cc"));
+    grpc::protobuf::io::CodedOutputStream source_coded_out(
+        source_output.get());
+    source_coded_out.WriteRaw(source_code.data(), source_code.size());
 
     return true;
   }
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
index 3085789..374e137 100644
--- a/src/compiler/generator_helpers.h
+++ b/src/compiler/generator_helpers.h
@@ -95,6 +95,27 @@
   }
 }
 
+inline grpc::string CapitalizeFirstLetter(grpc::string s) {
+  if (s.empty()) {
+    return s;
+  }
+  s[0] = ::toupper(s[0]);
+  return s;
+}
+
+inline grpc::string LowerUnderscoreToUpperCamel(grpc::string str) {
+  std::vector<grpc::string> tokens = tokenize(str, "_");
+  grpc::string result = "";
+  for (unsigned int i = 0; i < tokens.size(); i++) {
+    result += CapitalizeFirstLetter(tokens[i]);
+  }
+  return result;
+}
+
+inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *file) {
+  return LowerUnderscoreToUpperCamel(StripProto(file->name()));
+}
+
 }  // namespace grpc_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
new file mode 100644
index 0000000..c68c9c3
--- /dev/null
+++ b/src/compiler/objective_c_generator.cc
@@ -0,0 +1,236 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <map>
+
+#include "src/compiler/objective_c_generator.h"
+#include "src/compiler/objective_c_generator_helpers.h"
+
+#include "src/compiler/config.h"
+
+#include <sstream>
+
+namespace grpc_objective_c_generator {
+namespace {
+
+void PrintSimpleBlockSignature(grpc::protobuf::io::Printer *printer,
+                               const grpc::protobuf::MethodDescriptor *method,
+                               std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["method_name"] = method->name();
+  (*vars)["request_type"] = PrefixedName(method->input_type()->name());
+  (*vars)["response_type"] = PrefixedName(method->output_type()->name());
+
+  if (method->server_streaming()) {
+    printer->Print("// When the response stream finishes, the handler is "
+                   "called with nil for both arguments.\n\n");
+  } else {
+    printer->Print("// The handler is only called once.\n\n");
+  }
+  printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:"
+                 "($request_type$)request completionHandler:(void(^)"
+                 "($response_type$ *, NSError *))handler");
+}
+
+void PrintSimpleDelegateSignature(grpc::protobuf::io::Printer *printer,
+                                  const grpc::protobuf::MethodDescriptor *method,
+                                  std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["method_name"] = method->name();
+  (*vars)["request_type"] = PrefixedName(method->input_type()->name());
+
+  printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:"
+                 "($request_type$)request delegate:(id<GRXSink>)delegate");
+}
+
+void PrintAdvancedSignature(grpc::protobuf::io::Printer *printer,
+                            const grpc::protobuf::MethodDescriptor *method,
+                            std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["method_name"] = method->name();
+  printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:"
+                 "(id<GRXSource>)request");
+}
+
+void PrintSourceMethodSimpleBlock(grpc::protobuf::io::Printer *printer,
+                                  const grpc::protobuf::MethodDescriptor *method,
+                                  std::map<grpc::string, grpc::string> *vars) {
+  PrintSimpleBlockSignature(printer, method, vars);
+
+  (*vars)["method_name"] = method->name();
+  printer->Print(" {\n");
+  printer->Indent();
+  printer->Print(*vars, "return [[self $method_name$WithRequest:request] "
+                 "connectHandler:^(id value, NSError *error) {\n");
+  printer->Indent();
+  printer->Print("handler(value, error);\n");
+  printer->Outdent();
+  printer->Print("}];\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void PrintSourceMethodSimpleDelegate(grpc::protobuf::io::Printer *printer,
+                                     const grpc::protobuf::MethodDescriptor *method,
+                                     std::map<grpc::string, grpc::string> *vars) {
+  PrintSimpleDelegateSignature(printer, method, vars);
+
+  (*vars)["method_name"] = method->name();
+  printer->Print(" {\n");
+  printer->Indent();
+  printer->Print(*vars, "return [[self $method_name$WithRequest:request]"
+                 "connectToSink:delegate];\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void PrintSourceMethodAdvanced(grpc::protobuf::io::Printer *printer,
+                               const grpc::protobuf::MethodDescriptor *method,
+                               std::map<grpc::string, grpc::string> *vars) {
+  PrintAdvancedSignature(printer, method, vars);
+
+  (*vars)["method_name"] = method->name();
+  printer->Print(" {\n");
+  printer->Indent();
+  printer->Print(*vars, "return [self $method_name$WithRequest:request "
+                 "client:[self newClient]];\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void PrintSourceMethodHandler(grpc::protobuf::io::Printer *printer,
+                              const grpc::protobuf::MethodDescriptor *method,
+                              std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["method_name"] = method->name();
+  (*vars)["response_type"] = PrefixedName(method->output_type()->name());
+  (*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name());
+
+  printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:"
+                 "(id<GRXSource>)request client:(PBgRPCClient *)client {\n");
+  printer->Indent();
+  printer->Print(*vars,
+                 "return [self responseWithMethod:$@\"$caps_name\"\n");
+  printer->Print(*vars,
+                 "                          class:[$response_type$ class]\n");
+  printer->Print("                        request:request\n");
+  printer->Print("                         client:client];\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+}
+
+grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service,
+                       const grpc::string message_header) {
+  grpc::string output;
+  grpc::protobuf::io::StringOutputStream output_stream(&output);
+  grpc::protobuf::io::Printer printer(&output_stream, '$');
+  std::map<grpc::string, grpc::string> vars;
+  printer.Print("#import \"PBgRPCClient.h\"\n");
+  printer.Print("#import \"PBStub.h\"\n");
+  vars["message_header"] = message_header;
+  printer.Print(vars, "#import \"$message_header$\"\n\n");
+  printer.Print("@protocol GRXSource\n");
+  printer.Print("@class GRXSource\n\n");
+  vars["service_name"] = service->name();
+  printer.Print("@protocol $service_name$Stub <NSObject>\n\n");
+  printer.Print("#pragma mark Simple block handlers\n\n");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintSimpleBlockSignature(&printer, service->method(i), &vars);
+    printer.Print(";\n");
+  }
+  printer.Print("\n");
+  printer.Print("#pragma mark Simple delegate handlers.\n\n");
+  printer.Print("# TODO(jcanizales): Use high-level snippets to remove this duplication.");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintSimpleDelegateSignature(&printer, service->method(i), &vars);
+    printer.Print(";\n");
+  }
+  printer.Print("\n");
+  printer.Print("#pragma mark Advanced handlers.\n\n");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintAdvancedSignature(&printer, service->method(i), &vars);
+    printer.Print(";\n");
+  }
+  printer.Print("\n");
+  printer.Print("@end\n\n");
+  printer.Print("// Basic stub that only does marshalling and parsing\n");
+  printer.Print(vars, "@interface $service_name$Stub :"
+                " PBStub<$service_name$Stub>\n");
+  printer.Print("- (instancetype)initWithHost:(NSString *)host;\n");
+  printer.Print("@end\n");
+  return output;
+}
+
+grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service) {
+  grpc::string output;
+  grpc::protobuf::io::StringOutputStream output_stream(&output);
+  grpc::protobuf::io::Printer printer(&output_stream, '$');
+  std::map<grpc::string, grpc::string> vars;
+  vars["service_name"] = service->name();
+  printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n");
+  printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n");
+  vars["full_name"] = service->full_name();
+  printer.Print(vars,
+                "static NSString *const kInterface = @\"$full_name$\";\n");
+  printer.Print("@implementation $service_name$Stub\n\n");
+  printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
+  printer.Indent();
+  printer.Print("if ((self = [super initWithHost:host "
+                "interface:kInterface])) {\n");
+  printer.Print("}\n");
+  printer.Print("return self;\n");
+  printer.Outdent();
+  printer.Print("}\n\n");
+  printer.Print("#pragma mark Simple block handlers.\n");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintSourceMethodSimpleBlock(&printer, service->method(i), &vars);
+  }
+  printer.Print("\n");
+  printer.Print("#pragma mark Simple delegate handlers.\n");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintSourceMethodSimpleDelegate(&printer, service->method(i), &vars);
+  }
+  printer.Print("\n");
+  printer.Print("#pragma mark Advanced handlers.\n");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintSourceMethodAdvanced(&printer, service->method(i), &vars);
+  }
+  printer.Print("\n");
+  printer.Print("#pragma mark Handlers for subclasses "
+                "(stub wrappers) to override.\n");
+  for (int i = 0; i < service->method_count(); i++) {
+    PrintSourceMethodHandler(&printer, service->method(i), &vars);
+  }
+  printer.Print("@end\n");
+  return output;
+}
+
+} // namespace grpc_objective_c_generator
diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h
new file mode 100644
index 0000000..93c730b
--- /dev/null
+++ b/src/compiler/objective_c_generator.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
+
+#include "src/compiler/config.h"
+
+namespace grpc_objective_c_generator {
+
+grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service,
+                       const grpc::string message_header);
+
+grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service);
+
+}  // namespace grpc_objective_c_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h
new file mode 100644
index 0000000..6a7c139
--- /dev/null
+++ b/src/compiler/objective_c_generator_helpers.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
+#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
+
+#include <map>
+#include "src/compiler/config.h"
+#include "src/compiler/generator_helpers.h"
+
+namespace grpc_objective_c_generator {
+
+const grpc::string prefix = "PBG";
+
+inline grpc::string MessageHeaderName(const grpc::protobuf::FileDescriptor *file) {
+  return grpc_generator::FileNameInUpperCamel(file) + ".pb.h";
+}
+
+inline grpc::string StubFileName(grpc::string service_name) {
+  return prefix + service_name + "Stub";
+}
+
+inline grpc::string PrefixedName(grpc::string name) {
+  return prefix + name;
+}
+
+}
+#endif  // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
new file mode 100644
index 0000000..eebce0c
--- /dev/null
+++ b/src/compiler/objective_c_plugin.cc
@@ -0,0 +1,98 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+// Generates Objective C gRPC service interface out of Protobuf IDL.
+
+#include <memory>
+
+#include "src/compiler/config.h"
+#include "src/compiler/objective_c_generator.h"
+#include "src/compiler/objective_c_generator_helpers.h"
+
+class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
+ public:
+  ObjectiveCGrpcGenerator() {}
+  virtual ~ObjectiveCGrpcGenerator() {}
+
+  virtual bool Generate(const grpc::protobuf::FileDescriptor *file,
+                        const grpc::string &parameter,
+                        grpc::protobuf::compiler::GeneratorContext *context,
+                        grpc::string *error) const {
+
+    if (file->service_count() == 0) {
+      // No services.  Do nothing.
+      return true;
+    }
+
+    for (int i = 0; i < file->service_count(); i++) {
+      const grpc::protobuf::ServiceDescriptor *service = file->service(i);
+      grpc::string file_name = grpc_objective_c_generator::StubFileName(
+          service->name());
+
+      // Generate .pb.h
+      grpc::string header_code = grpc_objective_c_generator::GetHeader(
+          service, grpc_objective_c_generator::MessageHeaderName(file));
+      std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
+        context->Open(file_name + ".pb.h"));
+      grpc::protobuf::io::CodedOutputStream header_coded_out(
+          header_output.get());
+      header_coded_out.WriteRaw(header_code.data(), header_code.size());
+
+      // Generate .pb.m
+      grpc::string source_code = grpc_objective_c_generator::GetSource(service);
+      std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
+        context->Open(file_name + ".pb.m"));
+      grpc::protobuf::io::CodedOutputStream source_coded_out(
+          source_output.get());
+      source_coded_out.WriteRaw(source_code.data(), source_code.size());
+    }
+
+    return true;
+  }
+
+ private:
+  // Insert the given code into the given file at the given insertion point.
+  void Insert(grpc::protobuf::compiler::GeneratorContext *context,
+              const grpc::string &filename, const grpc::string &insertion_point,
+              const grpc::string &code) const {
+    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
+        context->OpenForInsert(filename, insertion_point));
+    grpc::protobuf::io::CodedOutputStream coded_out(output.get());
+    coded_out.WriteRaw(code.data(), code.size());
+  }
+};
+
+int main(int argc, char *argv[]) {
+  ObjectiveCGrpcGenerator generator;
+  return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
+}
diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c
index f92fb64..3cc7982 100644
--- a/src/core/support/thd_win32.c
+++ b/src/core/support/thd_win32.c
@@ -61,7 +61,7 @@
 static thread_local struct thd_info *g_thd_info;
 
 /* Destroys a thread info */
-static destroy_thread(struct thd_info *t) {
+static void destroy_thread(struct thd_info *t) {
   if (t->joinable) CloseHandle(t->join_event);
   gpr_free(t);
 }
diff --git a/src/csharp/Grpc.Examples.MathServer/.gitignore b/src/csharp/Grpc.Examples.MathServer/.gitignore
new file mode 100644
index 0000000..1746e32
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/.gitignore
@@ -0,0 +1,2 @@
+bin
+obj
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
new file mode 100644
index 0000000..3f7e6c0
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Grpc.Examples.MathServer</RootNamespace>
+    <AssemblyName>Grpc.Examples.MathServer</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="MathServer.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
+      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
+      <Name>Grpc.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj">
+      <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project>
+      <Name>Grpc.Examples</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
new file mode 100644
index 0000000..884a84d
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
@@ -0,0 +1,61 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Grpc.Core;
+
+namespace math
+{
+    class MainClass
+    {
+        public static void Main(string[] args)
+        {
+            String host = "0.0.0.0";
+
+            GrpcEnvironment.Initialize();
+
+            Server server = new Server();
+            server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl()));
+            int port = server.AddListeningPort(host + ":0");
+            server.Start();
+
+            Console.WriteLine("MathServer listening on port " + port);
+
+            Console.WriteLine("Press any key to stop the server...");
+            Console.ReadKey();
+
+            server.ShutdownAsync().Wait();
+            GrpcEnvironment.Shutdown();
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6b3d051
--- /dev/null
+++ b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,12 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.Examples.MathServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("0.1.*")]
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 2e6d288..2f8c2e1 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -17,6 +17,8 @@
 EndProject

 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{A654F3B8-E859-4E6A-B30D-227527DBEF0D}"

 EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{BF62FE08-373A-43D6-9D73-41CAA38B7011}"

+EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

 		Debug|x86 = Debug|x86

@@ -47,6 +49,10 @@
 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.Build.0 = Debug|x86

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.ActiveCfg = Release|x86

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.Build.0 = Release|x86

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.ActiveCfg = Debug|x86

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.Build.0 = Debug|x86

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.ActiveCfg = Release|x86

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.Build.0 = Release|x86

 		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.ActiveCfg = Debug|x86

 		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.Build.0 = Debug|x86

 		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.ActiveCfg = Release|x86

diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh
new file mode 100755
index 0000000..16f9374
--- /dev/null
+++ b/src/php/bin/generate_proto_php.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+# 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.
+
+
+set +e
+cd $(dirname $0)
+
+gen_code='../tests/generated_code'
+interop='../tests/interop'
+
+protoc-gen-php -i $gen_code -o $gen_code $gen_code/math.proto
+
+protoc-gen-php -i $interop -o $interop $interop/test.proto
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 6bc65b5..b1525e9 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -443,8 +443,9 @@
         add_property_bool(result, "send_status", true);
         break;
       case GRPC_OP_RECV_INITIAL_METADATA:
-        add_property_zval(result, "metadata",
-                          grpc_parse_metadata_array(&recv_metadata));
+        array = grpc_parse_metadata_array(&recv_metadata);
+        add_property_zval(result, "metadata", array);
+        Z_DELREF_P(array);
         break;
       case GRPC_OP_RECV_MESSAGE:
         byte_buffer_to_string(message, &message_str, &message_len);
@@ -458,11 +459,13 @@
       case GRPC_OP_RECV_STATUS_ON_CLIENT:
         MAKE_STD_ZVAL(recv_status);
         object_init(recv_status);
-        add_property_zval(recv_status, "metadata",
-                          grpc_parse_metadata_array(&recv_trailing_metadata));
+        array = grpc_parse_metadata_array(&recv_trailing_metadata);
+        add_property_zval(recv_status, "metadata", array);
+        Z_DELREF_P(array);
         add_property_long(recv_status, "code", status);
         add_property_string(recv_status, "details", status_details, true);
         add_property_zval(result, "status", recv_status);
+        Z_DELREF_P(recv_status);
         break;
       case GRPC_OP_RECV_CLOSE_ON_SERVER:
         add_property_bool(result, "cancelled", cancelled);
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 51a3eae..b8262db 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -62,6 +62,7 @@
   if (channel->wrapped != NULL) {
     grpc_channel_destroy(channel->wrapped);
   }
+  efree(channel->target);
   efree(channel);
 }
 
diff --git a/src/python/interop/interop/_interop_test_case.py b/src/python/interop/interop/_interop_test_case.py
index fec8f19..cd6a574 100644
--- a/src/python/interop/interop/_interop_test_case.py
+++ b/src/python/interop/interop/_interop_test_case.py
@@ -40,16 +40,16 @@
   """
 
   def testEmptyUnary(self):
-    methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub)
+    methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None)
 
   def testLargeUnary(self):
-    methods.TestCase.LARGE_UNARY.test_interoperability(self.stub)
+    methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None)
 
   def testServerStreaming(self):
-    methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub)
+    methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None)
 
   def testClientStreaming(self):
-    methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub)
+    methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None)
 
   def testPingPong(self):
-    methods.TestCase.PING_PONG.test_interoperability(self.stub)
+    methods.TestCase.PING_PONG.test_interoperability(self.stub, None)
diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py
index 85a0dcd..bae5e17 100644
--- a/src/python/interop/interop/client.py
+++ b/src/python/interop/interop/client.py
@@ -30,6 +30,7 @@
 """The Python implementation of the GRPC interoperability test client."""
 
 import argparse
+from oauth2client import client as oauth2client_client
 
 from grpc.early_adopter import implementations
 
@@ -44,9 +45,6 @@
   parser.add_argument(
       '--server_host', help='the host to which to connect', type=str)
   parser.add_argument(
-      '--server_host_override',
-      help='the server host to which to claim to connect', type=str)
-  parser.add_argument(
       '--server_port', help='the port to which to connect', type=int)
   parser.add_argument(
       '--test_case', help='the test case to execute', type=str)
@@ -56,10 +54,25 @@
   parser.add_argument(
       '--use_test_ca', help='replace platform root CAs with ca.pem',
       action='store_true')
+  parser.add_argument(
+      '--server_host_override',
+      help='the server host to which to claim to connect', type=str)
+  parser.add_argument('--oauth_scope', help='scope for OAuth tokens', type=str)
+  parser.add_argument(
+      '--default_service_account',
+      help='email address of the default service account', type=str)
   return parser.parse_args()
 
+def _oauth_access_token(args):
+  credentials = client.GoogleCredentials.get_application_default()
+  scoped_credentials = credentials.create_scoped([args.oauth_scope])
+  return scoped_credentials.get_access_token().access_token
 
 def _stub(args):
+  if args.oauth_scope:
+    metadata_transformer = lambda x: [('Authorization', 'Bearer %s' % _oauth_access_token(args))]
+  else:
+    metadata_transformer = lambda x: []
   if args.use_tls:
     if args.use_test_ca:
       root_certificates = resources.test_root_certificates()
@@ -68,7 +81,8 @@
 
     stub = implementations.stub(
         methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host,
-        args.server_port, secure=True, root_certificates=root_certificates,
+        args.server_port, metadata_transformer=metadata_transformer,
+        secure=True, root_certificates=root_certificates,
         server_host_override=args.server_host_override)
   else:
     stub = implementations.stub(
@@ -89,7 +103,7 @@
   args = _args()
   stub = _stub(args)
   test_case = _test_case_from_arg(args.test_case)
-  test_case.test_interoperability(stub)
+  test_case.test_interoperability(stub, args)
 
 
 if __name__ == '__main__':
diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py
index 79550a3..c69771d 100644
--- a/src/python/interop/interop/methods.py
+++ b/src/python/interop/interop/methods.py
@@ -30,8 +30,12 @@
 """Implementations of interoperability test methods."""
 
 import enum
+import json
+import os
 import threading
 
+from oauth2client import client as oauth2client_client
+
 from grpc.framework.alpha import utilities
 
 from interop import empty_pb2
@@ -150,6 +154,23 @@
 }
 
 
+def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope):
+  with stub:
+    request = messages_pb2.SimpleRequest(
+        response_type=messages_pb2.COMPRESSABLE, response_size=314159,
+        payload=messages_pb2.Payload(body=b'\x00' * 271828),
+        fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
+    response_future = stub.UnaryCall.async(request, _TIMEOUT)
+    response = response_future.result()
+    if response.payload.type is not messages_pb2.COMPRESSABLE:
+      raise ValueError(
+          'response payload type is "%s"!' % type(response.payload.type))
+    if len(response.payload.body) != 314159:
+      raise ValueError(
+          'response body of incorrect size %d!' % len(response.payload.body))
+    return response
+
+
 def _empty_unary(stub):
   with stub:
     response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
@@ -159,18 +180,7 @@
 
 
 def _large_unary(stub):
-  with stub:
-    request = messages_pb2.SimpleRequest(
-        response_type=messages_pb2.COMPRESSABLE, response_size=314159,
-        payload=messages_pb2.Payload(body=b'\x00' * 271828))
-    response_future = stub.UnaryCall.async(request, _TIMEOUT)
-    response = response_future.result()
-    if response.payload.type is not messages_pb2.COMPRESSABLE:
-      raise ValueError(
-          'response payload type is "%s"!' % type(response.payload.type))
-    if len(response.payload.body) != 314159:
-      raise ValueError(
-          'response body of incorrect size %d!' % len(response.payload.body))
+  _large_unary_common_behavior(stub, False, False)
 
 
 def _client_streaming(stub):
@@ -266,6 +276,28 @@
     pipe.close()
 
 
+def _compute_engine_creds(stub, args):
+  response = _large_unary_common_behavior(stub, True, True)
+  if args.default_service_account != response.username:
+    raise ValueError(
+        'expected username %s, got %s' % (args.default_service_account,
+                                          response.username))
+
+
+def _service_account_creds(stub, args):
+  json_key_filename = os.environ[
+      oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+  wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+  response = _large_unary_common_behavior(stub, True, True)
+  if wanted_email != response.username:
+    raise ValueError(
+        'expected username %s, got %s' % (wanted_email, response.username))
+  if response.oauth_scope in args.oauth_scope:
+    raise ValueError(
+        'expected to find oauth scope "%s" in received "%s"' %
+            (response.oauth_scope, args.oauth_scope))
+
+
 @enum.unique
 class TestCase(enum.Enum):
   EMPTY_UNARY = 'empty_unary'
@@ -273,8 +305,10 @@
   SERVER_STREAMING = 'server_streaming'
   CLIENT_STREAMING = 'client_streaming'
   PING_PONG = 'ping_pong'
+  COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
+  SERVICE_ACCOUNT_CREDS = 'service_account_creds'
 
-  def test_interoperability(self, stub):
+  def test_interoperability(self, stub, args):
     if self is TestCase.EMPTY_UNARY:
       _empty_unary(stub)
     elif self is TestCase.LARGE_UNARY:
@@ -285,5 +319,9 @@
       _client_streaming(stub)
     elif self is TestCase.PING_PONG:
       _ping_pong(stub)
+    elif self is TestCase.COMPUTE_ENGINE_CREDS:
+      _compute_engine_creds(stub, args)
+    elif self is TestCase.SERVICE_ACCOUNT_CREDS:
+      _service_account_creds(stub, args)
     else:
       raise NotImplementedError('Test case "%s" not implemented!' % self.name)
diff --git a/src/python/interop/setup.py b/src/python/interop/setup.py
index 7a32992..502fcbe 100644
--- a/src/python/interop/setup.py
+++ b/src/python/interop/setup.py
@@ -45,7 +45,7 @@
         'credentials/server1.pem',]
 }
 
-_INSTALL_REQUIRES = ['grpcio>=0.4.0a4']
+_INSTALL_REQUIRES = ['oauth2client>=1.4.7', 'grpcio>=0.4.0a4']
 
 setuptools.setup(
     name='interop',
diff --git a/templates/Makefile.template b/templates/Makefile.template
index d6c80a5..776ee7a 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -35,17 +35,11 @@
 
   proto_re = re.compile('(.*)\\.proto')
 
-  def excluded(filename, exclude_res):
-    for r in exclude_res:
-      if r.match(filename):
-        return True
-    return False
-
   def proto_to_cc(filename):
     m = proto_re.match(filename)
     if not m:
       return filename
-    return '$(GENDIR)/' + m.group(1) + '.pb.cc'
+    return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc'
 %>
 
 
@@ -840,11 +834,17 @@
 % for p in protos:
 ifeq ($(NO_PROTOC),true)
 $(GENDIR)/${p}.pb.cc: protoc_dep_error
+$(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error
 else
 $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
 	$(E) "[PROTOC]  Generating protobuf CC file from $<"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
 endif
 
 % endfor
@@ -926,10 +926,10 @@
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/${lib.name}.$(SHARED_EXT) $(prefix)/lib/${lib.name}.$(SHARED_EXT)
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a
 else
-ifneq ($(SYSTEM),Darwin)
 	$(E) "[INSTALL] Installing lib${lib.name}.$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT)
+ifneq ($(SYSTEM),Darwin)
 	$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so
 endif
 endif
@@ -1166,7 +1166,7 @@
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs}
+	$(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name lib${lib.name}.$(SHARED_EXT) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs}
 else
 	$(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} -o ${out_libbase}.$(SHARED_EXT) ${common}${libs}
 	$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) ${out_libbase}.so.${settings.version.major}
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 9938fcf..dd294d9 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -35,8 +35,8 @@
 #include <memory>
 
 #include "test/core/util/test_config.h"
-#include "test/cpp/util/echo_duplicate.pb.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo_duplicate.grpc.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
 #include "src/cpp/util/time.h"
 #include <grpc++/async_unary_call.h>
 #include <grpc++/channel_arguments.h>
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 0d5db04..f96051c 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -35,8 +35,8 @@
 #include <thread>
 
 #include "test/core/util/test_config.h"
-#include "test/cpp/util/echo_duplicate.pb.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo_duplicate.grpc.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
 #include "src/cpp/util/time.h"
 #include "src/cpp/server/thread_pool.h"
 #include <grpc++/channel_arguments.h>
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 9cdd8c9..eb6f536 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -38,7 +38,7 @@
 #include "src/cpp/util/time.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
 #include <grpc++/async_generic_service.h>
 #include <grpc++/async_unary_call.h>
 #include <grpc++/byte_buffer.h>
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index de6c6b7..7c5e1aa 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -51,9 +51,9 @@
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/interop/test.pb.h"
-#include "test/cpp/interop/empty.pb.h"
-#include "test/cpp/interop/messages.pb.h"
+#include "test/cpp/interop/test.grpc.pb.h"
+#include "test/cpp/interop/empty.grpc.pb.h"
+#include "test/cpp/interop/messages.grpc.pb.h"
 
 DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
 DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google");
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index 780a737..87bf489 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -49,9 +49,9 @@
 #include <grpc++/server_credentials.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
-#include "test/cpp/interop/test.pb.h"
-#include "test/cpp/interop/empty.pb.h"
-#include "test/cpp/interop/messages.pb.h"
+#include "test/cpp/interop/test.grpc.pb.h"
+#include "test/cpp/interop/empty.grpc.pb.h"
+#include "test/cpp/interop/messages.grpc.pb.h"
 
 DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
 DEFINE_int32(port, 0, "Server port.");
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index cae7f44..08b338c 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -36,7 +36,7 @@
 
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/timer.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 
 #include <condition_variable>
 #include <mutex>
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 1ed3c71..c01d840 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -48,7 +48,7 @@
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 #include "test/cpp/qps/timer.h"
 #include "test/cpp/qps/client.h"
 
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 77da172..9476181 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -55,7 +55,7 @@
 #include <gtest/gtest.h>
 #include "test/cpp/util/create_test_channel.h"
 #include "test/cpp/qps/client.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/timer.h"
 
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 64a5349..f448837 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -74,7 +74,9 @@
 ScenarioResult RunScenario(const ClientConfig& initial_client_config,
                            size_t num_clients,
                            const ServerConfig& server_config,
-                           size_t num_servers) {
+                           size_t num_servers,
+                           int warmup_seconds,
+                           int benchmark_seconds) {
   // ClientContext allocator (all are destroyed at scope exit)
   list<ClientContext> contexts;
   auto alloc_context = [&contexts]() {
@@ -146,7 +148,7 @@
   // Let everything warmup
   gpr_log(GPR_INFO, "Warming up");
   gpr_timespec start = gpr_now();
-  gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(5)));
+  gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(warmup_seconds)));
 
   // Start a run
   gpr_log(GPR_INFO, "Starting");
@@ -171,7 +173,7 @@
 
   // Wait some time
   gpr_log(GPR_INFO, "Running");
-  gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(15)));
+  gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds)));
 
   // Finish a run
   ScenarioResult result;
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index d87e80d..b3a8bf8 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -35,7 +35,7 @@
 #define TEST_QPS_DRIVER_H
 
 #include "test/cpp/qps/histogram.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
@@ -54,7 +54,10 @@
 ScenarioResult RunScenario(const grpc::testing::ClientConfig& client_config,
                            size_t num_clients,
                            const grpc::testing::ServerConfig& server_config,
-                           size_t num_servers);
+                           size_t num_servers,
+                           int warmup_seconds,
+                           int benchmark_seconds);
+
 }  // namespace testing
 }  // namespace grpc
 
diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h
index 7ba00e9..eb17821 100644
--- a/test/cpp/qps/histogram.h
+++ b/test/cpp/qps/histogram.h
@@ -35,7 +35,7 @@
 #define TEST_QPS_HISTOGRAM_H
 
 #include <grpc/support/histogram.h>
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index f7aa8e2..f42d538 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -40,6 +40,9 @@
 DEFINE_int32(num_clients, 1, "Number of client binaries");
 DEFINE_int32(num_servers, 1, "Number of server binaries");
 
+DEFINE_int32(warmup_seconds, 5, "Warmup time (in seconds)");
+DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)");
+
 // Common config
 DEFINE_bool(enable_ssl, false, "Use SSL");
 DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING");
@@ -98,8 +101,9 @@
   server_config.set_threads(FLAGS_server_threads);
   server_config.set_enable_ssl(FLAGS_enable_ssl);
 
-  auto result = RunScenario(client_config, FLAGS_num_clients, server_config,
-                            FLAGS_num_servers);
+  auto result = RunScenario(client_config, FLAGS_num_clients,
+                            server_config, FLAGS_num_servers,
+                            FLAGS_warmup_seconds, FLAGS_benchmark_seconds);
 
   gpr_log(GPR_INFO, "QPS: %.1f",
           result.latencies.Count() /
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index ef71cb9..68e0115 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -35,7 +35,7 @@
 #define TEST_QPS_SERVER_H
 
 #include "test/cpp/qps/timer.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 65c170a..2e366a8d 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -52,7 +52,7 @@
 #include <grpc++/stream.h>
 #include <gtest/gtest.h>
 #include "src/cpp/server/thread_pool.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 #include "test/cpp/qps/server.h"
 
 #include <grpc/grpc.h>
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 9964429..2770233 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -47,7 +47,7 @@
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "src/cpp/server/thread_pool.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 #include "test/cpp/qps/server.h"
 #include "test/cpp/qps/timer.h"
 
diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc
index b6830cc..101eb9f 100644
--- a/test/cpp/qps/worker.cc
+++ b/test/cpp/qps/worker.cc
@@ -55,7 +55,7 @@
 #include <grpc++/stream.h>
 #include "test/core/util/grpc_profiler.h"
 #include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/qps/qpstest.pb.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
 #include "test/cpp/qps/client.h"
 #include "test/cpp/qps/server.h"
 
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 91fc40c..32ef392 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -33,7 +33,7 @@
 
 #include "test/core/util/test_config.h"
 #include "test/cpp/util/cli_call.h"
-#include "test/cpp/util/echo.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
 #include "src/cpp/server/thread_pool.h"
 #include <grpc++/channel_arguments.h>
 #include <grpc++/channel_interface.h>
diff --git a/tools/distpackages/build_deb_packages.sh b/tools/distpackages/build_deb_packages.sh
index 7dff8e3..0beb41e 100755
--- a/tools/distpackages/build_deb_packages.sh
+++ b/tools/distpackages/build_deb_packages.sh
@@ -30,9 +30,13 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 # Where to put resulting .deb packages.
+set -x
 deb_dest="/tmp/deb_out"
 mkdir -p $deb_dest
 
+# Where the grpc disto is
+grpc_root="/var/local/git/grpc"
+
 # Update version from default values if the file /version.txt exists
 #
 # - when present, /version.txt will added by the docker build.
@@ -41,7 +45,13 @@
   pkg_version=$(cat /version.txt)
 fi
 version="${pkg_version}.0"
-echo "Target release => $pkg_version"
+release_tag="release-${pkg_version//./_}"
+echo "Target release => $pkg_version, will checkout tag $release_tag"
+
+# Switch grpc_root to the release tag
+pushd $grpc_root
+git checkout $release_tag || { echo "bad release tag ${release_tag}"; exit 1; }
+popd
 
 if [ -f /.dockerinit ]; then
   # We're in Docker where uname -p returns "unknown".
@@ -71,7 +81,9 @@
   if [ $pkg_name == "libgrpc" ]
   then
     # Copy shared libraries
-    (cd ../..; make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib)
+    pushd $grpc_root
+    make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib
+    popd
     mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir
 
     # non-dev package should contain so.0 symlinks
@@ -84,7 +96,10 @@
   if [ $pkg_name == "libgrpc-dev" ]
   then
     # Copy headers and static libraries
-    (cd ../..; make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib)
+    pushd $grpc_root
+    make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib
+    popd
+
     mv $tmp_dir/$pkg_name/usr/lib/include $tmp_dir/$pkg_name/usr/include
     mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir
 
diff --git a/tools/distpackages/templates/libgrpc/DEBIAN/control b/tools/distpackages/templates/libgrpc/DEBIAN/control
index 417a825..5854b1f 100644
--- a/tools/distpackages/templates/libgrpc/DEBIAN/control
+++ b/tools/distpackages/templates/libgrpc/DEBIAN/control
@@ -2,7 +2,8 @@
 Version: 0.5.0
 Architecture: amd64
 Maintainer: Jan Tattermusch <jtattermusch@google.com>
-Depends: libc6
+Depends: libc6, openssl (1.0.2-1)
+Build-Depends-Indep: openssl (1.0.2-1)
 Section: libs
 Priority: optional
 Homepage: https://github.com/grpc/grpc
diff --git a/tools/dockerfile/grpc_build_deb/Dockerfile b/tools/dockerfile/grpc_build_deb/Dockerfile
index cf8da59..7f025b6 100644
--- a/tools/dockerfile/grpc_build_deb/Dockerfile
+++ b/tools/dockerfile/grpc_build_deb/Dockerfile
@@ -33,8 +33,14 @@
 # Add the file containing the gRPC version
 ADD version.txt version.txt
 
+# Add the update-to-date distpackages folder
+ADD distpackages distpackages
+
 # Install dependencies
-RUN apt-get update && apt-get install -y lintian
+RUN echo 'deb http://http.debian.net/debian experimental main contrib non-free' >> /etc/apt/sources.list
+RUN apt-get update \
+  && apt-get -t experimental install -y openssl=1.0.2-1 \
+  && apt-get install -y lintian
 
 # Get the source from GitHub
 RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
@@ -42,4 +48,4 @@
   git pull --recurse-submodules && \
   git submodule update --init --recursive
 
-RUN /bin/bash -l -c 'cd /var/local/git/grpc/tools/distpackages && ./build_deb_packages.sh'
+RUN /bin/bash -l -c 'cd /distpackages && ./build_deb_packages.sh'
diff --git a/tools/dockerfile/grpc_build_deb/version.txt b/tools/dockerfile/grpc_build_deb/version.txt
index 4b9fcbe..a918a2a 100644
--- a/tools/dockerfile/grpc_build_deb/version.txt
+++ b/tools/dockerfile/grpc_build_deb/version.txt
@@ -1 +1 @@
-0.5.1
+0.6.0
diff --git a/tools/dockerfile/grpc_dist_proto/version.txt b/tools/dockerfile/grpc_dist_proto/version.txt
index 8f0916f..a918a2a 100644
--- a/tools/dockerfile/grpc_dist_proto/version.txt
+++ b/tools/dockerfile/grpc_dist_proto/version.txt
@@ -1 +1 @@
-0.5.0
+0.6.0
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index 0e82ac1..4063429 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -747,6 +747,11 @@
   local project_opt="--project $grpc_project"
   local zone_opt="--zone $grpc_zone"
 
+  # Update the remote distpackages_dir
+  local src_dist_dir='tools/distpackages'
+  local rmt_dist_dir="$host:~"
+  gcloud compute copy-files $src_dist_dir $rmt_dist_dir $project_opt $zone_opt || return 1
+
   # rebuild the build_deb image
   local label='build_deb'
   grpc_update_image -- -h $host $label || return 1
@@ -1036,6 +1041,35 @@
   echo $the_cmd
 }
 
+# constructs the full dockerized python service_account auth interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() {
+  local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
+  local gfe_flags=$(_grpc_prod_gfe_flags)
+  local added_gfe_flags=$(_grpc_default_creds_test_flags)
+  local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
+  env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
+  local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'"
+  echo $the_cmd
+}
+
+# constructs the full dockerized python gce auth interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_auth_compute_engine_creds_gen_python_cmd() {
+  local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
+  local gfe_flags=$(_grpc_prod_gfe_flags)
+  local added_gfe_flags=$(_grpc_gce_test_flags)
+  local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
+  local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'"
+  echo $the_cmd
+}
+
 # constructs the full dockerized java interop test cmd.
 #
 # call-seq:
diff --git a/tools/gce_setup/shared_startup_funcs.sh b/tools/gce_setup/shared_startup_funcs.sh
index e6eecc5..c4a0767 100755
--- a/tools/gce_setup/shared_startup_funcs.sh
+++ b/tools/gce_setup/shared_startup_funcs.sh
@@ -434,6 +434,12 @@
     grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1;
   }
 
+  # For deb builds, copy the distpackages folder into the docker directory so
+  # that it can be installed using ADD distpackages distpackages.
+  [[ $image_label == "grpc/build_deb" ]] && {
+    cp -vR ~/distpackages $dockerfile_dir
+  }
+
   # TODO(temiola): maybe make cache/no-cache a func option?
   sudo docker build $cache_opt -t $image_label $dockerfile_dir || {
     echo "$FUNCNAME:: build of $image_label <- $dockerfile_dir"