compiler: add build option to enable deprecated generated code

partially resolving #1469

The added option for java_plugin `enable_deprecated` is `true` by default in `java_plugin.cpp`, so the generated code for `TestService.java` (`compiler/build.gradle` not setting this option) has all deprecated interfaces and static bindService method.

`./build.gradle` and `examples/build.gradle` set this option explicitly to `false`, so all the other generated classes do not have deprecated code.

Will set `enable_deprecated` to `false` by default in future PR when we are ready.
diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp
index a992c34..73cd6e9 100644
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ b/compiler/src/java_plugin/cpp/java_generator.cpp
@@ -427,110 +427,137 @@
   FUTURE_CALL = 2
 };
 
+static void PrintBindServiceMethodBody(const ServiceDescriptor* service,
+                                   map<string, string>* vars,
+                                   Printer* p,
+                                   bool generate_nano);
+
+static void PrintDeprecatedDocComment(const ServiceDescriptor* service,
+                                      map<string, string>* vars,
+                                      Printer* p) {
+  p->Print(
+      *vars,
+      "/**\n"
+      " * This will be removed in the next release.\n"
+      " * If your code has been using gRPC-java v0.15.0 or higher already,\n"
+      " * the following changes to your code are suggested:\n"
+      " * <ul>\n"
+      " *   <li> replace {@code extends/implements $service_name$}"
+      " with {@code extends $service_name$ImplBase} for server side;</li>\n"
+      " *   <li> replace {@code $service_name$} with {@code $service_name$Stub} for client side;"
+      "</li>\n"
+      " *   <li> replace usage of {@code $service_name$} with {@code $service_name$ImplBase};"
+      "</li>\n"
+      " *   <li> replace usage of {@code Abstract$service_name$}"
+      " with {@link $service_name$ImplBase};</li>\n"
+      " *   <li> replace"
+      " {@code serverBuilder.addService($service_class_name$.bindService(serviceImpl))}\n"
+      " *        with {@code serverBuilder.addService(serviceImpl)};</li>\n"
+      " *   <li> if you are mocking stubs using mockito, please do not mock them.\n"
+      " *        See the documentation on testing with gRPC-java;</li>\n"
+      " *   <li> replace {@code $service_name$BlockingClient}"
+      " with {@link $service_name$BlockingStub};</li>\n"
+      " *   <li> replace {@code $service_name$FutureClient}"
+      " with {@link $service_name$FutureStub}.</li>\n"
+      " * </ul>\n"
+      " */\n");
+}
+
 // Prints a client interface or implementation class, or a server interface.
 static void PrintStub(
     const ServiceDescriptor* service,
     map<string, string>* vars,
-    Printer* p, StubType type, bool generate_nano) {
-  (*vars)["service_name"] = service->name();
-  (*vars)["abstract_name"] = service->name() + "ImplBase";
-  string interface_name = service->name();
-  string impl_name = service->name();
-  bool abstract = false;
+    Printer* p, StubType type, bool generate_nano,
+    bool enable_deprecated) {
+  const string service_name = service->name();
+  (*vars)["service_name"] = service_name;
+  (*vars)["abstract_name"] = service_name + "ImplBase";
+  string stub_name = service_name;
+  string client_name = service_name;
+  CallType call_type;
+  bool impl_base = false;
+  bool interface = false;
   switch (type) {
     case ABSTRACT_CLASS:
-      abstract = true;
+      call_type = ASYNC_CALL;
+      impl_base = true;
       break;
-    case ASYNC_INTERFACE:
     case ASYNC_CLIENT_IMPL:
-      impl_name += "Stub";
+      call_type = ASYNC_CALL;
+      stub_name += "Stub";
       break;
     case BLOCKING_CLIENT_INTERFACE:
+      interface = true;
     case BLOCKING_CLIENT_IMPL:
-      interface_name += "BlockingClient";
-      impl_name += "BlockingStub";
+      call_type = BLOCKING_CALL;
+      stub_name += "BlockingStub";
+      client_name += "BlockingClient";
       break;
     case FUTURE_CLIENT_INTERFACE:
+      interface = true;
     case FUTURE_CLIENT_IMPL:
-      interface_name += "FutureClient";
-      impl_name += "FutureStub";
+      call_type = FUTURE_CALL;
+      stub_name += "FutureStub";
+      client_name += "FutureClient";
       break;
-    case BLOCKING_SERVER_INTERFACE:
-      interface_name += "BlockingServer";
+    case ASYNC_INTERFACE:
+      call_type = ASYNC_CALL;
+      interface = true;
       break;
     default:
       GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type;
   }
-  CallType call_type;
-  bool impl = false;
-  switch (type) {
-    case ABSTRACT_CLASS:
-    case ASYNC_INTERFACE:
-      call_type = ASYNC_CALL;
-      impl = false;
-      break;
-    case BLOCKING_CLIENT_INTERFACE:
-    case BLOCKING_SERVER_INTERFACE:
-      call_type = BLOCKING_CALL;
-      impl = false;
-      break;
-    case FUTURE_CLIENT_INTERFACE:
-      call_type = FUTURE_CALL;
-      impl = false;
-      break;
-    case ASYNC_CLIENT_IMPL:
-      call_type = ASYNC_CALL;
-      impl = true;
-      break;
-    case BLOCKING_CLIENT_IMPL:
-      call_type = BLOCKING_CALL;
-      impl = true;
-      break;
-    case FUTURE_CLIENT_IMPL:
-      call_type = FUTURE_CALL;
-      impl = true;
-      break;
-    default:
-      GRPC_CODEGEN_FAIL << "Cannot determine call type for StubType: " << type;
-  }
-  (*vars)["interface_name"] = interface_name;
-  (*vars)["impl_name"] = impl_name;
+  (*vars)["stub_name"] = stub_name;
+  (*vars)["client_name"] = client_name;
 
-  bool interface = !abstract && !impl;
   // Class head
-  if (abstract) {
-    p->Print(
-        *vars,
-        "@$ExperimentalApi$(\"https://github.com/grpc/grpc-java/issues/1469\")\n"
-        "public static abstract class $abstract_name$ implements $service_name$, "
-        "$BindableService$ {\n");
-  } else if (interface) {
-    // TODO(nmittler): Replace with WriteServiceDocComment when included in protobuf distribution.
-    // Print the service-level javadoc when we define the interface.
+  if (!interface) {
     GrpcWriteServiceDocComment(p, service);
-    p->Print(
-        *vars,
-        "@$Deprecated$ public static interface $interface_name$ {\n");
+  }
+  if (impl_base) {
+    if (enable_deprecated) {
+      p->Print(
+          *vars,
+          "public static abstract class $abstract_name$ implements $BindableService$, "
+          "$service_name$ {\n");
+    }
+    else {
+      p->Print(
+          *vars,
+          "public static abstract class $abstract_name$ implements $BindableService$ {\n");
+    }
   } else {
-    p->Print(
-        *vars,
-        "public static class $impl_name$ extends $AbstractStub$<$impl_name$>\n"
-        "    implements $interface_name$ {\n");
+    if (enable_deprecated) {
+      if (interface) {
+        p->Print(
+            *vars,
+            "@$Deprecated$ public static interface $client_name$ {\n");
+      } else {
+        p->Print(
+            *vars,
+            "public static class $stub_name$ extends $AbstractStub$<$stub_name$>\n"
+            "    implements $client_name$ {\n");
+      }
+    } else {
+      p->Print(
+          *vars,
+          "public static class $stub_name$ extends $AbstractStub$<$stub_name$> {\n");
+    }
   }
   p->Indent();
 
   // Constructor and build() method
-  if (impl) {
+  if (!impl_base && !interface) {
     p->Print(
         *vars,
-        "private $impl_name$($Channel$ channel) {\n");
+        "private $stub_name$($Channel$ channel) {\n");
     p->Indent();
     p->Print("super(channel);\n");
     p->Outdent();
     p->Print("}\n\n");
     p->Print(
         *vars,
-        "private $impl_name$($Channel$ channel,\n"
+        "private $stub_name$($Channel$ channel,\n"
         "    $CallOptions$ callOptions) {\n");
     p->Indent();
     p->Print("super(channel, callOptions);\n");
@@ -539,12 +566,12 @@
     p->Print(
         *vars,
         "@$Override$\n"
-        "protected $impl_name$ build($Channel$ channel,\n"
+        "protected $stub_name$ build($Channel$ channel,\n"
         "    $CallOptions$ callOptions) {\n");
     p->Indent();
     p->Print(
         *vars,
-        "return new $impl_name$(channel, callOptions);\n");
+        "return new $stub_name$(channel, callOptions);\n");
     p->Outdent();
     p->Print("}\n");
   }
@@ -573,20 +600,18 @@
 
     // Method signature
     p->Print("\n");
-    if (interface) {
-      // TODO(nmittler): Replace with WriteMethodDocComment once included by the protobuf distro.
+    // TODO(nmittler): Replace with WriteMethodDocComment once included by the protobuf distro.
+    if (!interface) {
       GrpcWriteMethodDocComment(p, method);
-    } else {
-      p->Print(
-          *vars,
-          "@$Override$\n");
+      if (enable_deprecated) {
+        p->Print(
+            *vars,
+            "@$Override$\n");
+      }
     }
     p->Print("public ");
     switch (call_type) {
       case BLOCKING_CALL:
-        // TODO(zhangkun83): decide the blocking server interface
-        GRPC_CODEGEN_CHECK(type != BLOCKING_SERVER_INTERFACE)
-            << "Blocking server interface is not available";
         GRPC_CODEGEN_CHECK(!client_streaming)
             << "Blocking client interface with client streaming is unavailable";
         if (server_streaming) {
@@ -629,17 +654,14 @@
         break;
     }
 
-    if (!(abstract || impl)) {
-      // Interface method - there will be no body, close method.
+    if (interface) {
       p->Print(";\n");
       continue;
     }
-
-    // Method body for abstract stub & client impls.
+    // Method body.
     p->Print(" {\n");
     p->Indent();
-
-    if (abstract) {
+    if (impl_base) {
       switch (call_type) {
         // NB: Skipping validation of service methods. If something is wrong, we wouldn't get to
         // this point as compiler would return errors when generating service interface.
@@ -657,7 +679,7 @@
         default:
           break;
       }
-    } else if (impl) {
+    } else if (!interface) {
       switch (call_type) {
         case BLOCKING_CALL:
           GRPC_CODEGEN_CHECK(!client_streaming)
@@ -715,16 +737,13 @@
     p->Print("}\n");
   }
 
-  if (abstract) {
+  if (impl_base) {
     p->Print("\n");
-    p->Print(*vars,
-             "@$Override$ public $ServerServiceDefinition$ bindService() {\n"
-             );
-    p->Indent();
-    p->Print(*vars,
-             "return $service_class_name$.bindService(this);\n"
-             );
-    p->Outdent();
+    p->Print(
+        *vars,
+        "@$Override$ public $ServerServiceDefinition$ bindService() {\n");
+    (*vars)["instance"] = "this";
+    PrintBindServiceMethodBody(service, vars, p, generate_nano);
     p->Print("}\n");
   }
 
@@ -743,7 +762,8 @@
 static void PrintMethodHandlerClass(const ServiceDescriptor* service,
                                    map<string, string>* vars,
                                    Printer* p,
-                                   bool generate_nano) {
+                                   bool generate_nano,
+                                   bool enable_deprecated) {
   // Sort method ids based on client_streaming() so switch tables are compact.
   vector<const MethodDescriptor*> sorted_methods(service->method_count());
   for (int i = 0; i < service->method_count(); ++i) {
@@ -760,7 +780,11 @@
         "private static final int $method_id_name$ = $method_id$;\n");
   }
   p->Print("\n");
-  (*vars)["service_name"] = service->name();
+  if (enable_deprecated) {
+    (*vars)["service_name"] = service->name();
+  } else {
+    (*vars)["service_name"] = service->name() + "ImplBase";
+  }
   p->Print(
       *vars,
       "private static class MethodHandlers<Req, Resp> implements\n"
@@ -876,15 +900,11 @@
   p->Print("}\n\n");
 }
 
-static void PrintBindServiceMethod(const ServiceDescriptor* service,
+static void PrintBindServiceMethodBody(const ServiceDescriptor* service,
                                    map<string, string>* vars,
                                    Printer* p,
                                    bool generate_nano) {
   (*vars)["service_name"] = service->name();
-  p->Print(
-      *vars,
-      "@$Deprecated$ public static $ServerServiceDefinition$ bindService(\n"
-      "    final $service_name$ serviceImpl) {\n");
   p->Indent();
   p->Print(*vars,
            "return "
@@ -927,7 +947,7 @@
         "new MethodHandlers<\n"
         "  $input_type$,\n"
         "  $output_type$>(\n"
-        "    serviceImpl, $method_id_name$)))\n");
+        "    $instance$, $method_id_name$)))\n");
     p->Outdent();
     p->Outdent();
   }
@@ -935,13 +955,13 @@
   p->Outdent();
   p->Outdent();
   p->Outdent();
-  p->Print("}\n");
 }
 
 static void PrintService(const ServiceDescriptor* service,
                          map<string, string>* vars,
                          Printer* p,
-                         ProtoFlavor flavor) {
+                         ProtoFlavor flavor,
+                         bool enable_deprecated) {
   (*vars)["service_name"] = service->name();
   (*vars)["file_name"] = service->file()->name();
   (*vars)["service_class_name"] = ServiceClassName(service);
@@ -1011,19 +1031,39 @@
   p->Print("}\n\n");
 
   bool generate_nano = flavor == ProtoFlavor::NANO;
-  PrintStub(service, vars, p, ASYNC_INTERFACE, generate_nano);
-  PrintStub(service, vars, p, ABSTRACT_CLASS, generate_nano);
-  PrintStub(service, vars, p, BLOCKING_CLIENT_INTERFACE, generate_nano);
-  PrintStub(service, vars, p, FUTURE_CLIENT_INTERFACE, generate_nano);
-  PrintStub(service, vars, p, ASYNC_CLIENT_IMPL, generate_nano);
-  PrintStub(service, vars, p, BLOCKING_CLIENT_IMPL, generate_nano);
-  PrintStub(service, vars, p, FUTURE_CLIENT_IMPL, generate_nano);
-  p->Print(*vars,
-           "@$Deprecated$ public static abstract class Abstract$service_name$"
-           " extends $service_name$ImplBase {}\n\n");
-  PrintMethodHandlerClass(service, vars, p, generate_nano);
+  PrintStub(service, vars, p, ABSTRACT_CLASS, generate_nano, enable_deprecated);
+  PrintStub(service, vars, p, ASYNC_CLIENT_IMPL, generate_nano, enable_deprecated);
+  PrintStub(service, vars, p, BLOCKING_CLIENT_IMPL, generate_nano, enable_deprecated);
+  PrintStub(service, vars, p, FUTURE_CLIENT_IMPL, generate_nano, enable_deprecated);
+
+  if (enable_deprecated) {
+    PrintDeprecatedDocComment(service, vars, p);
+    PrintStub(service, vars, p, ASYNC_INTERFACE, generate_nano, true);
+    PrintDeprecatedDocComment(service, vars, p);
+    PrintStub(service, vars, p, BLOCKING_CLIENT_INTERFACE, generate_nano, true);
+    PrintDeprecatedDocComment(service, vars, p);
+    PrintStub(service, vars, p, FUTURE_CLIENT_INTERFACE, generate_nano, true);
+
+    PrintDeprecatedDocComment(service, vars, p);
+    p->Print(
+        *vars,
+        "@$Deprecated$ public static abstract class Abstract$service_name$"
+        " extends $service_name$ImplBase {}\n\n");
+
+    // static bindService method
+    PrintDeprecatedDocComment(service, vars, p);
+    p->Print(
+        *vars,
+        "@$Deprecated$ public static $ServerServiceDefinition$ bindService("
+        "final $service_name$ serviceImpl) {\n");
+    (*vars)["instance"] = "serviceImpl";
+    PrintBindServiceMethodBody(service, vars, p, generate_nano);
+    p->Print(
+        *vars,
+        "}\n\n");
+  }
+  PrintMethodHandlerClass(service, vars, p, generate_nano, enable_deprecated);
   PrintGetServiceDescriptorMethod(service, vars, p, generate_nano);
-  PrintBindServiceMethod(service, vars, p, generate_nano);
   p->Outdent();
   p->Print("}\n");
 }
@@ -1065,7 +1105,8 @@
 
 void GenerateService(const ServiceDescriptor* service,
                      google::protobuf::io::ZeroCopyOutputStream* out,
-                     ProtoFlavor flavor) {
+                     ProtoFlavor flavor,
+                     bool enable_deprecated) {
   // All non-generated classes must be referred by fully qualified names to
   // avoid collision with generated classes.
   map<string, string> vars;
@@ -1112,7 +1153,7 @@
   if (!vars["Package"].empty()) {
     vars["Package"].append(".");
   }
-  PrintService(service, &vars, &printer, flavor);
+  PrintService(service, &vars, &printer, flavor, enable_deprecated);
 }
 
 string ServiceJavaPackage(const FileDescriptor* file, bool nano) {
diff --git a/compiler/src/java_plugin/cpp/java_generator.h b/compiler/src/java_plugin/cpp/java_generator.h
index 29c6fd9..6754249 100644
--- a/compiler/src/java_plugin/cpp/java_generator.h
+++ b/compiler/src/java_plugin/cpp/java_generator.h
@@ -52,7 +52,8 @@
 // Writes the generated service interface into the given ZeroCopyOutputStream
 void GenerateService(const google::protobuf::ServiceDescriptor* service,
                      google::protobuf::io::ZeroCopyOutputStream* out,
-                     ProtoFlavor flavor);
+                     ProtoFlavor flavor,
+                     bool enable_deprecated);
 
 }  // namespace java_grpc_generator
 
diff --git a/compiler/src/java_plugin/cpp/java_plugin.cpp b/compiler/src/java_plugin/cpp/java_plugin.cpp
index 5b4b190..9765fa7 100644
--- a/compiler/src/java_plugin/cpp/java_plugin.cpp
+++ b/compiler/src/java_plugin/cpp/java_plugin.cpp
@@ -37,11 +37,16 @@
 
     java_grpc_generator::ProtoFlavor flavor =
         java_grpc_generator::ProtoFlavor::NORMAL;
+
+    // TODO(zdapeng): turn the default value to false
+    bool enable_deprecated = true;
     for (int i = 0; i < options.size(); i++) {
       if (options[i].first == "nano") {
         flavor = java_grpc_generator::ProtoFlavor::NANO;
       } else if (options[i].first == "lite") {
         flavor = java_grpc_generator::ProtoFlavor::LITE;
+      } else if (options[i].first == "enable_deprecated") {
+        enable_deprecated = options[i].second == "true";
       }
     }
 
@@ -54,7 +59,7 @@
           + java_grpc_generator::ServiceClassName(service) + ".java";
       std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
           context->Open(filename));
-      java_grpc_generator::GenerateService(service, output.get(), flavor);
+      java_grpc_generator::GenerateService(service, output.get(), flavor, enable_deprecated);
     }
     return true;
   }
diff --git a/compiler/src/test/golden/TestService.java.txt b/compiler/src/test/golden/TestService.java.txt
index 9be7964..5774715 100644
--- a/compiler/src/test/golden/TestService.java.txt
+++ b/compiler/src/test/golden/TestService.java.txt
@@ -104,7 +104,7 @@
    * Test service that supports all call types.
    * </pre>
    */
-  @java.lang.Deprecated public static interface TestService {
+  public static abstract class TestServiceImplBase implements io.grpc.BindableService, TestService {
 
     /**
      * <pre>
@@ -112,8 +112,11 @@
      * The server returns the client payload as-is.
      * </pre>
      */
+    @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -121,8 +124,11 @@
      * The server returns the payload with client desired type and sizes.
      * </pre>
      */
+    @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -130,8 +136,11 @@
      * The server returns the aggregated size of client payload as the result.
      * </pre>
      */
+    @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
+      return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -140,8 +149,11 @@
      * demonstrates the idea of full bidirectionality.
      * </pre>
      */
+    @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+      return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -151,37 +163,6 @@
      * first request.
      * </pre>
      */
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
-  }
-
-  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1469")
-  public static abstract class TestServiceImplBase implements TestService, io.grpc.BindableService {
-
-    @java.lang.Override
-    public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
-      asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
-      asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
-      return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
-      return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
-    }
-
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -189,7 +170,43 @@
     }
 
     @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
-      return TestServiceGrpc.bindService(this);
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            METHOD_UNARY_CALL,
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.SimpleRequest,
+                io.grpc.testing.integration.Test.SimpleResponse>(
+                  this, METHODID_UNARY_CALL)))
+          .addMethod(
+            METHOD_STREAMING_OUTPUT_CALL,
+            asyncServerStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                  this, METHODID_STREAMING_OUTPUT_CALL)))
+          .addMethod(
+            METHOD_STREAMING_INPUT_CALL,
+            asyncClientStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingInputCallRequest,
+                io.grpc.testing.integration.Test.StreamingInputCallResponse>(
+                  this, METHODID_STREAMING_INPUT_CALL)))
+          .addMethod(
+            METHOD_FULL_BIDI_CALL,
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                  this, METHODID_FULL_BIDI_CALL)))
+          .addMethod(
+            METHOD_HALF_BIDI_CALL,
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                  this, METHODID_HALF_BIDI_CALL)))
+          .build();
     }
   }
 
