refactor a bit, add some document comments