update with more elegant solution and add some comment