There are several comments made throughout this thread that points to a misuse of AFIs.
An example, and no offence, "I would use the AFI to leave the original code intact, but not operational". This is OK when the alternative code is built on the same rung as the original (as a branch structure), but if used on whole rungs, and replacement rungs added, then problems can occur.
It must be stressed that a rung with an AFI on it is still operational, the AFI just makes whatever follows it False. The remainder of the rung is processed as normal, except that "Rung Logic Continuity" is now false. In truth, an AFI does not "disable code" at all.
So, if AFIs are employed to "disable old code", and new code is inserted to drive the same outputs, then you are creating "Duplicate Destructive Bit References".
Most people are aware of the pitfalls of duplicating outputs, but for the uninitiated, the most important are......
1. The "Last One Wins" rule applies.** The latest rung sets the state of the bit that the rest of the code "sees".
2. Code becomes "Position Dependant". You have to be careful when inserting rungs, that you are not putting new code in that looks at the transient state of the output bit on the rung, i.e. after the AFI'd rung, and before the rung that makes it true.
** Last One Wins rule applies to internal bits only, but when these bits are real-world outputs (as in the case of Logix5000 systems), the Last One Wins rule goes out the window, because I/O is exchanged with the I/O modules asynchronously to the program scan. You could be sending your AFId output to the module briefly, and depending on the I/O exchange rate (RPI), this could cause problems in the field devices. There is no issue with Logix5 or Logix500 real-world outputs, because these are internal data-table bits, that are exchanged with the I/O modules between program scans.
Also be aware that AFI'ing a rung with a Timer on it, will reset the timer!. The same applies to any instruction that is triggered by a "False-to-True" transition, e.g. FAL, FSC, CTU, CTD, MSG, etc.
There are better, safer ways to "disable" old code, you have to devise a way to stop the processor scanning it, so that it doesn't set any inappropriate states, or take any inappropriate actions.
You could use a JMP/LBL combination to completely skip "old" code, but this doesn't remove pitfall no.2 above. You would still have an area in your logic that is a "no man's land".
My preference is to relocate the "old" code into a dead subroutine file (one that is not called), and put my "new" code into a subroutine that is called. You can even condition the subroutine calls on the state of a bit, so that you can switch between "old" and "new" by toggling the bit.
Whichever way it is done, documentation is paramount, so that everyone is made aware of the situation.