First working draft. Needs refactoring.