complete rewrite, new interface