almost complete rewrite, simpler