package com.rollbar.payload.data.body;

import com.rollbar.payload.utilities.ArgumentNullException;
import com.rollbar.payload.utilities.InvalidLengthException;
import com.rollbar.payload.utilities.Validate;

import java.util.ArrayList;

public class TraceChain implements BodyContents {
    public static TraceChain fromThrowable(Throwable error) throws ArgumentNullException {
        Validate.isNotNull(error, "error");
        ArrayList<Trace> chain = new ArrayList<Trace>();
        do {
            chain.add(Trace.fromThrowable(error));
            error = error.getCause();
        } while(error != null);
        Trace[] traces = chain.toArray(new Trace[chain.size()]);
        try {
            return new TraceChain(traces);
        } catch (InvalidLengthException e) {
            throw new IllegalStateException("non null errors should never result in zero length chains");
        }
    }

    private final Trace[] traces;

    public TraceChain(Trace[] traces) throws ArgumentNullException, InvalidLengthException {
        Validate.isNotNull(traces, "traces");
        Validate.minLength(traces, 1, "traces");
        this.traces = traces.clone();
    }

    public Trace[] traces() {
        return this.traces.clone();
    }

    public TraceChain traces(Trace[] traces) throws ArgumentNullException, InvalidLengthException {
        return new TraceChain(traces);
    }
}

@@ -235,57 +235,415 @@
 t;%0A%0A
-public class TraceChain implements BodyContents %7B
+/**%0A * Represents a chain of errors (typically from Exceptions with %7B@link Exception#getCause()%7D returning some value)%0A */%0Apublic class TraceChain implements BodyContents %7B%0A    /**%0A     * Generate a TraceChain from a throwable with multiple causes%0A     * @param error the error to record%0A     * @return the trace chain representing the Throwable%0A     * @throws ArgumentNullException if error is null%0A     */
 %0A   
@@ -1034,26 +1034,8 @@
 %5D);%0A
-        try %7B%0A    
     
@@ -1077,206 +1077,269 @@
     
+%7D%0A%0A
     
-%7D catch (InvalidLengthException e) %7B%0A            throw new IllegalStateException(%22non null errors should never result in zero length
+private final Trace%5B%5D traces;%0A%0A    /**%0A     * Constructor%0A     * @param traces the traces making up this trace
  chain
-s%22);
 %0A     
-   %7D%0A    %7D%0A%0A    private final Trace%5B%5D traces;%0A
+* @throws ArgumentNullException if traces are null%0A     * @throws InvalidLengthException if there are no traces in the array%0A     */
 %0A   
@@ -1560,32 +1560,89 @@
 clone();%0A    %7D%0A%0A
+    /**%0A     * @return a copy of the trace array%0A     */%0A
     public Trace
@@ -1694,24 +1694,320 @@
 e();%0A    %7D%0A%0A
+    /**%0A     * Set the trace array on a copy of this trace chain%0A     * @param traces the traces to set%0A     * @return a new TraceChain with the traces given%0A     * @throws ArgumentNullException if traces are null%0A     * @throws InvalidLengthException if there are no traces in the array%0A     */%0A
     public T

Document Trace Chain