### Question:
ExecutionHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler, ExternalResourceReleasable { public void handleDownstream( ChannelHandlerContext ctx, ChannelEvent e) throws Exception { if (!handleReadSuspend(ctx, e)) { if (handleDownstream) { executor.execute(new ChannelDownstreamEventRunnable(ctx, e, executor)); } else { ctx.sendDownstream(e); } } } ExecutionHandler(Executor executor); @Deprecated  ExecutionHandler(Executor executor, boolean handleDownstream);  ExecutionHandler(Executor executor, boolean handleDownstream, boolean handleUpstream); Executor getExecutor(); void releaseExternalResources(); void handleUpstream(
            ChannelHandlerContext context, ChannelEvent e); void handleDownstream(
            ChannelHandlerContext ctx, ChannelEvent e);  }### Answer:
@Test public void testReleaseExternalResourceViaDownstreamEvent() throws Exception { Channel channel = createMock(Channel.class); expect(channel.getCloseFuture()).andReturn(new DefaultChannelFuture(channel, false)); ChannelEvent event = createMock(ChannelEvent.class); expect(event.getChannel()).andReturn(channel).anyTimes(); expect(event.getFuture()).andReturn(new DefaultChannelFuture(channel,false)).anyTimes(); replay(channel, event); final CountDownLatch latch = new CountDownLatch(1); OrderedDownstreamThreadPoolExecutor executor = new OrderedDownstreamThreadPoolExecutor(10); final ExecutionHandler handler = new ExecutionHandler(executor, true, true); handler.handleDownstream(new TestChannelHandlerContext(channel, handler, latch), event); assertTrue(latch.await(5, TimeUnit.SECONDS)); }