Lots of update taken from lazycat