implement it right by myself, very good, but not very elegant, need read more elegant code. TODO