complete rewrite

rewritten from scratch