Optimized a bit, but the code is a bit messier :s