package com.bugsnag.android;

import java.lang.Thread.UncaughtExceptionHandler;

class ExceptionHandler implements UncaughtExceptionHandler {
    private UncaughtExceptionHandler originalHandler;
    private Client client;

    static void install(Client client) {
        UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler();
        if(currentHandler instanceof ExceptionHandler) {
            currentHandler = ((ExceptionHandler)currentHandler).originalHandler;
        }

        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(currentHandler, client));
    }

    static void remove() {
        UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler();
        if(currentHandler instanceof ExceptionHandler) {
            Thread.setDefaultUncaughtExceptionHandler(((ExceptionHandler)currentHandler).originalHandler);
        }
    }

    public ExceptionHandler(UncaughtExceptionHandler originalHandler, Client client) {
        this.originalHandler = originalHandler;
        this.client = client;
    }

    public void uncaughtException(Thread t, Throwable e) {
        client.autoNotify(e);
        if(originalHandler != null) {
            originalHandler.uncaughtException(t, e);
        } else {
            System.err.printf("Exception in thread \"%s\" ", t.getName());
            e.printStackTrace(System.err);
        }
    }
}

@@ -72,16 +72,64 @@
 Handler;
+%0Aimport java.util.HashSet;%0Aimport java.util.Set;
 %0A%0Aclass 
@@ -249,29 +249,59 @@
 private 
+Set%3C
 Client
+%3E
  client
+s = new HashSet%3CClient%3E()
 ;%0A%0A    s
@@ -315,15 +315,14 @@
 oid 
-install
+enable
 (Cli
@@ -421,32 +421,129 @@
 eptionHandler();
+%0A%0A        // Find or create the Bugsnag ExceptionHandler%0A        ExceptionHandler bugsnagHandler;
 %0A        if(curr
@@ -596,23 +596,23 @@
         
-current
+bugsnag
 Handler 
@@ -613,17 +613,16 @@
 ndler = 
-(
 (Excepti
@@ -649,38 +649,98 @@
 dler
-).original
+;%0A        %7D else %7B%0A            bugsnagHandler = new ExceptionHandler(current
 Handler
+)
 ;%0A    
-  
-  %7D%0A%0A
     
@@ -789,53 +789,134 @@
 ler(
-new ExceptionHandler(currentHandler, 
+bugsnagHandler);%0A        %7D%0A%0A        // Subscribe this client to uncaught exceptions%0A        bugsnagHandler.clients.add(
 client)
-)
 ;%0A  
@@ -940,18 +940,77 @@
 oid 
-remove() %7B
+disable(Client client) %7B%0A        // Find tje Bugsnag ExceptionHandler
 %0A   
@@ -1174,84 +1174,397 @@
     
-Thread.setDefaultUncaughtExceptionHandler(((ExceptionHandler)currentHandler)
+// Unsubscribe this client from uncaught exceptions%0A            ExceptionHandler bugsnagHandler = (ExceptionHandler)currentHandler;%0A            bugsnagHandler.clients.remove(client);%0A%0A            // Remove the Bugsnag ExceptionHandler if no clients are subscribed%0A            if(bugsnagHandler.clients.size() == 0) %7B%0A                Thread.setDefaultUncaughtExceptionHandler(bugsnagHandler
 .ori
@@ -1570,32 +1570,46 @@
 iginalHandler);%0A
+            %7D%0A
         %7D%0A    %7D%0A
@@ -1681,23 +1681,8 @@
 dler
-, Client client
 ) %7B%0A
@@ -1733,38 +1733,8 @@
 er;%0A
-        this.client = client;%0A
     
@@ -1807,29 +1807,221 @@
     
-client.autoNotify(e);
+// Notify any subscribed clients of the uncaught exception%0A        for(Client client : clients) %7B%0A            client.notify(e, Severity.ERROR);%0A        %7D%0A%0A        // Pass exception on to original exception handler
 %0A   

Allow subscribing multiple clients to uncaught exceptions