heavy refactoring; broken