@@ -198,43 +215,6 @@
    * Test service that supports all call types.
    * </pre>
    */
-  @java.lang.Deprecated public static interface TestServiceBlockingClient {
-
-    /**
-     * <pre>
-     * One request followed by one response.
-     * The server returns the client payload as-is.
-     * </pre>
-     */
-    public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
-
-    /**
-     * <pre>
-     * One request followed by a sequence of responses (streamed download).
-     * The server returns the payload with client desired type and sizes.
-     * </pre>
-     */
-    public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
-        io.grpc.testing.integration.Test.StreamingOutputCallRequest request);
-  }
-
-  /**
-   * <pre>
-   * Test service that supports all call types.
-   * </pre>
-   */
-  @java.lang.Deprecated public static interface TestServiceFutureClient {
-
-    /**
-     * <pre>
-     * One request followed by one response.
-     * The server returns the client payload as-is.
-     * </pre>
-     */
-    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
-        io.grpc.testing.integration.Test.SimpleRequest request);
-  }
-
   public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
     private TestServiceStub(io.grpc.Channel channel) {
@@ -252,6 +232,12 @@
       return new TestServiceStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
@@ -259,6 +245,12 @@
           getChannel().newCall(METHOD_UNARY_CALL, getCallOptions()), request, responseObserver);
     }
 
