I implemented a hack to put the equivalent functionality in. What I ended up doing was subclassing the sink I needed decorated and overriding the getChannel() method. I had it return a channel that largely delegates to the original channel, but intercepts calls to take events. In order to maintain the correctness, I couldn't modify events in place in case the transaction got copied, so I ended up creating a new event on every call. This could have performance implications. The other idea I had was to add a header along the lines of "decorators.complete" that could have a coma delimited list of decorators that have processed the event. That way, I could avoid re-processing events that were processed and then returned to the channel.