Major rewrite, not tested