rewritten to be more object oriented