diff --git a/kaspresso/src/main/java/io/reactivex/exceptions/ExtCompositeException.java b/kaspresso/src/main/java/io/reactivex/exceptions/ExtCompositeException.java
deleted file mode 100644
index 32c80f600..000000000
--- a/kaspresso/src/main/java/io/reactivex/exceptions/ExtCompositeException.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/**
- * Copyright (c) 2016-present, RxJava Contributors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package io.reactivex.exceptions;
-
-import androidx.annotation.NonNull;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.*;
-
-/**
- * Represents an exception that is a composite of one or more other exceptions. A {@code ExtCompositeException}
- * does not modify the structure of any exception it wraps, but at print-time it iterates through the list of
- * Throwables contained in the composite in order to print them all.
- *
- * Its invariant is to contain an immutable, ordered (by insertion order), unique list of non-composite
- * exceptions. You can retrieve individual exceptions in this list with {@link #getExceptions()}.
- *
- * The {@link #printStackTrace()} implementation handles the StackTrace in a customized way instead of using
- * {@code getCause()} so that it can avoid circular references.
- *
- * If you invoke {@link #getCause()}, it will lazily create the causal chain but will stop if it finds any
- * Throwable in the chain that it has already seen.
- */
-public final class ExtCompositeException extends RuntimeException {
-
- private static final long serialVersionUID = 3026362227162912146L;
-
- private final List exceptions;
- private final String message;
- private Throwable cause;
-
- /**
- * Constructs a ExtCompositeException with the given array of Throwables as the
- * list of suppressed exceptions.
- * @param exceptions the Throwables to have as initially suppressed exceptions
- *
- * @throws IllegalArgumentException if exceptions
is empty.
- */
- public ExtCompositeException(@NonNull Throwable... exceptions) {
- this(exceptions == null ?
- Collections.singletonList(new NullPointerException("exceptions was null")) : Arrays.asList(exceptions));
- }
-
- /**
- * Constructs a ExtCompositeException with the given array of Throwables as the
- * list of suppressed exceptions.
- * @param errors the Throwables to have as initially suppressed exceptions
- *
- * @throws IllegalArgumentException if errors
is empty.
- */
- public ExtCompositeException(@NonNull Iterable extends Throwable> errors) {
- Set deDupedExceptions = new LinkedHashSet();
- List localExceptions = new ArrayList();
- if (errors != null) {
- for (Throwable ex : errors) {
- if (ex instanceof ExtCompositeException) {
- deDupedExceptions.addAll(((ExtCompositeException) ex).getExceptions());
- } else if (ex != null) {
- deDupedExceptions.add(ex);
- } else {
- deDupedExceptions.add(new NullPointerException("Throwable was null!"));
- }
- }
- } else {
- deDupedExceptions.add(new NullPointerException("errors was null"));
- }
- if (deDupedExceptions.isEmpty()) {
- throw new IllegalArgumentException("errors is empty");
- }
- localExceptions.addAll(deDupedExceptions);
- this.exceptions = Collections.unmodifiableList(localExceptions);
- this.message = exceptions.size() + " exceptions occurred. ";
- }
-
- /**
- * Retrieves the list of exceptions that make up the {@code ExtCompositeException}.
- *
- * @return the exceptions that make up the {@code ExtCompositeException}, as a {@link List} of {@link Throwable}s
- */
- @NonNull
- public List getExceptions() {
- return exceptions;
- }
-
- @Override
- @NonNull
- public String getMessage() {
- return message;
- }
-
- @Override
- @NonNull
- public synchronized Throwable getCause() { // NOPMD
- if (cause == null) {
- // we lazily generate this causal chain if this is called
- CompositeExceptionCausalChain localCause = new CompositeExceptionCausalChain();
- Set seenCauses = new HashSet();
-
- Throwable chain = localCause;
- for (Throwable e : exceptions) {
- if (seenCauses.contains(e)) {
- // already seen this outer Throwable so skip
- continue;
- }
- seenCauses.add(e);
-
- List listOfCauses = getListOfCauses(e);
- // check if any of them have been seen before
- for (Throwable child : listOfCauses) {
- if (seenCauses.contains(child)) {
- // already seen this outer Throwable so skip
- e = new RuntimeException("Duplicate found in causal chain so cropping to prevent loop ...");
- continue;
- }
- seenCauses.add(child);
- }
-
- // we now have 'e' as the last in the chain
- try {
- chain.initCause(e);
- } catch (Throwable t) { // NOPMD
- // ignore
- // the JavaDocs say that some Throwables (depending on how they're made) will never
- // let me call initCause without blowing up even if it returns null
- }
- chain = getRootCause(chain);
- }
- cause = localCause;
- }
- return cause;
- }
-
- /**
- * All of the following {@code printStackTrace} functionality is derived from JDK {@link Throwable}
- * {@code printStackTrace}. In particular, the {@code PrintStreamOrWriter} abstraction is copied wholesale.
- *
- * Changes from the official JDK implementation:
- * - no infinite loop detection
- * - smaller critical section holding {@link PrintStream} lock
- * - explicit knowledge about the exceptions {@link List} that this loops through
- *
- */
- @Override
- public void printStackTrace() {
- printStackTrace(System.err);
- }
-
- @Override
- public void printStackTrace(PrintStream s) {
- printStackTrace(new WrappedPrintStream(s));
- }
-
- @Override
- public void printStackTrace(PrintWriter s) {
- printStackTrace(new WrappedPrintWriter(s));
- }
-
- /**
- * Special handling for printing out a {@code ExtCompositeException}.
- * Loops through all inner exceptions and prints them out.
- *
- * @param s
- * stream to print to
- */
- private void printStackTrace(PrintStreamOrWriter s) {
- StringBuilder b = new StringBuilder(128);
- b.append(this).append('\n');
- for (StackTraceElement myStackElement : getStackTrace()) {
- b.append("\tat ").append(myStackElement).append('\n');
- }
- int i = 1;
- for (Throwable ex : exceptions) {
- b.append(" ComposedException ").append(i).append(" :\n");
- appendStackTrace(b, ex, "\t");
- i++;
- }
- s.println(b.toString());
- }
-
- private void appendStackTrace(StringBuilder b, Throwable ex, String prefix) {
- b.append(prefix).append(ex).append('\n');
- for (StackTraceElement stackElement : ex.getStackTrace()) {
- b.append("\t\tat ").append(stackElement).append('\n');
- }
- if (ex.getCause() != null) {
- b.append("\tCaused by: ");
- appendStackTrace(b, ex.getCause(), "");
- }
- }
-
- abstract static class PrintStreamOrWriter {
- /** Prints the specified string as a line on this StreamOrWriter. */
- abstract void println(Object o);
- }
-
- /**
- * Same abstraction and implementation as in JDK to allow PrintStream and PrintWriter to share implementation.
- */
- static final class WrappedPrintStream extends PrintStreamOrWriter {
- private final PrintStream printStream;
-
- WrappedPrintStream(PrintStream printStream) {
- this.printStream = printStream;
- }
-
- @Override
- void println(Object o) {
- printStream.println(o);
- }
- }
-
- static final class WrappedPrintWriter extends PrintStreamOrWriter {
- private final PrintWriter printWriter;
-
- WrappedPrintWriter(PrintWriter printWriter) {
- this.printWriter = printWriter;
- }
-
- @Override
- void println(Object o) {
- printWriter.println(o);
- }
- }
-
- static final class CompositeExceptionCausalChain extends RuntimeException {
- private static final long serialVersionUID = 3875212506787802066L;
- /* package-private */static final String MESSAGE = "Chain of Causes for ExtCompositeException In Order Received =>";
-
- @Override
- public String getMessage() {
- return MESSAGE;
- }
- }
-
- private List getListOfCauses(Throwable ex) {
- List list = new ArrayList();
- Throwable root = ex.getCause();
- if (root == null || root == ex) {
- return list;
- } else {
- while (true) {
- list.add(root);
- Throwable cause = root.getCause();
- if (cause == null || cause == root) {
- return list;
- } else {
- root = cause;
- }
- }
- }
- }
-
- /**
- * Returns the number of suppressed exceptions.
- * @return the number of suppressed exceptions
- */
- public int size() {
- return exceptions.size();
- }
-
- /**
- * Returns the root cause of {@code e}. If {@code e.getCause()} returns {@code null} or {@code e}, just return {@code e} itself.
- *
- * @param e the {@link Throwable} {@code e}.
- * @return The root cause of {@code e}. If {@code e.getCause()} returns {@code null} or {@code e}, just return {@code e} itself.
- */
- /*private */Throwable getRootCause(Throwable e) {
- Throwable root = e.getCause();
- if (root == null || e == root) {
- return e;
- }
- while (true) {
- Throwable cause = root.getCause();
- if (cause == null || cause == root) {
- return root;
- }
- root = cause;
- }
- }
-}
\ No newline at end of file
diff --git a/kaspresso/src/main/java/io/reactivex/exceptions/ExtCompositeException.kt b/kaspresso/src/main/java/io/reactivex/exceptions/ExtCompositeException.kt
new file mode 100644
index 000000000..4c97f0b1a
--- /dev/null
+++ b/kaspresso/src/main/java/io/reactivex/exceptions/ExtCompositeException.kt
@@ -0,0 +1,260 @@
+/**
+ * Copyright (c) 2016-present, RxJava Contributors.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.reactivex.exceptions
+
+import java.io.PrintStream
+import java.io.PrintWriter
+import java.util.Arrays
+import java.util.Collections
+
+/**
+ * Represents an exception that is a composite of one or more other exceptions. A `ExtCompositeException`
+ * does not modify the structure of any exception it wraps, but at print-time it iterates through the list of
+ * Throwables contained in the composite in order to print them all.
+ *
+ * Its invariant is to contain an immutable, ordered (by insertion order), unique list of non-composite
+ * exceptions. You can retrieve individual exceptions in this list with [.getExceptions].
+ *
+ * The [.printStackTrace] implementation handles the StackTrace in a customized way instead of using
+ * `getCause()` so that it can avoid circular references.
+ *
+ * If you invoke [.getCause], it will lazily create the causal chain but will stop if it finds any
+ * Throwable in the chain that it has already seen.
+ */
+class ExtCompositeException(errors: Iterable) : RuntimeException() {
+ /**
+ * Retrieves the list of exceptions that make up the `ExtCompositeException`.
+ *
+ * @return the exceptions that make up the `ExtCompositeException`, as a [List] of [Throwable]s
+ */
+ val exceptions: List
+ override var message: String = ""
+
+ @get:Synchronized
+ override var cause: Throwable? = null
+ get() { // NOPMD
+ if (field == null) {
+ // we lazily generate this causal chain if this is called
+ val localCause = CompositeExceptionCausalChain()
+ val seenCauses: MutableSet = HashSet()
+
+ var chain: Throwable? = localCause
+ for (ex in exceptions) {
+ var e = ex
+ if (seenCauses.contains(e)) {
+ // already seen this outer Throwable so skip
+ continue
+ }
+ seenCauses.add(e)
+
+ val listOfCauses = getListOfCauses(e)
+ // check if any of them have been seen before
+ for (child in listOfCauses) {
+ if (seenCauses.contains(child)) {
+ // already seen this outer Throwable so skip
+ e = RuntimeException("Duplicate found in causal chain so cropping to prevent loop ...")
+ continue
+ }
+ seenCauses.add(child)
+ }
+
+ // we now have 'e' as the last in the chain
+ try {
+ chain?.initCause(e)
+ } catch (t: Throwable) { // NOPMD
+ // ignore
+ // the JavaDocs say that some Throwables (depending on how they're made) will never
+ // let me call initCause without blowing up even if it returns null
+ }
+ chain = getRootCause(chain)
+ }
+ field = localCause
+ }
+ return field
+ }
+ private set
+
+ /**
+ * Constructs a ExtCompositeException with the given array of Throwables as the
+ * list of suppressed exceptions.
+ * @param exceptions the Throwables to have as initially suppressed exceptions
+ *
+ * @throws IllegalArgumentException if `exceptions` is empty.
+ */
+ constructor(vararg exceptions: Throwable) : this(listOf(*exceptions))
+
+ /**
+ * Constructs a ExtCompositeException with the given array of Throwables as the
+ * list of suppressed exceptions.
+ * @param errors the Throwables to have as initially suppressed exceptions
+ *
+ * @throws IllegalArgumentException if `errors` is empty.
+ */
+ init {
+ val deDupedExceptions: MutableSet = LinkedHashSet()
+ val localExceptions: MutableList = ArrayList()
+ for (ex in errors) {
+ if (ex is ExtCompositeException) {
+ deDupedExceptions.addAll(ex.exceptions)
+ } else if (ex != null) {
+ deDupedExceptions.add(ex)
+ } else {
+ deDupedExceptions.add(NullPointerException("Throwable was null!"))
+ }
+ }
+ require(!deDupedExceptions.isEmpty()) { "errors is empty" }
+ localExceptions.addAll(deDupedExceptions)
+ this.exceptions = Collections.unmodifiableList(localExceptions)
+ this.message = exceptions.size.toString() + " exceptions occurred. "
+ }
+
+ /**
+ * All of the following `printStackTrace` functionality is derived from JDK [Throwable]
+ * `printStackTrace`. In particular, the `PrintStreamOrWriter` abstraction is copied wholesale.
+ *
+ * Changes from the official JDK implementation:
+ * * no infinite loop detection
+ * * smaller critical section holding [PrintStream] lock
+ * * explicit knowledge about the exceptions [List] that this loops through
+ *
+ */
+ override fun printStackTrace() {
+ printStackTrace(System.err)
+ }
+
+ override fun printStackTrace(s: PrintStream) {
+ printStackTrace(WrappedPrintStream(s))
+ }
+
+ override fun printStackTrace(s: PrintWriter) {
+ printStackTrace(WrappedPrintWriter(s))
+ }
+
+ /**
+ * Special handling for printing out a `ExtCompositeException`.
+ * Loops through all inner exceptions and prints them out.
+ *
+ * @param s
+ * stream to print to
+ */
+ private fun printStackTrace(s: PrintStreamOrWriter) {
+ val b = StringBuilder(128)
+ b.append(this).append('\n')
+ for (myStackElement in stackTrace) {
+ b.append("\tat ").append(myStackElement).append('\n')
+ }
+ var i = 1
+ for (ex in exceptions) {
+ b.append(" ComposedException ").append(i).append(" :\n")
+ appendStackTrace(b, ex, "\t")
+ i++
+ }
+ s.println(b.toString())
+ }
+
+ private fun appendStackTrace(b: StringBuilder, ex: Throwable?, prefix: String) {
+ b.append(prefix).append(ex).append('\n')
+ ex?.stackTrace?.forEach { stackElement ->
+ b.append("\t\tat ").append(stackElement).append('\n')
+ }
+ if (ex?.cause != null) {
+ b.append("\tCaused by: ")
+ appendStackTrace(b, ex.cause, "")
+ }
+ }
+
+ internal abstract class PrintStreamOrWriter {
+ /** Prints the specified string as a line on this StreamOrWriter. */
+ abstract fun println(o: Any?)
+ }
+
+ /**
+ * Same abstraction and implementation as in JDK to allow PrintStream and PrintWriter to share implementation.
+ */
+ internal class WrappedPrintStream(private val printStream: PrintStream) : PrintStreamOrWriter() {
+ override fun println(o: Any?) {
+ printStream.println(o)
+ }
+ }
+
+ internal class WrappedPrintWriter(private val printWriter: PrintWriter) : PrintStreamOrWriter() {
+ override fun println(o: Any?) {
+ printWriter.println(o)
+ }
+ }
+
+ internal class CompositeExceptionCausalChain : RuntimeException() {
+
+ override val message = MESSAGE
+
+ companion object {
+ private const val serialVersionUID = 3875212506787802066L
+
+ /* package-private */
+ const val MESSAGE: String = "Chain of Causes for ExtCompositeException In Order Received =>"
+ }
+ }
+
+ private fun getListOfCauses(ex: Throwable): List {
+ val list: MutableList = ArrayList()
+ var root = ex.cause
+ if (root == null || root === ex) {
+ return list
+ } else {
+ while (true) {
+ list.add(root)
+ val cause = root?.cause
+ if (cause == null || cause === root) {
+ return list
+ } else {
+ root = cause
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the number of suppressed exceptions.
+ * @return the number of suppressed exceptions
+ */
+ fun size(): Int {
+ return exceptions.size
+ }
+
+ /**
+ * Returns the root cause of `e`. If `e.getCause()` returns `null` or `e`, just return `e` itself.
+ *
+ * @param e the [Throwable] `e`.
+ * @return The root cause of `e`. If `e.getCause()` returns `null` or `e`, just return `e` itself.
+ */
+ /*private */
+ fun getRootCause(e: Throwable?): Throwable? {
+ var root = e?.cause
+ if (root == null || e === root) {
+ return e
+ }
+ while (true) {
+ val cause = root?.cause
+ if (cause == null || cause === root) {
+ return root
+ }
+ root = cause
+ }
+ }
+}