+    /**
+     * <pre>
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * </pre>
+     */
     @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -266,6 +258,12 @@
           getChannel().newCall(METHOD_STREAMING_OUTPUT_CALL, getCallOptions()), request, responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests followed by one response (streamed upload).
+     * The server returns the aggregated size of client payload as the result.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
@@ -273,6 +271,13 @@
           getChannel().newCall(METHOD_STREAMING_INPUT_CALL, getCallOptions()), responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests with each request served by the server immediately.
+     * As one request could lead to multiple responses, this interface
+     * demonstrates the idea of full bidirectionality.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -280,6 +285,14 @@
           getChannel().newCall(METHOD_FULL_BIDI_CALL, getCallOptions()), responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests followed by a sequence of responses.
+     * The server buffers all the client requests and then serves them in order. A
+     * stream of responses are returned to the client when the server starts with
+     * first request.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -288,6 +301,11 @@
     }
   }
 
+  /**
+   * <pre>
+   * Test service that supports all call types.
+   * </pre>
+   */
   public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
     private TestServiceBlockingStub(io.grpc.Channel channel) {
@@ -305,12 +323,24 @@
       return new TestServiceBlockingStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request) {
       return blockingUnaryCall(
           getChannel(), METHOD_UNARY_CALL, getCallOptions(), request);
     }
 
