all fixed up (still needs some testing)