The third version, finished all functions, need to be tested