major rewrite, needs thourough testing