huge refactoring - hope still works