@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();
}