Reimplementation to fix #19, handles #30 also