mostly rewritten