finish most of function