+    /**
+     * <pre>
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * </pre>
+     */
     @java.lang.Override
     public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
         io.grpc.testing.integration.Test.StreamingOutputCallRequest request) {
@@ -319,6 +349,11 @@
     }
   }
 
+  /**
+   * <pre>
+   * Test service that supports all call types.
+   * </pre>
+   */
   public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
     private TestServiceFutureStub(io.grpc.Channel channel) {
@@ -336,6 +371,12 @@
       return new TestServiceFutureStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
         io.grpc.testing.integration.Test.SimpleRequest request) {
@@ -344,8 +385,165 @@
     }
   }
 
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestService {
+
+    public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver);
+
+    public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestServiceBlockingClient {
+
+    public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
+
+    public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
+        io.grpc.testing.integration.Test.StreamingOutputCallRequest request);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestServiceFutureClient {
+
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
+        io.grpc.testing.integration.Test.SimpleRequest request);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
   @java.lang.Deprecated public static abstract class AbstractTestService extends TestServiceImplBase {}
 
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(final TestService serviceImpl) {
+    return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+        .addMethod(
+          METHOD_UNARY_CALL,
+          asyncUnaryCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.SimpleRequest,
+              io.grpc.testing.integration.Test.SimpleResponse>(
+                serviceImpl, METHODID_UNARY_CALL)))
+        .addMethod(
+          METHOD_STREAMING_OUTPUT_CALL,
+          asyncServerStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_STREAMING_OUTPUT_CALL)))
+        .addMethod(
+          METHOD_STREAMING_INPUT_CALL,
+          asyncClientStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingInputCallRequest,
+              io.grpc.testing.integration.Test.StreamingInputCallResponse>(
+                serviceImpl, METHODID_STREAMING_INPUT_CALL)))
+        .addMethod(
+          METHOD_FULL_BIDI_CALL,
+          asyncBidiStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_FULL_BIDI_CALL)))
+        .addMethod(
+          METHOD_HALF_BIDI_CALL,
+          asyncBidiStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_HALF_BIDI_CALL)))
+        .build();
+  }
+
   private static final int METHODID_UNARY_CALL = 0;
   private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
   private static final int METHODID_STREAMING_INPUT_CALL = 2;
