I am reopening this issue as there is some API problem which makes openIfChanged not consistently useable with FilterIndexReader:
If you have a FilterIndexReader that did in the past not implement reopen(...), the base class IndexReader throwed UOE. This was fine, as a FilterIndexReader cannot support reopen unless specifically supported. A FilterIndexReader of course must reopen the delegate reader and then wrap it again to Filter. This was done by overriding reopen() methods, checking if the delegate returned another reader and if yes, wrapping it.
I tried to transform code that implement this pattern to Lucene 3.5RC1 but failed to do it in the clean way: Reopen was replaced by a static IR.openIfChanged(IR oldReader) that delegates to the specific IndexReaders implementation of doOpenIfChanged (which is protected).
To implement the above pattern, doOpenIfChanged must be overridden in FilterIndexReader (again the default must thorw UOE, otherwise reopening a filtered reader returns a non-filtered one). This method must call delegate's doOpenIfChanged and if it returns != null, wrap by our FilterIndexReader implementation. The problem: This cannot be implemented if the custom Filter is in a 3rd party package, as it cannot call the protected doOpenIfChanged. The workaround is to use IndexReader.openIfChanged(delegate), but this look borken and violates the pattern.
The good thing with the workaround is that the VirtualMethod sophisticated backwards works correctly. We must at least document this behaviour in FilterIndexReader or fix the API.