omg, so many exception in order to finish this problem, not an elegant
solution, but functional