added multi-threaded