package org.ardulink.util;

import static org.ardulink.util.Preconditions.checkNotNull;

public final class Throwables {

	private Throwables() {
		super();
	}

	public static Throwable getRootCause(Throwable throwable) {
		Throwable cause;
		while ((cause = throwable.getCause()) != null) {
			throwable = cause;
		}
		return throwable;
	}

	public static RuntimeException propagate(Throwable throwable) {
		propagateIfPossible(checkNotNull(throwable,
				"throwable must not be null"));
		throw new RuntimeException(throwable);
	}

	public static void propagateIfPossible(Throwable throwable) {
		propagateIfInstanceOf(throwable, Error.class);
		propagateIfInstanceOf(throwable, RuntimeException.class);
	}

	public static <T extends Throwable> void propagateIfInstanceOf(
			Throwable throwable, Class<T> type) throws T {
		if (type.isInstance(throwable)) {
			throw type.cast(throwable);
		}
	}

}

@@ -82,16 +82,44 @@
 tNull;%0A%0A
+import java.util.Iterator;%0A%0A
 public f
@@ -249,120 +249,511 @@
 %7B%0A%09%09
-Throwable cause;%0A%09%09while ((cause = throwable.getCause()) != null
+return Iterators.getLast(getCauses(throwable)).or(throwable);%0A%09%7D%0A%0A%09public static Iterator%3CThrowable%3E getCauses(final Throwable throwable) %7B%0A%09%09return new Iterator%3CThrowable%3E() %7B%0A%0A%09%09%09private Throwable actual = throwable;%0A%0A%09%09%09@Override%0A%09%09%09public void remove(
 ) %7B%0A%09%09%09
+%09
 throw
-able = c
+ new UnsupportedOperationException();%0A%09%09%09%7D%0A%0A%09%09%09@Override%0A%09%09%09public Throwable next() %7B%0A%09%09%09%09return this.actual = this.actual.getC
 ause
+()
 ;%0A%09%09
-%7D%0A%09%09return throwable
+%09%7D%0A%0A%09%09%09@Override%0A%09%09%09public boolean hasNext() %7B%0A%09%09%09%09return this.actual.getCause() != null;%0A%09%09%09%7D%0A%09%09%7D
 ;%0A%09%7D

use Iterators