rewritten OOP and speedup