This function is almost totally the same with noted exceptions.