this method is too big. please divided it into a reasonable submethods