rewritten and cleaned