They also have tricky semantics (e.g. returning null).
No longer since January's refactoring, leaves() returns always something != null. And getSeqSubReaders is only available on CompositeReaders, which always have subReaders. See the other issue
LUCENE-3866 where I did some more refactoring to make all this easier.
In general I agree with that, as leaves() and children()/subs() would then just be a shortcut to getTopReaderContext()'s methods (leaves(), children() - both are Iterable, no need to change anything) (I would rename that one to as[Top]Context()).
Returning plain subReaders without Contexts is not really useful, as all of Lucene's Query logic uses AtomicReaderContext, so leaves() on IndexReader returning the same as getTopReaderContext().leaves() is the way to go. This method can be added as final "easy-use method". I hope you look at my other patch @
LUCENE-3866, because it shows how simple the code is now without ReaderUtil.Gather.
Additionally, as noted in
LUCENE-3866, getSequentialSubReaders() in CompositeReader should be made protected, user code does not need to use it. It's solely there for building the reader hierarchy, later available using IRC.leaves() and IRC.children(). Currently this method is only used by tests anymore (which can be rewritten). In CompositeReader, getSequentialSubReaders() should just be the protected abstract way for the API on top to get the inner structure, but not for the outside.