Working version but may contain some bug