title: Typical ref counting for a handler pipeline
body: <p>Trying to upgrade to Netty 4.1.17.Final, I'm facing a ref counting issue for the following pipeline.</p>
  
  <ul>
  <li>The first handler is framing the raw input from <code>ByteBuf</code>: waiting there are at least the minimal amount of <code>readableBytes</code> to consume a frame, putting all the frames that can be read from this raw input in the <code>output</code> (in/out <code>List</code> parameter). The frames are derived buffers, using <code>readSlice</code>.</li>
  <li>The second handler is parsing each frame as an application specific class (not ref counted).</li>
  </ul>
  
  <p>As far as I understand, only the second handler should call <code>release()</code>.</p>
  
  <p>Unfortunately, it raises <code>IllegalReferenceCountException: refCnt: 0</code> for some cases (when the buffer is recycled) in the first, when trying to <code>readIntLE</code>.</p>
  
  <p>It's unclear to me whether in such handler pipeline/chain, the first one should <code>retain</code> the buffer, or not use derived buffer, ...</p>
  
  <hr>
  
  <p>Edit #1: Contrary to what I understand from the documentation, <code>readRetainedSlice</code> doesn't really "behaves similarly to readSlice(...).retain()" in such case, as the buffer returned by <code>readRetainedSlice</code> has a <code>refCnt</code> different from the parent one.</p>
  
  <hr>
  
  <p>Edit #2: Filtering the leak detection details with <code>leakDetection.acquireAndReleaseOnly=false</code>, it seems the issue is on the outbound side.</p>
  
  <pre><code>23:20:55.586 ERROR [s.n.u.ResourceLeakDetector] :: LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
  Recent access records: 
  #1:
      io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:88)
      io.netty.util.ReferenceCountUtil.safeRelease(ReferenceCountUtil.java:113)
      io.netty.channel.ChannelOutboundBuffer.remove(ChannelOutboundBuffer.java:256)
      io.netty.channel.embedded.EmbeddedChannel.doWrite(EmbeddedChannel.java:724)
      io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:934)
      io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:901)
      io.netty.channel.embedded.EmbeddedChannel$EmbeddedUnsafe$1.flush(EmbeddedChannel.java:820)
      io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1321)
          ...
      io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4$$anonfun$apply$6.apply(ChannelFactorySpec.scala:92)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4$$anonfun$apply$6.apply(ChannelFactorySpec.scala:89)
      NettyEmbedder$.withChannel(NettyEmbedder.scala:95)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4.apply(ChannelFactorySpec.scala:89)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4.apply(ChannelFactorySpec.scala:50)
          ...
  #2:
      io.netty.buffer.AdvancedLeakAwareByteBuf.retain(AdvancedLeakAwareByteBuf.java:36)
      io.netty.util.ReferenceCountUtil.retain(ReferenceCountUtil.java:40)
      io.netty.channel.embedded.EmbeddedChannel.doWrite(EmbeddedChannel.java:722)
      io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:934)
      io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:901)
      io.netty.channel.embedded.EmbeddedChannel$EmbeddedUnsafe$1.flush(EmbeddedChannel.java:820)
      io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1321)
          ...
      io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1041)
      io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4$$anonfun$apply$6.apply(ChannelFactorySpec.scala:92)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4$$anonfun$apply$6.apply(ChannelFactorySpec.scala:89)
      NettyEmbedder$.withChannel(NettyEmbedder.scala:95)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4.apply(ChannelFactorySpec.scala:89)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4.apply(ChannelFactorySpec.scala:50)
  #3:
      Hint: 'DefaultChannelPipeline$HeadContext#0' will handle the message from this point.
      io.netty.channel.DefaultChannelPipeline.touch(DefaultChannelPipeline.java:116)
      io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:810)
      io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:723)
      io.netty.channel.ChannelOutboundHandlerAdapter.write(ChannelOutboundHandlerAdapter.java:104)
      NettyEmbedder$$anon$1.write(NettyEmbedder.scala:88)
          ...
      io.netty.handler.timeout.IdleStateHandler.write(IdleStateHandler.java:304)
      reactivemongo.core.protocol.MongoHandler.write(MongoHandler.scala:91)
          ...
  Created at:
      Hint: 'NettyEmbedder$$anon$1#0' will handle the message from this point.
      io.netty.channel.DefaultChannelPipeline.touch(DefaultChannelPipeline.java:116)
      io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:810)
      io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:723)
      io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:113)
      io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
      io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730)
      io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:816)
      io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:723)
      io.netty.handler.timeout.IdleStateHandler.write(IdleStateHandler.java:304)
      reactivemongo.core.protocol.MongoHandler.write(MongoHandler.scala:91)
          ...
      io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4$$anonfun$apply$6.apply(ChannelFactorySpec.scala:92)
      ChannelFactorySpec$$anonfun$3$$anonfun$apply$4$$anonfun$apply$6.apply(ChannelFactorySpec.scala:89)
      NettyEmbedder$.withChannel(NettyEmbedder.scala:95)
          ...
  </code></pre>