Awful long code, but it's functional