I think the problem you are mentioning on your lines 59-56 (negative timespan) are solved by the limiter at your lines 74-78. Right?
Cheers!
Not really.
Since history shows there are blocks where nActualTimespan becomes negative, DIGI will resolve to nActualTimespan = (retargetTimespan - (retargetTimespan/4)) and the diff jumps up max. This happens because of the wrong time of 1 block, not because the hashrate jumped up; hashrate might even go down at that time.
I don't see a problem today to reject those blocks instead of accepting them into the chain. A submitting miner should be able to keep his clock within a few seconds of synced time nowadays, which should always lead to a positive nActualTimespan. If a miner mines a block faster than his clock is off, than bad luck for him (his own fault).
Your cleanup was even far more radical than mine

I only think we chould leave the testnet code in there for now (only my opinion).
Oh, you could even replace retargetTimespan with nTargetSpacing and save another line and variable

Than it's cleaned to the minimum beside the basic comments.
Isn't the difficulty changing between a min of 66.7% (1/0.75) and a max of 133% (1/1.5) or did I read something wrong there?