This function should be split into several smaller ones.