I think there is a bug in this code. In the method
public Object invoke(Object proxy, Method method,
Object args) throws Throwable
args can be null if the method has no arguments.
I tried to adapt this code to handle this case but got very strange interactions between equals() and hashCode() (got an infinite loop).