copy soonho code, add some type