The first, quick-and-dirty version; needs refactoring