Rewritten some parts to make it more readable, and compact