working single-threaded version