refactored version (still missing some things)