### Question:
ExceptionUtils { public static <T extends Throwable> T findThrowableInCause(Class<T> wantedThrowableType, Throwable throwable) { Set<Throwable> visitedObjects = Sets.newIdentityHashSet(); Throwable currentThrowable = throwable; while (currentThrowable != null && !visitedObjects.contains(currentThrowable)) { if (wantedThrowableType.isInstance(currentThrowable)) { return wantedThrowableType.cast(currentThrowable); } visitedObjects.add(currentThrowable); currentThrowable = currentThrowable.getCause(); } return null; } private  ExceptionUtils(); static T findThrowableInCause(Class<T> wantedThrowableType, Throwable throwable);  }### Answer:
@Test public void shouldFindWantedThrowable() { ConcurrentModificationException initialCme = new ConcurrentModificationException(); Throwable th = new Throwable(initialCme); ConcurrentModificationException cme = new ConcurrentModificationException(th); IllegalStateException ise = new IllegalStateException(cme); UnsupportedOperationException uoe = new UnsupportedOperationException(ise); ReflectiveOperationException roe = new ReflectiveOperationException(uoe); IllegalStateException resultIse = ExceptionUtils.findThrowableInCause(IllegalStateException.class, roe); ConcurrentModificationException resultCme = ExceptionUtils.findThrowableInCause(ConcurrentModificationException.class, cme); StackOverflowError resultSoe = ExceptionUtils.findThrowableInCause(StackOverflowError.class, cme); assertThat(resultIse, sameInstance(ise)); assertThat(resultCme, sameInstance(cme)); assertThat(resultSoe, nullValue()); }
@Test public void shouldHandleCircularCausesGracefully() { IllegalStateException ise = new IllegalStateException(); UnsupportedOperationException uoe = new UnsupportedOperationException(ise); ReflectiveOperationException roe = new ReflectiveOperationException(uoe); ReflectionTestUtils.setField(Throwable.class, ise, "cause", roe); NullPointerException resultNpe = ExceptionUtils.findThrowableInCause(NullPointerException.class, uoe); UnsupportedOperationException resultUoe = ExceptionUtils.findThrowableInCause(UnsupportedOperationException.class, uoe); assertThat(resultNpe, nullValue()); assertThat(resultUoe, sameInstance(uoe)); }