Final code from AOP blog 2