netty,alts: hide ProtocolNegotiator behind an accessor, and... 

...and move the `close()` method to ProtocolNegotiator rather than Handler.

Since this is a breaking change (for people who ignored our `@Internal` annotations), I wanted to make both changes in the same PR so as to fix them both at the same time.
diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java
index 78ee8d9..3845d8a 100644
--- a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java
+++ b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java
@@ -31,8 +31,8 @@
 import io.grpc.internal.GrpcAttributes;
 import io.grpc.internal.ObjectPool;
 import io.grpc.netty.GrpcHttp2ConnectionHandler;
+import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
 import io.grpc.netty.InternalProtocolNegotiators.AbstractBufferingHandler;
-import io.grpc.netty.ProtocolNegotiator;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.util.AsciiString;
@@ -62,7 +62,7 @@
     final class ClientAltsProtocolNegotiator extends AltsProtocolNegotiator {
 
       @Override
-      public Handler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
+      public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
         TsiHandshaker handshaker = handshakerFactory.newHandshaker(grpcHandler.getAuthority());
         return new BufferUntilAltsNegotiatedHandler(
             grpcHandler,
@@ -80,13 +80,18 @@
     return new ClientAltsProtocolNegotiator();
   }
 
+  @Override
+  public final AsciiString scheme() {
+    return scheme;
+  }
+
   /** Creates a negotiator used for ALTS server. */
   public static AltsProtocolNegotiator createServerNegotiator(
       final TsiHandshakerFactory handshakerFactory, final LazyChannel lazyHandshakerChannel) {
     final class ServerAltsProtocolNegotiator extends AltsProtocolNegotiator {
 
       @Override
-      public Handler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
+      public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
         TsiHandshaker handshaker = handshakerFactory.newHandshaker(/*authority=*/ null);
         return new BufferUntilAltsNegotiatedHandler(
             grpcHandler,
@@ -134,8 +139,7 @@
 
   /** Buffers all writes until the ALTS handshake is complete. */
   @VisibleForTesting
-  static final class BufferUntilAltsNegotiatedHandler extends AbstractBufferingHandler
-      implements ProtocolNegotiator.Handler {
+  static final class BufferUntilAltsNegotiatedHandler extends AbstractBufferingHandler {
 
     private final GrpcHttp2ConnectionHandler grpcHandler;
 
@@ -156,11 +160,6 @@
     }
 
     @Override
-    public AsciiString scheme() {
-      return scheme;
-    }
-
-    @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
       if (logger.isLoggable(Level.FINEST)) {
         logger.log(Level.FINEST, "User Event triggered while negotiating ALTS", new Object[] {evt});
diff --git a/alts/src/main/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiator.java b/alts/src/main/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiator.java
index 47ead1e..2953afd 100644
--- a/alts/src/main/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiator.java
+++ b/alts/src/main/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiator.java
@@ -20,9 +20,11 @@
 import io.grpc.alts.internal.AltsProtocolNegotiator.LazyChannel;
 import io.grpc.internal.GrpcAttributes;
 import io.grpc.netty.GrpcHttp2ConnectionHandler;
+import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
 import io.grpc.netty.InternalProtocolNegotiators;
-import io.grpc.netty.ProtocolNegotiator;
+import io.netty.channel.ChannelHandler;
 import io.netty.handler.ssl.SslContext;
+import io.netty.util.AsciiString;
 
 /** A client-side GPRC {@link ProtocolNegotiator} for Google Default Channel. */
 public final class GoogleDefaultProtocolNegotiator implements ProtocolNegotiator {
@@ -38,6 +40,12 @@
     tlsProtocolNegotiator = InternalProtocolNegotiators.tls(sslContext);
   }
 
+  @Override
+  public AsciiString scheme() {
+    assert tlsProtocolNegotiator.scheme().equals(altsProtocolNegotiator.scheme());
+    return tlsProtocolNegotiator.scheme();
+  }
+
   @VisibleForTesting
   GoogleDefaultProtocolNegotiator(
       ProtocolNegotiator altsProtocolNegotiator, ProtocolNegotiator tlsProtocolNegotiator) {
@@ -46,7 +54,7 @@
   }
 
   @Override
-  public Handler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
+  public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
     if (grpcHandler.getEagAttributes().get(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY) != null
         || grpcHandler.getEagAttributes().get(GrpcAttributes.ATTR_LB_PROVIDED_BACKEND) != null) {
       return altsProtocolNegotiator.newHandler(grpcHandler);
diff --git a/alts/src/test/java/io/grpc/alts/AltsChannelBuilderTest.java b/alts/src/test/java/io/grpc/alts/AltsChannelBuilderTest.java
index e8cc538..da202c5 100644
--- a/alts/src/test/java/io/grpc/alts/AltsChannelBuilderTest.java
+++ b/alts/src/test/java/io/grpc/alts/AltsChannelBuilderTest.java
@@ -19,7 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import io.grpc.alts.internal.AltsProtocolNegotiator;
-import io.grpc.netty.ProtocolNegotiator;
+import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
diff --git a/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java b/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java
index d9bba54..9c84ee2 100644
--- a/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java
+++ b/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java
@@ -19,7 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import io.grpc.alts.internal.GoogleDefaultProtocolNegotiator;
-import io.grpc.netty.ProtocolNegotiator;
+import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
diff --git a/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java b/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java
index 74e342e..50b674f 100644
--- a/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java
+++ b/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java
@@ -25,8 +25,7 @@
 import io.grpc.Attributes;
 import io.grpc.internal.GrpcAttributes;
 import io.grpc.netty.GrpcHttp2ConnectionHandler;
-import io.grpc.netty.ProtocolNegotiator;
-import io.grpc.netty.ProtocolNegotiator.Handler;
+import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,7 +51,7 @@
         Attributes.newBuilder().set(GrpcAttributes.ATTR_LB_PROVIDED_BACKEND, true).build();
     GrpcHttp2ConnectionHandler mockHandler = mock(GrpcHttp2ConnectionHandler.class);
     when(mockHandler.getEagAttributes()).thenReturn(eagAttributes);
-    Handler handler = googleProtocolNegotiator.newHandler(mockHandler);
+    googleProtocolNegotiator.newHandler(mockHandler);
     verify(altsProtocolNegotiator, times(1)).newHandler(mockHandler);
     verify(tlsProtocolNegotiator, never()).newHandler(mockHandler);
   }
@@ -62,7 +61,7 @@
     Attributes eagAttributes = Attributes.EMPTY;
     GrpcHttp2ConnectionHandler mockHandler = mock(GrpcHttp2ConnectionHandler.class);
     when(mockHandler.getEagAttributes()).thenReturn(eagAttributes);
-    Handler handler = googleProtocolNegotiator.newHandler(mockHandler);
+    googleProtocolNegotiator.newHandler(mockHandler);
     verify(altsProtocolNegotiator, never()).newHandler(mockHandler);
     verify(tlsProtocolNegotiator, times(1)).newHandler(mockHandler);
   }
diff --git a/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java b/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java
index 0bbaed0..3b5348d 100644
--- a/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java
+++ b/netty/src/main/java/io/grpc/netty/InternalNettyChannelBuilder.java
@@ -39,7 +39,11 @@
 
   /** A class that provides a Netty handler to control protocol negotiation. */
   public interface ProtocolNegotiatorFactory
-      extends NettyChannelBuilder.ProtocolNegotiatorFactory {}
+      extends NettyChannelBuilder.ProtocolNegotiatorFactory {
+
+    @Override
+    InternalProtocolNegotiator.ProtocolNegotiator buildProtocolNegotiator();
+  }
 
   /**
    * Sets the {@link ProtocolNegotiatorFactory} to be used. Overrides any specified negotiation type
diff --git a/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiator.java b/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiator.java
new file mode 100644
index 0000000..a6a8335
--- /dev/null
+++ b/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2019 The gRPC Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.grpc.netty;
+
+/**
+ * Internal accessor for {@link ProtocolNegotiator}.
+ */
+public final class InternalProtocolNegotiator {
+
+  private InternalProtocolNegotiator() {}
+
+  public interface ProtocolNegotiator extends io.grpc.netty.ProtocolNegotiator {}
+}
diff --git a/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiators.java b/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiators.java
index 8994fa2..eaaf973 100644
--- a/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiators.java
+++ b/netty/src/main/java/io/grpc/netty/InternalProtocolNegotiators.java
@@ -19,6 +19,7 @@
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.handler.ssl.SslContext;
+import io.netty.util.AsciiString;
 
 /**
  * Internal accessor for {@link ProtocolNegotiators}.
@@ -46,7 +47,26 @@
    * be negotiated, the {@code handler} is added and writes to the {@link io.netty.channel.Channel}
    * may happen immediately, even before the TLS Handshake is complete.
    */
-  public static ProtocolNegotiator tls(SslContext sslContext) {
-    return ProtocolNegotiators.tls(sslContext);
+  public static InternalProtocolNegotiator.ProtocolNegotiator tls(SslContext sslContext) {
+    final io.grpc.netty.ProtocolNegotiator negotiator = ProtocolNegotiators.tls(sslContext);
+    final class TlsNegotiator implements InternalProtocolNegotiator.ProtocolNegotiator {
+
+      @Override
+      public AsciiString scheme() {
+        return negotiator.scheme();
+      }
+
+      @Override
+      public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
+        return negotiator.newHandler(grpcHandler);
+      }
+
+      @Override
+      public void close() {
+        negotiator.close();
+      }
+    }
+    
+    return new TlsNegotiator();
   }
 }
diff --git a/netty/src/main/java/io/grpc/netty/NettyClientTransport.java b/netty/src/main/java/io/grpc/netty/NettyClientTransport.java
index 06e3f84..1e4a432 100644
--- a/netty/src/main/java/io/grpc/netty/NettyClientTransport.java
+++ b/netty/src/main/java/io/grpc/netty/NettyClientTransport.java
@@ -80,8 +80,8 @@
   private final long keepAliveTimeNanos;
   private final long keepAliveTimeoutNanos;
   private final boolean keepAliveWithoutCalls;
+  private final AsciiString negotiationScheme;
   private final Runnable tooManyPingsRunnable;
-  private ProtocolNegotiator.Handler negotiationHandler;
   private NettyClientHandler handler;
   // We should not send on the channel until negotiation completes. This is a hard requirement
   // by SslHandler but is appropriate for HTTP/1.1 Upgrade as well.
@@ -104,6 +104,7 @@
       Runnable tooManyPingsRunnable, TransportTracer transportTracer, Attributes eagAttributes,
       LocalSocketPicker localSocketPicker) {
     this.negotiator = Preconditions.checkNotNull(negotiator, "negotiator");
+    this.negotiationScheme = this.negotiator.scheme();
     this.remoteAddress = Preconditions.checkNotNull(address, "address");
     this.group = Preconditions.checkNotNull(group, "group");
     this.channelFactory = channelFactory;
@@ -177,7 +178,7 @@
         headers,
         channel,
         authority,
-        negotiationHandler.scheme(),
+        negotiationScheme,
         userAgent,
         statsTraceCtx,
         transportTracer,
@@ -208,7 +209,7 @@
         authorityString);
     NettyHandlerSettings.setAutoWindow(handler);
 
-    negotiationHandler = negotiator.newHandler(handler);
+    ChannelHandler negotiationHandler = negotiator.newHandler(handler);
 
     Bootstrap b = new Bootstrap();
     b.group(eventLoop);
diff --git a/netty/src/main/java/io/grpc/netty/ProtocolNegotiator.java b/netty/src/main/java/io/grpc/netty/ProtocolNegotiator.java
index 098ba73..c3c668d 100644
--- a/netty/src/main/java/io/grpc/netty/ProtocolNegotiator.java
+++ b/netty/src/main/java/io/grpc/netty/ProtocolNegotiator.java
@@ -16,25 +16,18 @@
 
 package io.grpc.netty;
 
-import io.grpc.Internal;
 import io.netty.channel.ChannelHandler;
 import io.netty.util.AsciiString;
 
 /**
- * A class that provides a Netty handler to control protocol negotiation.
+ * An class that provides a Netty handler to control protocol negotiation.
  */
-@Internal
-public interface ProtocolNegotiator {
+interface ProtocolNegotiator {
 
   /**
-   * The Netty handler to control the protocol negotiation.
+   * The HTTP/2 scheme to be used when sending {@code HEADERS}.
    */
-  interface Handler extends ChannelHandler {
-    /**
-     * The HTTP/2 scheme to be used when sending {@code HEADERS}.
-     */
-    AsciiString scheme();
-  }
+  AsciiString scheme();
 
   /**
    * Creates a new handler to control the protocol negotiation. Once the negotiation has completed
@@ -42,7 +35,7 @@
    * grpcHandler.onHandleProtocolNegotiationCompleted()} at certain point if the negotiation has
    * completed successfully.
    */
-  Handler newHandler(GrpcHttp2ConnectionHandler grpcHandler);
+  ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler);
 
   /**
    * Releases resources held by this negotiator. Called when the Channel transitions to terminated.
diff --git a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java
index 2d8fa27..c028b6b 100644
--- a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java
+++ b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java
@@ -29,7 +29,6 @@
 import io.grpc.Status;
 import io.grpc.internal.GrpcAttributes;
 import io.grpc.internal.GrpcUtil;
-import io.netty.channel.Channel;
 import io.netty.channel.ChannelDuplexHandler;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
@@ -38,7 +37,6 @@
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandler;
 import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
 import io.netty.channel.ChannelPromise;
 import io.netty.handler.codec.http.DefaultHttpRequest;
@@ -85,8 +83,8 @@
   public static ProtocolNegotiator serverPlaintext() {
     return new ProtocolNegotiator() {
       @Override
-      public Handler newHandler(final GrpcHttp2ConnectionHandler handler) {
-        class PlaintextHandler extends ChannelHandlerAdapter implements Handler {
+      public ChannelHandler newHandler(final GrpcHttp2ConnectionHandler handler) {
+        class PlaintextHandler extends ChannelHandlerAdapter {
           @Override
           public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
             // Set sttributes before replace to be sure we pass it before accepting any requests.
@@ -98,11 +96,6 @@
             // Just replace this handler with the gRPC handler.
             ctx.pipeline().replace(this, null, handler);
           }
-
-          @Override
-          public AsciiString scheme() {
-            return Utils.HTTP;
-          }
         }
 
         return new PlaintextHandler();
@@ -110,6 +103,11 @@
 
       @Override
       public void close() {}
+
+      @Override
+      public AsciiString scheme() {
+        return Utils.HTTP;
+      }
     };
   }
 
@@ -120,18 +118,23 @@
     Preconditions.checkNotNull(sslContext, "sslContext");
     return new ProtocolNegotiator() {
       @Override
-      public Handler newHandler(GrpcHttp2ConnectionHandler handler) {
+      public ChannelHandler newHandler(GrpcHttp2ConnectionHandler handler) {
         return new ServerTlsHandler(sslContext, handler);
       }
 
       @Override
       public void close() {}
+
+
+      @Override
+      public AsciiString scheme() {
+        return Utils.HTTPS;
+      }
     };
   }
 
   @VisibleForTesting
-  static final class ServerTlsHandler extends ChannelInboundHandlerAdapter
-      implements ProtocolNegotiator.Handler {
+  static final class ServerTlsHandler extends ChannelInboundHandlerAdapter {
     private final GrpcHttp2ConnectionHandler grpcHandler;
     private final SslContext sslContext;
 
@@ -191,11 +194,6 @@
       logSslEngineDetails(Level.FINE, ctx, "TLS negotiation failed for new client.", exception);
       ctx.close();
     }
-
-    @Override
-    public AsciiString scheme() {
-      return Utils.HTTPS;
-    }
   }
 
   /**
@@ -204,11 +202,12 @@
   public static ProtocolNegotiator httpProxy(final SocketAddress proxyAddress,
       final @Nullable String proxyUsername, final @Nullable String proxyPassword,
       final ProtocolNegotiator negotiator) {
+    final AsciiString scheme = negotiator.scheme();
     Preconditions.checkNotNull(proxyAddress, "proxyAddress");
     Preconditions.checkNotNull(negotiator, "negotiator");
     class ProxyNegotiator implements ProtocolNegotiator {
       @Override
-      public Handler newHandler(GrpcHttp2ConnectionHandler http2Handler) {
+      public ChannelHandler newHandler(GrpcHttp2ConnectionHandler http2Handler) {
         HttpProxyHandler proxyHandler;
         if (proxyUsername == null || proxyPassword == null) {
           proxyHandler = new HttpProxyHandler(proxyAddress);
@@ -219,6 +218,11 @@
             proxyHandler, negotiator.newHandler(http2Handler));
       }
 
+      @Override
+      public AsciiString scheme() {
+        return scheme;
+      }
+
       // This method is not normally called, because we use httpProxy on a per-connection basis in
       // NettyChannelBuilder. Instead, we expect `negotiator' to be closed by NettyTransportFactory.
       @Override
@@ -233,22 +237,14 @@
   /**
    * Buffers all writes until the HTTP CONNECT tunnel is established.
    */
-  static final class BufferUntilProxyTunnelledHandler extends AbstractBufferingHandler
-      implements ProtocolNegotiator.Handler {
-    private final ProtocolNegotiator.Handler originalHandler;
+  static final class BufferUntilProxyTunnelledHandler extends AbstractBufferingHandler {
+    private final ChannelHandler originalHandler;
 
-    public BufferUntilProxyTunnelledHandler(
-        ProxyHandler proxyHandler, ProtocolNegotiator.Handler handler) {
+    public BufferUntilProxyTunnelledHandler(ProxyHandler proxyHandler, ChannelHandler handler) {
       super(proxyHandler, handler);
       this.originalHandler = handler;
     }
 
-
-    @Override
-    public AsciiString scheme() {
-      return originalHandler.scheme();
-    }
-
     @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
       if (evt instanceof ProxyConnectionEvent) {
@@ -313,7 +309,7 @@
     }
 
     @Override
-    public Handler newHandler(GrpcHttp2ConnectionHandler handler) {
+    public ChannelHandler newHandler(GrpcHttp2ConnectionHandler handler) {
       final HostPort hostPort = parseAuthority(handler.getAuthority());
 
       ChannelHandler sslBootstrap = new ChannelHandlerAdapter() {
@@ -330,6 +326,11 @@
     }
 
     @Override
+    public AsciiString scheme() {
+      return Utils.HTTPS;
+    }
+
+    @Override
     public void close() {}
   }
 
@@ -355,7 +356,7 @@
   static final class PlaintextUpgradeNegotiator implements ProtocolNegotiator {
 
     @Override
-    public Handler newHandler(GrpcHttp2ConnectionHandler handler) {
+    public ChannelHandler newHandler(GrpcHttp2ConnectionHandler handler) {
       // Register the plaintext upgrader
       Http2ClientUpgradeCodec upgradeCodec = new Http2ClientUpgradeCodec(handler);
       HttpClientCodec httpClientCodec = new HttpClientCodec();
@@ -366,6 +367,11 @@
     }
 
     @Override
+    public AsciiString scheme() {
+      return Utils.HTTP;
+    }
+
+    @Override
     public void close() {}
   }
 
@@ -632,8 +638,7 @@
   /**
    * Buffers all writes until the TLS Handshake is complete.
    */
-  private static class BufferUntilTlsNegotiatedHandler extends AbstractBufferingHandler
-      implements ProtocolNegotiator.Handler {
+  private static class BufferUntilTlsNegotiatedHandler extends AbstractBufferingHandler {
 
     private final GrpcHttp2ConnectionHandler grpcHandler;
 
@@ -644,11 +649,6 @@
     }
 
     @Override
-    public AsciiString scheme() {
-      return Utils.HTTPS;
-    }
-
-    @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
       if (evt instanceof SslHandshakeCompletionEvent) {
         SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;
@@ -691,8 +691,7 @@
   /**
    * Buffers all writes until the HTTP to HTTP/2 upgrade is complete.
    */
-  private static class BufferingHttp2UpgradeHandler extends AbstractBufferingHandler
-      implements ProtocolNegotiator.Handler {
+  private static class BufferingHttp2UpgradeHandler extends AbstractBufferingHandler {
 
     private final GrpcHttp2ConnectionHandler grpcHandler;
 
@@ -706,11 +705,6 @@
     }
 
     @Override
-    public AsciiString scheme() {
-      return Utils.HTTP;
-    }
-
-    @Override
     @SuppressWarnings("FutureReturnValueIgnored")
     public void channelActive(ChannelHandlerContext ctx) throws Exception {
       // Trigger the HTTP/1.1 plaintext upgrade protocol by issuing an HTTP request
@@ -798,40 +792,18 @@
   static final class PlaintextProtocolNegotiator implements ProtocolNegotiator {
 
     @Override
-    public Handler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
+    public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) {
       ChannelHandler grpcNegotiationHandler = new GrpcNegotiationHandler(grpcHandler);
       ChannelHandler activeHandler = new WaitUntilActiveHandler(grpcNegotiationHandler);
-      PlaintextProtocolNegotiator.Handler initHandler = new InitHandler(Utils.HTTP, activeHandler);
-      return initHandler;
+      return activeHandler;
     }
 
     @Override
     public void close() {}
-  }
-
-  /**
-   * A {@link ProtocolNegotiator.Handler} that installs the next handler in the pipeline.  This
-   * is likely the first handler returned by a {@link ProtocolNegotiator}.
-   */
-  static final class InitHandler extends ChannelInitializer<Channel>
-      implements ProtocolNegotiator.Handler {
-
-    private final AsciiString scheme;
-    private final ChannelHandler next;
-
-    public InitHandler(AsciiString scheme, ChannelHandler next) {
-      this.scheme = checkNotNull(scheme, "scheme");
-      this.next = checkNotNull(next, "next");
-    }
-
-    @Override
-    protected void initChannel(Channel ch) {
-      ch.pipeline().addFirst(/*name=*/ null, next);
-    }
 
     @Override
     public AsciiString scheme() {
-      return scheme;
+      return Utils.HTTP;
     }
   }
 
diff --git a/netty/src/test/java/io/grpc/netty/NettyClientTransportTest.java b/netty/src/test/java/io/grpc/netty/NettyClientTransportTest.java
index 27d0b59..b4da4cc 100644
--- a/netty/src/test/java/io/grpc/netty/NettyClientTransportTest.java
+++ b/netty/src/test/java/io/grpc/netty/NettyClientTransportTest.java
@@ -65,6 +65,7 @@
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelConfig;
 import io.netty.channel.ChannelFactory;
+import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.ReflectiveChannelFactory;
 import io.netty.channel.local.LocalChannel;
@@ -851,16 +852,10 @@
     }
   }
 
-  private static class NoopHandler extends ProtocolNegotiators.AbstractBufferingHandler
-      implements ProtocolNegotiator.Handler {
+  private static class NoopHandler extends ProtocolNegotiators.AbstractBufferingHandler {
     public NoopHandler(GrpcHttp2ConnectionHandler grpcHandler) {
       super(grpcHandler);
     }
-
-    @Override
-    public AsciiString scheme() {
-      return Utils.HTTP;
-    }
   }
 
   private static class NoopProtocolNegotiator implements ProtocolNegotiator {
@@ -868,12 +863,17 @@
     NoopHandler handler;
 
     @Override
-    public Handler newHandler(final GrpcHttp2ConnectionHandler grpcHandler) {
+    public ChannelHandler newHandler(final GrpcHttp2ConnectionHandler grpcHandler) {
       this.grpcHandler = grpcHandler;
       return handler = new NoopHandler(grpcHandler);
     }
 
     @Override
+    public AsciiString scheme() {
+      return Utils.HTTP;
+    }
+
+    @Override
     public void close() {}
   }