major changes, makes the code a bit convoluted but performs better