package net.kencochrane.raven.event.interfaces;

import java.util.Deque;

/**
 * The Exception interface for Sentry allowing to add an Exception details to an event.
 */
public class ExceptionInterface implements SentryInterface {
    /**
     * Name of the exception interface in Sentry.
     */
    public static final String EXCEPTION_INTERFACE = "sentry.interfaces.Exception";
    private final ImmutableThrowable throwable;

    /**
     * Creates a an Exception element for an {@link net.kencochrane.raven.event.Event}.
     *
     * @param throwable Exception from the JVM to send to Sentry.
     */
    public ExceptionInterface(Throwable throwable) {
        this.throwable = new ImmutableThrowable(throwable);
    }

    @Override
    public String getInterfaceName() {
        return EXCEPTION_INTERFACE;
    }

    public ImmutableThrowable getThrowable() {
        return throwable;
    }

    public Deque<ExceptionWithStackTrace> getExceptions()  {
        return null; // TODO replace this
    }
}

@@ -53,23 +53,158 @@
 ort 
-java.util.Deque
+org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport java.util.ArrayDeque;%0Aimport java.util.Deque;%0Aimport java.util.HashSet;%0Aimport java.util.Set
 ;%0A%0A/
@@ -509,16 +509,17 @@
 ption%22;%0A
+%0A
     priv
@@ -526,213 +526,303 @@
 ate 
-final ImmutableThrowable throwable;%0A%0A    /**%0A     * Creates a an Exception element for an %7B@link net.kencochrane.raven.event.Event%7D.%0A     *%0A     * @param throwable Exception from the JVM to send to Sentry.
+static final Logger logger = LoggerFactory.getLogger(ExceptionInterface.class);%0A%0A    private final Deque%3CExceptionWithStackTrace%3E exceptions;%0A%0A    /**%0A     * Creates a new instance from the given %7B@code throwable%7D.%0A     *%0A     * @param throwable the %7B@link Throwable%7D to build this instance from
 %0A   
@@ -856,16 +856,22 @@
 terface(
+final 
 Throwabl
@@ -901,192 +901,807 @@
 this
-.throwable = new ImmutableThrowable(throwable);%0A    %7D%0A%0A    @Override%0A    public String getInterfaceName() %7B%0A        return EXCEPTION_INTERFACE;%0A    %7D%0A%0A    public ImmutableThrowable g
+(extractExceptionQueue(throwable));%0A    %7D%0A%0A    /**%0A     * Creates a new instance from the given %7B@code exceptions%7D.%0A     *%0A     * @param exceptions a %7B@link Deque%7D of %7B@link ExceptionWithStackTrace%7D to build this instance from%0A     */%0A    public ExceptionInterface(final Deque%3CExceptionWithStackTrace%3E exceptions) %7B%0A        this.exceptions = exceptions;%0A    %7D%0A%0A    @Override%0A    public String getInterfaceName() %7B%0A        return EXCEPTION_INTERFACE;%0A    %7D%0A%0A    public Deque%3CExceptionWithStackTrace%3E getExceptions()  %7B%0A        return exceptions;%0A    %7D%0A%0A    private static Deque%3CExceptionWithStackTrace%3E extractExceptionQueue(Throwable throwable) %7B%0A        Deque%3CExceptionWithStackTrace%3E exceptions = new ArrayDeque%3CExceptionWithStackTrace%3E();%0A        Set%3CThrowable%3E circularityDetector = new HashS
 et
+%3C
 Thro
@@ -1709,148 +1709,1529 @@
 able
+%3E
 ()
- %7B%0A        return throwable;%0A    %7D%0A%0A    public Deque%3CExceptionWithStackTrace%3E getExceptions()  %7B%0A        return null; // TODO replace this
+;%0A        StackTraceElement%5B%5D enclosingStackTrace = new StackTraceElement%5B0%5D;%0A%0A        //Stack the exceptions to send them in the reverse order%0A        while (throwable != null) %7B%0A            if (!circularityDetector.add(throwable)) %7B%0A                logger.warn(%22Exiting a circular exception!%22);%0A                break;%0A            %7D%0A%0A            StackTraceInterface stackTrace = new StackTraceInterface(throwable.getStackTrace(), enclosingStackTrace);%0A            exceptions.push(createExceptionWithStackTraceFrom(throwable, stackTrace));%0A            enclosingStackTrace = throwable.getStackTrace();%0A            throwable = throwable.getCause();%0A        %7D%0A%0A        return exceptions;%0A    %7D%0A%0A    private static ExceptionWithStackTrace createExceptionWithStackTraceFrom(final Throwable throwable,%0A                                                                      final StackTraceInterface stackTrace) %7B%0A        final String exceptionMessage = throwable.getMessage();%0A        final String exceptionClassName = throwable.getClass().getSimpleName();%0A        final String exceptionPackageName = extractPackageName(throwable);%0A        return new ExceptionWithStackTrace(exceptionMessage, exceptionClassName, exceptionPackageName, stackTrace);%0A    %7D%0A%0A    private static String extractPackageName(final Throwable throwable) %7B%0A%0A        final Package exceptionPackage = throwable.getClass().getPackage();%0A%0A        if (exceptionPackage != null) %7B%0A            return exceptionPackage.getName();%0A        %7D%0A%0A        return null;
 %0A   

Remove the ImmutableThrowable usage from ExceptionInterface