@@ -411,44 +609,4 @@
         METHOD_HALF_BIDI_CALL);
   }
 
-  @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(
-      final TestService serviceImpl) {
-    return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
-        .addMethod(
-          METHOD_UNARY_CALL,
-          asyncUnaryCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.SimpleRequest,
-              io.grpc.testing.integration.Test.SimpleResponse>(
-                serviceImpl, METHODID_UNARY_CALL)))
-        .addMethod(
-          METHOD_STREAMING_OUTPUT_CALL,
-          asyncServerStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_STREAMING_OUTPUT_CALL)))
-        .addMethod(
-          METHOD_STREAMING_INPUT_CALL,
-          asyncClientStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingInputCallRequest,
-              io.grpc.testing.integration.Test.StreamingInputCallResponse>(
-                serviceImpl, METHODID_STREAMING_INPUT_CALL)))
-        .addMethod(
-          METHOD_FULL_BIDI_CALL,
-          asyncBidiStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_FULL_BIDI_CALL)))
-        .addMethod(
-          METHOD_HALF_BIDI_CALL,
-          asyncBidiStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_HALF_BIDI_CALL)))
-        .build();
-  }
 }
diff --git a/compiler/src/testLite/golden/TestService.java.txt b/compiler/src/testLite/golden/TestService.java.txt
index b81fc9b..7637f07 100644
--- a/compiler/src/testLite/golden/TestService.java.txt
+++ b/compiler/src/testLite/golden/TestService.java.txt
@@ -104,7 +104,7 @@
    * Test service that supports all call types.
    * </pre>
    */
-  @java.lang.Deprecated public static interface TestService {
+  public static abstract class TestServiceImplBase implements io.grpc.BindableService, TestService {
 
     /**
      * <pre>
@@ -112,8 +112,11 @@
      * The server returns the client payload as-is.
      * </pre>
      */
+    @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -121,8 +124,11 @@
      * The server returns the payload with client desired type and sizes.
      * </pre>
      */
+    @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -130,8 +136,11 @@
      * The server returns the aggregated size of client payload as the result.
      * </pre>
      */
+    @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
+      return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -140,8 +149,11 @@
      * demonstrates the idea of full bidirectionality.
      * </pre>
      */
+    @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
+      return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -151,37 +163,6 @@
      * first request.
      * </pre>
      */
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
-  }
-
-  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1469")
-  public static abstract class TestServiceImplBase implements TestService, io.grpc.BindableService {
-
-    @java.lang.Override
-    public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
-      asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
-      asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
-      return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
-      return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
-    }
-
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -189,7 +170,43 @@
     }
 
     @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
-      return TestServiceGrpc.bindService(this);
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            METHOD_UNARY_CALL,
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.SimpleRequest,
+                io.grpc.testing.integration.Test.SimpleResponse>(
+                  this, METHODID_UNARY_CALL)))
+          .addMethod(
+            METHOD_STREAMING_OUTPUT_CALL,
+            asyncServerStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                  this, METHODID_STREAMING_OUTPUT_CALL)))
+          .addMethod(
+            METHOD_STREAMING_INPUT_CALL,
+            asyncClientStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingInputCallRequest,
+                io.grpc.testing.integration.Test.StreamingInputCallResponse>(
+                  this, METHODID_STREAMING_INPUT_CALL)))
+          .addMethod(
+            METHOD_FULL_BIDI_CALL,
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                  this, METHODID_FULL_BIDI_CALL)))
+          .addMethod(
+            METHOD_HALF_BIDI_CALL,
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                  this, METHODID_HALF_BIDI_CALL)))
+          .build();
     }
   }
 
@@ -198,43 +215,6 @@
    * Test service that supports all call types.
    * </pre>
    */
