This part of an upgrade project can from experience take between 10% of initial development effort all the way up to and including 100%+ of the initial dev effort depending upon what and how modifications were done.
The 100%+ example list of do not do's are :
Changes to std BaseEnums sequence and related code, f.ex. I had a customer / consultant precede me on a case where they decided it would be a good idea to change the salesorder type enumerated type and add some new types in the middle of the list :-(. Upgrading this was an unnecessarily big job if they had just created them at the end with a big gap in the enum it would have been much less of an issue anyhow.
Duplication of classes and calling these duplicated classes instead of the standard class, the problem here is that the layers mechanism of resolving / helping upgrade is negated and one is forced to export the class and do a manual external comparison.
Writing code in unusual places, that is in screen buttons, on the datasource of screens, in the datasource fields on screens.
Changing the standard data structure relationships in data as well as classes.
Partial list ends here TBC