Functional version. Quite messy need loads of refactoring.