refactor. not totally done yet