This method should probably be broken into many methods.