Final version, testing cases need to be rewritten