-  @java.lang.Deprecated public static interface TestServiceBlockingClient {
-
-    /**
-     * <pre>
-     * One request followed by one response.
-     * The server returns the client payload as-is.
-     * </pre>
-     */
-    public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
-
-    /**
-     * <pre>
-     * One request followed by a sequence of responses (streamed download).
-     * The server returns the payload with client desired type and sizes.
-     * </pre>
-     */
-    public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
-        io.grpc.testing.integration.Test.StreamingOutputCallRequest request);
-  }
-
-  /**
-   * <pre>
-   * Test service that supports all call types.
-   * </pre>
-   */
-  @java.lang.Deprecated public static interface TestServiceFutureClient {
-
-    /**
-     * <pre>
-     * One request followed by one response.
-     * The server returns the client payload as-is.
-     * </pre>
-     */
-    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
-        io.grpc.testing.integration.Test.SimpleRequest request);
-  }
-
   public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
     private TestServiceStub(io.grpc.Channel channel) {
@@ -252,6 +232,12 @@
       return new TestServiceStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver) {
@@ -259,6 +245,12 @@
           getChannel().newCall(METHOD_UNARY_CALL, getCallOptions()), request, responseObserver);
     }
 
+    /**
+     * <pre>
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * </pre>
+     */
     @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -266,6 +258,12 @@
           getChannel().newCall(METHOD_STREAMING_OUTPUT_CALL, getCallOptions()), request, responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests followed by one response (streamed upload).
+     * The server returns the aggregated size of client payload as the result.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver) {
@@ -273,6 +271,13 @@
           getChannel().newCall(METHOD_STREAMING_INPUT_CALL, getCallOptions()), responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests with each request served by the server immediately.
+     * As one request could lead to multiple responses, this interface
+     * demonstrates the idea of full bidirectionality.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -280,6 +285,14 @@
           getChannel().newCall(METHOD_FULL_BIDI_CALL, getCallOptions()), responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests followed by a sequence of responses.
+     * The server buffers all the client requests and then serves them in order. A
+     * stream of responses are returned to the client when the server starts with
+     * first request.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver) {
@@ -288,6 +301,11 @@
     }
   }
 
+  /**
+   * <pre>
+   * Test service that supports all call types.
+   * </pre>
+   */
   public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
     private TestServiceBlockingStub(io.grpc.Channel channel) {
@@ -305,12 +323,24 @@
       return new TestServiceBlockingStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request) {
       return blockingUnaryCall(
           getChannel(), METHOD_UNARY_CALL, getCallOptions(), request);
     }
 
+    /**
+     * <pre>
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * </pre>
+     */
     @java.lang.Override
     public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
         io.grpc.testing.integration.Test.StreamingOutputCallRequest request) {
@@ -319,6 +349,11 @@
     }
   }
 
+  /**
+   * <pre>
+   * Test service that supports all call types.
+   * </pre>
+   */
   public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
     private TestServiceFutureStub(io.grpc.Channel channel) {
@@ -336,6 +371,12 @@
       return new TestServiceFutureStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
         io.grpc.testing.integration.Test.SimpleRequest request) {
@@ -344,8 +385,165 @@
     }
   }
 
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestService {
+
+    public void unaryCall(io.grpc.testing.integration.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.SimpleResponse> responseObserver);
+
+    public void streamingOutputCall(io.grpc.testing.integration.Test.StreamingOutputCallRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallRequest> streamingInputCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingInputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> fullBidiCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallRequest> halfBidiCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.Test.StreamingOutputCallResponse> responseObserver);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestServiceBlockingClient {
+
+    public io.grpc.testing.integration.Test.SimpleResponse unaryCall(io.grpc.testing.integration.Test.SimpleRequest request);
+
+    public java.util.Iterator<io.grpc.testing.integration.Test.StreamingOutputCallResponse> streamingOutputCall(
+        io.grpc.testing.integration.Test.StreamingOutputCallRequest request);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestServiceFutureClient {
+
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.Test.SimpleResponse> unaryCall(
+        io.grpc.testing.integration.Test.SimpleRequest request);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
   @java.lang.Deprecated public static abstract class AbstractTestService extends TestServiceImplBase {}
 
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(final TestService serviceImpl) {
+    return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+        .addMethod(
+          METHOD_UNARY_CALL,
+          asyncUnaryCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.SimpleRequest,
+              io.grpc.testing.integration.Test.SimpleResponse>(
+                serviceImpl, METHODID_UNARY_CALL)))
+        .addMethod(
+          METHOD_STREAMING_OUTPUT_CALL,
+          asyncServerStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_STREAMING_OUTPUT_CALL)))
+        .addMethod(
+          METHOD_STREAMING_INPUT_CALL,
+          asyncClientStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingInputCallRequest,
+              io.grpc.testing.integration.Test.StreamingInputCallResponse>(
+                serviceImpl, METHODID_STREAMING_INPUT_CALL)))
+        .addMethod(
+          METHOD_FULL_BIDI_CALL,
+          asyncBidiStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_FULL_BIDI_CALL)))
+        .addMethod(
+          METHOD_HALF_BIDI_CALL,
+          asyncBidiStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_HALF_BIDI_CALL)))
+        .build();
+  }
+
   private static final int METHODID_UNARY_CALL = 0;
   private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
   private static final int METHODID_STREAMING_INPUT_CALL = 2;
@@ -411,44 +609,4 @@
         METHOD_HALF_BIDI_CALL);
   }
 
-  @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(
-      final TestService serviceImpl) {
-    return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
-        .addMethod(
-          METHOD_UNARY_CALL,
-          asyncUnaryCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.SimpleRequest,
-              io.grpc.testing.integration.Test.SimpleResponse>(
-                serviceImpl, METHODID_UNARY_CALL)))
-        .addMethod(
-          METHOD_STREAMING_OUTPUT_CALL,
-          asyncServerStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_STREAMING_OUTPUT_CALL)))
-        .addMethod(
-          METHOD_STREAMING_INPUT_CALL,
-          asyncClientStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingInputCallRequest,
-              io.grpc.testing.integration.Test.StreamingInputCallResponse>(
-                serviceImpl, METHODID_STREAMING_INPUT_CALL)))
-        .addMethod(
-          METHOD_FULL_BIDI_CALL,
-          asyncBidiStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_FULL_BIDI_CALL)))
-        .addMethod(
-          METHOD_HALF_BIDI_CALL,
-          asyncBidiStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_HALF_BIDI_CALL)))
-        .build();
-  }
 }
