backport a function from trunk