This method is too long and too complex. Try to break it up.