complete rewrite with classes