Clean reimplementation to fix issue #2509

Please do not yet merge this one, it is to find the best solution
Why not `Throwable`? What if deserialization throws OOME?