This method is a bit complex, might be worth considering for a refactor later