Rewrote some hard-to-understand parts
Updated version