update and merge with xjwangliang's fork