### Question:
ByteToMessageDecoder extends ChannelInboundHandlerAdapter { static void fireChannelRead(ChannelHandlerContext ctx, List<Object> msgs, int numElements) { if (msgs instanceof CodecOutputList) { fireChannelRead(ctx, (CodecOutputList) msgs, numElements); } else { for (int i = 0; i < numElements; i++) { ctx.fireChannelRead(msgs.get(i)); } } } protected  ByteToMessageDecoder(); @Override void channelRead(ChannelHandlerContext ctx, Object msg); void setSingleDecode(boolean singleDecode); boolean isSingleDecode(); void setCumulator(Cumulator cumulator); void setDiscardAfterReads(int discardAfterReads); @Override final void handlerRemoved(ChannelHandlerContext ctx); @Override void channelReadComplete(ChannelHandlerContext ctx); @Override void channelInactive(ChannelHandlerContext ctx); @Override void userEventTriggered(ChannelHandlerContext ctx, Object evt); static final Cumulator MERGE_CUMULATOR; static final Cumulator COMPOSITE_CUMULATOR; }### Answer:
@Test public void testRemoveWhileInCallDecode() { final Object upgradeMessage = new Object(); final ByteToMessageDecoder decoder = new ByteToMessageDecoder() { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { assertEquals('a', in.readByte()); out.add(upgradeMessage); } }; EmbeddedChannel channel = new EmbeddedChannel(decoder, new ChannelInboundHandlerAdapter() { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg == upgradeMessage) { ctx.pipeline().remove(decoder); return; } ctx.fireChannelRead(msg); } }); ByteBuf buf = Unpooled.wrappedBuffer(new byte[] { 'a', 'b', 'c' }); assertTrue(channel.writeInbound(buf.copy())); ByteBuf b = channel.readInbound(); assertEquals(b, buf.skipBytes(1)); assertFalse(channel.finish()); buf.release(); b.release(); }