picked some changes from awakecoding's branch