One of the key features in Tapestry 5 is something which Howard has dubbed adaptive API. The idea is that the framework adapts to your code, rather than the other way around. IoC containers get you halfway there by allowing you to code POJOs with distinct responsibilities which are later wired by the container. However, when your code is part of a larger whole (i.e. you’re using some framework), best practice usually dictates that the relevant boundaries are formed by some well-defined set of interfaces.
Tapestry 5 has taken another route: do whatever you want to do, and the framework will use every trick in the bag to attempt to accommodate you. One obvious example of this principle is the event handler API. Specifically, the return values for these event handlers determine the next page that will be rendered. In most web frameworks, you would most definitely need to return an instance of IPage or ILink or whatever well-defined return type your framework understands. In T5 land, however, you can return almost anything that might make sense: null, a page name, a page instance, a link, even a stream. And now, thanks to Howard’s genius and my copy-and-paste skills, a page class