Splitting gRPC service class codegen into its own set of files.
diff --git a/Makefile b/Makefile
index 8e01bb8..c50eb8c 100644
--- a/Makefile
+++ b/Makefile
@@ -2001,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
 
 
@@ -3417,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 \
 
@@ -3480,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 = \
@@ -3658,9 +3718,9 @@
 
 
 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 \
 
@@ -3721,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 \
 
@@ -3783,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 = \
@@ -8426,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))))
@@ -8474,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/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/templates/Makefile.template b/templates/Makefile.template
index 848ee87..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
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.h b/test/cpp/qps/driver.h
index d87e80d..348c032 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 {
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/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>