Add ProGuard instructions to make sure AndroidExceptionPreHandler
is kept on Android when using minification. Make sure that original
app exception is not "eaten" any case.

Fixes #214
diff --git a/README.md b/README.md
index f43d212..789d0ea 100644
--- a/README.md
+++ b/README.md
@@ -101,8 +101,15 @@
 In obfuscated code, fields with different types can have the same names,
 and `AtomicReferenceFieldUpdater` may be unable to find the correct ones.
 To avoid field overloading by type during obfuscation, add this to your config:
+
 ```
 -keepclassmembernames class kotlinx.** {
     volatile <fields>;
 }
 ```
+
+You also need to keep this class if you build your Android releases with `minifyEnabled true`:
+
+```
+-keep class kotlinx.coroutines.experimental.android.AndroidExceptionPreHandler
+```
diff --git a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CoroutineExceptionHandler.kt b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CoroutineExceptionHandler.kt
index a8ef8bd..2bb0cc7 100644
--- a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CoroutineExceptionHandler.kt
+++ b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/CoroutineExceptionHandler.kt
@@ -33,21 +33,31 @@
  *     * current thread's [Thread.uncaughtExceptionHandler] is invoked.
  */
 public actual fun handleCoroutineException(context: CoroutineContext, exception: Throwable) {
-    context[CoroutineExceptionHandler]?.let {
-        it.handleException(context, exception)
-        return
+    // if exception handling fails, make sure the original exception is not lost
+    try {
+        context[CoroutineExceptionHandler]?.let {
+            it.handleException(context, exception)
+            return
+        }
+        // ignore CancellationException (they are normal means to terminate a coroutine)
+        if (exception is CancellationException) return
+        // try cancel job in the context
+        context[Job]?.cancel(exception)
+        // use additional extension handlers
+        ServiceLoader.load(CoroutineExceptionHandler::class.java).forEach { handler ->
+            handler.handleException(context, exception)
+        }
+        // use thread's handler
+        val currentThread = Thread.currentThread()
+        currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, exception)
+    } catch (handlerException: Throwable) {
+        // simply rethrow if handler threw the original exception
+        if (handlerException === exception) throw exception
+        // handler itself crashed for some other reason -- that is bad -- keep both
+        throw RuntimeException("Exception while trying to handle coroutine exception", exception).apply {
+            addSuppressed(handlerException)
+        }
     }
-    // ignore CancellationException (they are normal means to terminate a coroutine)
-    if (exception is CancellationException) return
-    // try cancel job in the context
-    context[Job]?.cancel(exception)
-    // use additional extension handlers
-    ServiceLoader.load(CoroutineExceptionHandler::class.java).forEach { handler ->
-        handler.handleException(context, exception)
-    }
-    // use thread's handler
-    val currentThread = Thread.currentThread()
-    currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, exception)
 }
 
 /**