Split the application flow into three steps: 1) routing, 2) dispatching, 3) responding. In the first step, the incoming request is converted to a route. In the second step, the route is converted to a page. And in the third step, the page will be executed so we get a response.
The router, dispatcher and responder returned an array of objects, which was not very 'clean'. These arrays of objects are now enclosed in their own request objects 'DispatchedRequest' and 'RoutedRequest'. In a certain way, these are 'states' for the request object.
Let the responder create a Response object. This way the creation of a response is localised to one place. The response is passed to the page and must be returned after it has been filled with content.
Moved the example pages to a different module, so that they don't pollute the Oframe core.
If no routes.xml file exists inside a module, don't try to load it. The loading will fail silently and assume that the user didn't want to load any routes for that module.
Renamed the 'Routing/Routes' directory to 'Routing/RouteCollectionFactories' to better represent the contents.
Let a route collection implement the ArrayAccess, Countable and Iterator interfaces. A route collection can then be accessed much easier. A disadvantage is we can't use array_merge, but have to create our own 'merge' method.
Trivial: changed a documentation reference to the Route object.
Moved all dispatching related classes into the 'Dispatching' directory.
Moved all response related classes into the 'Responding' directory.
Renamed the 'Modules' directory to 'Modularisation' to better reflect its contents.