This is too long and confusing, can we extract this to another method