diff --git a/compiler/src/testNano/golden/TestService.java.txt b/compiler/src/testNano/golden/TestService.java.txt
index 18455b9..9c0ac11 100644
--- a/compiler/src/testNano/golden/TestService.java.txt
+++ b/compiler/src/testNano/golden/TestService.java.txt
@@ -182,7 +182,7 @@
    * Test service that supports all call types.
    * </pre>
    */
-  @java.lang.Deprecated public static interface TestService {
+  public static abstract class TestServiceImplBase implements io.grpc.BindableService, TestService {
 
     /**
      * <pre>
@@ -190,8 +190,11 @@
      * The server returns the client payload as-is.
      * </pre>
      */
+    @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.SimpleResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.SimpleResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -199,8 +202,11 @@
      * The server returns the payload with client desired type and sizes.
      * </pre>
      */
+    @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -208,8 +214,11 @@
      * The server returns the aggregated size of client payload as the result.
      * </pre>
      */
+    @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallRequest> streamingInputCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallResponse> responseObserver) {
+      return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -218,8 +227,11 @@
      * demonstrates the idea of full bidirectionality.
      * </pre>
      */
+    @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> fullBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
+      return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
+    }
 
     /**
      * <pre>
@@ -229,37 +241,6 @@
      * first request.
      * </pre>
      */
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> halfBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
-  }
-
-  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1469")
-  public static abstract class TestServiceImplBase implements TestService, io.grpc.BindableService {
-
-    @java.lang.Override
-    public void unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.SimpleResponse> responseObserver) {
-      asyncUnimplementedUnaryCall(METHOD_UNARY_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public void streamingOutputCall(io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request,
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
-      asyncUnimplementedUnaryCall(METHOD_STREAMING_OUTPUT_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallRequest> streamingInputCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallResponse> responseObserver) {
-      return asyncUnimplementedStreamingCall(METHOD_STREAMING_INPUT_CALL, responseObserver);
-    }
-
-    @java.lang.Override
-    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> fullBidiCall(
-        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
-      return asyncUnimplementedStreamingCall(METHOD_FULL_BIDI_CALL, responseObserver);
-    }
-
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> halfBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
@@ -267,7 +248,43 @@
     }
 
     @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
-      return TestServiceGrpc.bindService(this);
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            METHOD_UNARY_CALL,
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.nano.Test.SimpleRequest,
+                io.grpc.testing.integration.nano.Test.SimpleResponse>(
+                  this, METHODID_UNARY_CALL)))
+          .addMethod(
+            METHOD_STREAMING_OUTPUT_CALL,
+            asyncServerStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
+                  this, METHODID_STREAMING_OUTPUT_CALL)))
+          .addMethod(
+            METHOD_STREAMING_INPUT_CALL,
+            asyncClientStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.nano.Test.StreamingInputCallRequest,
+                io.grpc.testing.integration.nano.Test.StreamingInputCallResponse>(
+                  this, METHODID_STREAMING_INPUT_CALL)))
+          .addMethod(
+            METHOD_FULL_BIDI_CALL,
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
+                  this, METHODID_FULL_BIDI_CALL)))
+          .addMethod(
+            METHOD_HALF_BIDI_CALL,
+            asyncBidiStreamingCall(
+              new MethodHandlers<
+                io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
+                io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
+                  this, METHODID_HALF_BIDI_CALL)))
+          .build();
     }
   }
 
@@ -276,43 +293,6 @@
    * Test service that supports all call types.
    * </pre>
    */
-  @java.lang.Deprecated public static interface TestServiceBlockingClient {
-
-    /**
-     * <pre>
-     * One request followed by one response.
-     * The server returns the client payload as-is.
-     * </pre>
-     */
-    public io.grpc.testing.integration.nano.Test.SimpleResponse unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request);
-
-    /**
-     * <pre>
-     * One request followed by a sequence of responses (streamed download).
-     * The server returns the payload with client desired type and sizes.
-     * </pre>
-     */
-    public java.util.Iterator<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> streamingOutputCall(
-        io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request);
-  }
-
-  /**
-   * <pre>
-   * Test service that supports all call types.
-   * </pre>
-   */
-  @java.lang.Deprecated public static interface TestServiceFutureClient {
-
-    /**
-     * <pre>
-     * One request followed by one response.
-     * The server returns the client payload as-is.
-     * </pre>
-     */
-    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.nano.Test.SimpleResponse> unaryCall(
-        io.grpc.testing.integration.nano.Test.SimpleRequest request);
-  }
-
   public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub>
       implements TestService {
     private TestServiceStub(io.grpc.Channel channel) {
@@ -330,6 +310,12 @@
       return new TestServiceStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public void unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.SimpleResponse> responseObserver) {
@@ -337,6 +323,12 @@
           getChannel().newCall(METHOD_UNARY_CALL, getCallOptions()), request, responseObserver);
     }
 
+    /**
+     * <pre>
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * </pre>
+     */
     @java.lang.Override
     public void streamingOutputCall(io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request,
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
@@ -344,6 +336,12 @@
           getChannel().newCall(METHOD_STREAMING_OUTPUT_CALL, getCallOptions()), request, responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests followed by one response (streamed upload).
+     * The server returns the aggregated size of client payload as the result.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallRequest> streamingInputCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallResponse> responseObserver) {
@@ -351,6 +349,13 @@
           getChannel().newCall(METHOD_STREAMING_INPUT_CALL, getCallOptions()), responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests with each request served by the server immediately.
+     * As one request could lead to multiple responses, this interface
+     * demonstrates the idea of full bidirectionality.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> fullBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
@@ -358,6 +363,14 @@
           getChannel().newCall(METHOD_FULL_BIDI_CALL, getCallOptions()), responseObserver);
     }
 
