refactor and improve, #20