many improvements, check TODO for more details