add self test and modify code according to Paul's review