rewrote big parts of the code to prevent big code duplicates