+    /**
+     * <pre>
+     * A sequence of requests followed by a sequence of responses.
+     * The server buffers all the client requests and then serves them in order. A
+     * stream of responses are returned to the client when the server starts with
+     * first request.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> halfBidiCall(
         io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver) {
@@ -366,6 +379,11 @@
     }
   }
 
+  /**
+   * <pre>
+   * Test service that supports all call types.
+   * </pre>
+   */
   public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub>
       implements TestServiceBlockingClient {
     private TestServiceBlockingStub(io.grpc.Channel channel) {
@@ -383,12 +401,24 @@
       return new TestServiceBlockingStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public io.grpc.testing.integration.nano.Test.SimpleResponse unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request) {
       return blockingUnaryCall(
           getChannel(), METHOD_UNARY_CALL, getCallOptions(), request);
     }
 
+    /**
+     * <pre>
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * </pre>
+     */
     @java.lang.Override
     public java.util.Iterator<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> streamingOutputCall(
         io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request) {
@@ -397,6 +427,11 @@
     }
   }
 
+  /**
+   * <pre>
+   * Test service that supports all call types.
+   * </pre>
+   */
   public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub>
       implements TestServiceFutureClient {
     private TestServiceFutureStub(io.grpc.Channel channel) {
@@ -414,6 +449,12 @@
       return new TestServiceFutureStub(channel, callOptions);
     }
 
+    /**
+     * <pre>
+     * One request followed by one response.
+     * The server returns the client payload as-is.
+     * </pre>
+     */
     @java.lang.Override
     public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.nano.Test.SimpleResponse> unaryCall(
         io.grpc.testing.integration.nano.Test.SimpleRequest request) {
@@ -422,8 +463,165 @@
     }
   }
 
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestService {
+
+    public void unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.SimpleResponse> responseObserver);
+
+    public void streamingOutputCall(io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallRequest> streamingInputCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingInputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> fullBidiCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
+
+    public io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest> halfBidiCall(
+        io.grpc.stub.StreamObserver<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> responseObserver);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestServiceBlockingClient {
+
+    public io.grpc.testing.integration.nano.Test.SimpleResponse unaryCall(io.grpc.testing.integration.nano.Test.SimpleRequest request);
+
+    public java.util.Iterator<io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse> streamingOutputCall(
+        io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest request);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static interface TestServiceFutureClient {
+
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.integration.nano.Test.SimpleResponse> unaryCall(
+        io.grpc.testing.integration.nano.Test.SimpleRequest request);
+  }
+
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
   @java.lang.Deprecated public static abstract class AbstractTestService extends TestServiceImplBase {}
 
+  /**
+   * This will be removed in the next release.
+   * If your code has been using gRPC-java v0.15.0 or higher already,
+   * the following changes to your code are suggested:
+   * <ul>
+   *   <li> replace {@code extends/implements TestService} with {@code extends TestServiceImplBase} for server side;</li>
+   *   <li> replace {@code TestService} with {@code TestServiceStub} for client side;</li>
+   *   <li> replace usage of {@code TestService} with {@code TestServiceImplBase};</li>
+   *   <li> replace usage of {@code AbstractTestService} with {@link TestServiceImplBase};</li>
+   *   <li> replace {@code serverBuilder.addService(TestServiceGrpc.bindService(serviceImpl))}
+   *        with {@code serverBuilder.addService(serviceImpl)};</li>
+   *   <li> if you are mocking stubs using mockito, please do not mock them.
+   *        See the documentation on testing with gRPC-java;</li>
+   *   <li> replace {@code TestServiceBlockingClient} with {@link TestServiceBlockingStub};</li>
+   *   <li> replace {@code TestServiceFutureClient} with {@link TestServiceFutureStub}.</li>
+   * </ul>
+   */
+  @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(final TestService serviceImpl) {
+    return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+        .addMethod(
+          METHOD_UNARY_CALL,
+          asyncUnaryCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.nano.Test.SimpleRequest,
+              io.grpc.testing.integration.nano.Test.SimpleResponse>(
+                serviceImpl, METHODID_UNARY_CALL)))
+        .addMethod(
+          METHOD_STREAMING_OUTPUT_CALL,
+          asyncServerStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_STREAMING_OUTPUT_CALL)))
+        .addMethod(
+          METHOD_STREAMING_INPUT_CALL,
+          asyncClientStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.nano.Test.StreamingInputCallRequest,
+              io.grpc.testing.integration.nano.Test.StreamingInputCallResponse>(
+                serviceImpl, METHODID_STREAMING_INPUT_CALL)))
+        .addMethod(
+          METHOD_FULL_BIDI_CALL,
+          asyncBidiStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_FULL_BIDI_CALL)))
+        .addMethod(
+          METHOD_HALF_BIDI_CALL,
+          asyncBidiStreamingCall(
+            new MethodHandlers<
+              io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
+              io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
+                serviceImpl, METHODID_HALF_BIDI_CALL)))
+        .build();
+  }
+
   private static final int METHODID_UNARY_CALL = 0;
   private static final int METHODID_STREAMING_OUTPUT_CALL = 1;
   private static final int METHODID_STREAMING_INPUT_CALL = 2;
@@ -489,44 +687,4 @@
         METHOD_HALF_BIDI_CALL);
   }
 
-  @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(
-      final TestService serviceImpl) {
-    return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
-        .addMethod(
-          METHOD_UNARY_CALL,
-          asyncUnaryCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.nano.Test.SimpleRequest,
-              io.grpc.testing.integration.nano.Test.SimpleResponse>(
-                serviceImpl, METHODID_UNARY_CALL)))
-        .addMethod(
-          METHOD_STREAMING_OUTPUT_CALL,
-          asyncServerStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_STREAMING_OUTPUT_CALL)))
-        .addMethod(
-          METHOD_STREAMING_INPUT_CALL,
-          asyncClientStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.nano.Test.StreamingInputCallRequest,
-              io.grpc.testing.integration.nano.Test.StreamingInputCallResponse>(
-                serviceImpl, METHODID_STREAMING_INPUT_CALL)))
-        .addMethod(
-          METHOD_FULL_BIDI_CALL,
-          asyncBidiStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_FULL_BIDI_CALL)))
-        .addMethod(
-          METHOD_HALF_BIDI_CALL,
-          asyncBidiStreamingCall(
-            new MethodHandlers<
-              io.grpc.testing.integration.nano.Test.StreamingOutputCallRequest,
-              io.grpc.testing.integration.nano.Test.StreamingOutputCallResponse>(
-                serviceImpl, METHODID_HALF_BIDI_CALL)))
-        .build();
-  }
 }