Ported from Google Code and tidied