lots of refactorings a la Wei's suggestion. probably breaks something will fix it later