more refactoring. needs testing before general use