complete rewrite using classes