this method could be extracted in a few private methods, it's too long IMO