Huge refactoring; add specs