diff --git a/ring-android/app/src/main/java/cx/ring/service/SipService.java b/ring-android/app/src/main/java/cx/ring/service/SipService.java
index 820b001710e5fad1e63049ed3904a3b1984fcf4f..7adce55fba80cf805e1b6a06ced839191db0c550 100644
--- a/ring-android/app/src/main/java/cx/ring/service/SipService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/SipService.java
@@ -141,7 +141,7 @@ public class SipService extends Service {
     /* called for each startService() */
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.i(TAG, "onStarted");
+        Log.i(TAG, "onStarted " + intent.getAction() + " " + flags);
         super.onStartCommand(intent, flags, startId);
         return START_STICKY; /* started and stopped explicitly */
     }
@@ -225,12 +225,93 @@ public class SipService extends Service {
                 Log.e(TAG, "run task: " + task, t);
             }
         }
+
+        public final boolean executeSynced(final Runnable r) {
+            if (r == null) {
+                throw new IllegalArgumentException("runnable must not be null");
+            }
+            if (Looper.myLooper() == getLooper()) {
+                r.run();
+                return true;
+            }
+
+            BlockingRunnable br = new BlockingRunnable(r);
+            return br.postAndWait(this, 0);
+        }
+        public final <T> T executeAndReturn(final SipRunnableWithReturn<T> r) {
+            if (r == null) {
+                throw new IllegalArgumentException("runnable must not be null");
+            }
+            if (Looper.myLooper() == getLooper()) {
+                r.run();
+                return r.getVal();
+            }
+
+            BlockingRunnable br = new BlockingRunnable(r);
+            if (!br.postAndWait(this, 0))
+                throw new RuntimeException("Can't execute runnable");
+            return r.getVal();
+        }
+
+        private static final class BlockingRunnable implements Runnable {
+            private final Runnable mTask;
+            private boolean mDone;
+
+            public BlockingRunnable(Runnable task) {
+                mTask = task;
+            }
+
+            @Override
+            public void run() {
+                try {
+                    mTask.run();
+                } finally {
+                    synchronized (this) {
+                        mDone = true;
+                        notifyAll();
+                    }
+                }
+            }
+
+            public boolean postAndWait(Handler handler, long timeout) {
+                if (!handler.post(this)) {
+                    return false;
+                }
+
+                synchronized (this) {
+                    if (timeout > 0) {
+                        final long expirationTime = SystemClock.uptimeMillis() + timeout;
+                        while (!mDone) {
+                            long delay = expirationTime - SystemClock.uptimeMillis();
+                            if (delay <= 0) {
+                                return false; // timeout
+                            }
+                            try {
+                                wait(delay);
+                            } catch (InterruptedException ex) {
+                            }
+                        }
+                    } else {
+                        while (!mDone) {
+                            try {
+                                wait();
+                            } catch (InterruptedException ex) {
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+        }
     }
 
     private void stopDaemon() {
         handler.removeCallbacks(pollEvents);
-        Ringservice.fini();
-        isPjSipStackStarted = false;
+        if (isPjSipStackStarted) {
+            Ringservice.fini();
+            isPjSipStackStarted = false;
+            Log.i(TAG, "PjSIPStack stopped");
+        }
     }
 
     private void startPjSipStack() throws SameThreadException {
@@ -238,12 +319,6 @@ public class SipService extends Service {
             return;
 
         try {
-            /*System.loadLibrary("codec_ulaw");
-            System.loadLibrary("codec_alaw");
-            System.loadLibrary("codec_speex");
-            System.loadLibrary("codec_g729");
-            System.loadLibrary("codec_gsm");
-            System.loadLibrary("codec_opus");*/
             System.loadLibrary("ringjni");
             isPjSipStackStarted = true;
 
@@ -287,26 +362,24 @@ public class SipService extends Service {
         }
     }
 
-    public abstract class SipRunnableWithReturn implements Runnable {
-        Object obj = null;
-        boolean done = false;
+    public abstract class SipRunnableWithReturn<T> implements Runnable {
+        private T obj = null;
+        //boolean done = false;
 
-        protected abstract Object doRun() throws SameThreadException, RemoteException;
+        protected abstract T doRun() throws SameThreadException, RemoteException;
 
-        public Object getVal() {
+        public T getVal() {
             return obj;
         }
 
-        public boolean isDone() {
-            return done;
-        }
-
         @Override
         public void run() {
             try {
                 if (isPjSipStackStarted)
                     obj = doRun();
-                done = true;
+                else
+                    Log.e(TAG, "Can't perform operation: daemon not started.");
+                //done = true;
             } catch (SameThreadException e) {
                 Log.e(TAG, "Not done from same thread");
             } catch (RemoteException e) {
@@ -425,27 +498,14 @@ public class SipService extends Service {
         }
 
         @Override
-        public Map<String, String> getCallDetails(String callID) throws RemoteException {
-            class CallDetails extends SipRunnableWithReturn {
-                private String id;
-
-                CallDetails(String callID) {
-                    id = callID;
-                }
-
+        public Map<String, String> getCallDetails(final String callID) throws RemoteException {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getCallDetails() thread running...");
-                    return Ringservice.getCallDetails(id).toNative();
+                    return Ringservice.getCallDetails(callID).toNative();
                 }
-            }
-
-            CallDetails runInstance = new CallDetails(callID);
-            getExecutor().execute(runInstance);
-
-            while (!runInstance.isDone()) {
-            }
-            return (Map<String, String>)runInstance.getVal();
+            });
         }
 
         @Override
@@ -461,43 +521,24 @@ public class SipService extends Service {
 
         @Override
         public String getCurrentAudioOutputPlugin() {
-            class CurrentAudioPlugin extends SipRunnableWithReturn {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
                     return Ringservice.getCurrentAudioOutputPlugin();
                 }
-            }
-
-            CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-                // Log.e(TAG, "Waiting for Nofing");
-            }
-            return (String) runInstance.getVal();
+            });
         }
 
         @Override
-        public ArrayList<String> getAccountList() {
-            class AccountList extends SipRunnableWithReturn {
+        public List<String> getAccountList() {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<List<String>>() {
                 @Override
-                protected StringVect doRun() throws SameThreadException {
+                protected List<String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getAccountList() thread running...");
-                    return Ringservice.getAccountList();
+                    return new ArrayList<>(Ringservice.getAccountList());
                 }
-            }
-            AccountList runInstance = new AccountList();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-            StringVect swigvect = (StringVect) runInstance.getVal();
-
-            ArrayList<String> nativelist = new ArrayList<String>();
-
-            for (int i = 0; i < swigvect.size(); i++)
-                nativelist.add(swigvect.get(i));
-
-            return nativelist;
+            });
         }
 
         @Override
@@ -513,32 +554,20 @@ public class SipService extends Service {
 
         @Override
         public Map<String, String> getAccountDetails(final String accountID) {
-            class AccountDetails extends SipRunnableWithReturn {
-                private String id;
-
-                AccountDetails(String accountId) {
-                    id = accountId;
-                }
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getAccountDetails() thread running...");
-                    return Ringservice.getAccountDetails(id).toNative();
+                    return Ringservice.getAccountDetails(accountID).toNative();
                 }
-            }
-
-            AccountDetails runInstance = new AccountDetails(accountID);
-            getExecutor().execute(runInstance);
-
-            while (!runInstance.isDone()) {
-            }
-            return (Map<String, String>) runInstance.getVal();
+            });
         }
 
         @SuppressWarnings("unchecked")
         // Hashmap runtime cast
         @Override
         public void setAccountDetails(final String accountId, final Map map) {
+            Log.i(TAG, "SipService.setAccountDetails() " + map.get("Account.hostname"));
             final StringMap swigmap = StringMap.toSwig(map);
 
             getExecutor().execute(new SipRunnable() {
@@ -546,56 +575,45 @@ public class SipService extends Service {
                 protected void doRun() throws SameThreadException {
 
                     Ringservice.setAccountDetails(accountId, swigmap);
-                    Log.i(TAG, "SipService.setAccountDetails() thread running...");
+                    Log.i(TAG, "SipService.setAccountDetails() thread running... " + swigmap.get("Account.hostname"));
                 }
 
             });
         }
 
         @Override
-        public Map<String, String> getAccountTemplate(final String accountType) throws RemoteException {
-            class AccountTemplate extends SipRunnableWithReturn {
+        public Map<String, String> getVolatileAccountDetails(final String accountId) {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
+                @Override
+                protected Map<String, String> doRun() throws SameThreadException {
+                    Log.i(TAG, "SipService.getVolatileAccountDetails() thread running...");
+                    return Ringservice.getVolatileAccountDetails(accountId).toNative();
+                }
+            });
+        }
 
+        @Override
+        public Map<String, String> getAccountTemplate(final String accountType) throws RemoteException {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getAccountTemplate() thread running...");
                     return Ringservice.getAccountTemplate(accountType).toNative();
                 }
-            }
-
-            AccountTemplate runInstance = new AccountTemplate();
-            getExecutor().execute(runInstance);
-
-            while (!runInstance.isDone()) {
-            }
-            return (Map<String, String>) runInstance.getVal();
+            });
         }
 
         @SuppressWarnings("unchecked")
         // Hashmap runtime cast
         @Override
-        public String addAccount(Map map) {
-            class AddAccount extends SipRunnableWithReturn {
-                StringMap map;
-
-                AddAccount(StringMap m) {
-                    map = m;
-                }
-
+        public String addAccount(final Map map) {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.addAccount() thread running...");
-                    return Ringservice.addAccount(map);
+                    return Ringservice.addAccount(StringMap.toSwig(map));
                 }
-            }
-
-            final StringMap swigmap = StringMap.toSwig(map);
-
-            AddAccount runInstance = new AddAccount(swigmap);
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-            return (String) runInstance.getVal();
+            });
         }
 
         @Override
@@ -777,21 +795,13 @@ public class SipService extends Service {
 
         @Override
         public boolean isConferenceParticipant(final String callID) throws RemoteException {
-            class IsParticipant extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Boolean>() {
                 @Override
                 protected Boolean doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.isRecording() thread running...");
                     return Ringservice.isConferenceParticipant(callID);
                 }
-            }
-
-            IsParticipant runInstance = new IsParticipant();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Boolean) runInstance.getVal();
+            });
         }
 
         @Override
@@ -821,28 +831,14 @@ public class SipService extends Service {
         }
 
         @Override
-        public List getParticipantList(final String confID) throws RemoteException {
-            class PartList extends SipRunnableWithReturn {
+        public List<String> getParticipantList(final String confID) throws RemoteException {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<List<String>>() {
                 @Override
-                protected StringVect doRun() throws SameThreadException {
+                protected List<String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getParticipantList() thread running...");
-                    return Ringservice.getParticipantList(confID);
+                    return new ArrayList<>(Ringservice.getParticipantList(confID));
                 }
-            }
-            ;
-            PartList runInstance = new PartList();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-                Log.w(TAG, "getParticipantList");
-            }
-            StringVect swigvect = (StringVect) runInstance.getVal();
-            Log.w(TAG, "After that");
-            ArrayList<String> nativelist = new ArrayList<String>();
-
-            for (int i = 0; i < swigvect.size(); i++)
-                nativelist.add(swigvect.get(i));
-
-            return nativelist;
+            });
         }
 
         @Override
@@ -853,46 +849,29 @@ public class SipService extends Service {
 
         @Override
         public String getConferenceDetails(final String callID) throws RemoteException {
-            class ConfDetails extends SipRunnableWithReturn {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getConferenceDetails() thread running...");
                     return Ringservice.getConferenceDetails(callID).get("CONF_STATE");
                 }
-            }
-            ConfDetails runInstance = new ConfDetails();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-                // Log.w(TAG, "Waiting for getConferenceList");
-            }
-            return (String) runInstance.getVal();
+            });
         }
 
         @Override
         public String getRecordPath() throws RemoteException {
-            class RecordPath extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<String>() {
                 @Override
                 protected String doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getRecordPath() thread running...");
                     return Ringservice.getRecordPath();
                 }
-            }
-
-            RecordPath runInstance = new RecordPath();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-                // Log.w(TAG, "Waiting for getRecordPath");
-            }
-
-            return (String) runInstance.getVal();
+            });
         }
 
         @Override
         public boolean toggleRecordingCall(final String id) throws RemoteException {
-
-            class ToggleRecording extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Boolean>() {
                 @Override
                 protected Boolean doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.toggleRecordingCall() thread running...");
@@ -908,15 +887,7 @@ public class SipService extends Service {
                     }
                     return result;
                 }
-            }
-
-            ToggleRecording runInstance = new ToggleRecording();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Boolean) runInstance.getVal();
-
+            });
         }
 
         @Override
@@ -968,13 +939,12 @@ public class SipService extends Service {
         }
 
         @Override
-        public List getAudioCodecList(final String accountID) throws RemoteException {
-            class AudioCodecList extends SipRunnableWithReturn {
-
+        public List<Codec> getAudioCodecList(final String accountID) throws RemoteException {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<ArrayList<Codec>>() {
                 @Override
                 protected ArrayList<Codec> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getAudioCodecList() thread running...");
-                    ArrayList<Codec> results = new ArrayList<Codec>();
+                    ArrayList<Codec> results = new ArrayList<>();
 
                     UintVect active_payloads = Ringservice.getActiveCodecList(accountID);
                     for (int i = 0; i < active_payloads.size(); ++i) {
@@ -990,27 +960,18 @@ public class SipService extends Service {
                             if (co.getPayload() == payloads.get(i))
                                 isActive = true;
                         }
-                        if (isActive)
-                            continue;
-                        else {
+                        if (!isActive) {
                             StringMap details = Ringservice.getCodecDetails(accountID, payloads.get(i));
                             if (details.size() > 1)
                                 results.add(new Codec(payloads.get(i), Ringservice.getCodecDetails(accountID, payloads.get(i)), false));
                             else
                                 Log.i(TAG, "Error loading codec " + i);
                         }
-
                     }
 
                     return results;
                 }
-            }
-
-            AudioCodecList runInstance = new AudioCodecList();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-            return (ArrayList<Codec>) runInstance.getVal();
+            });
         }
 
         /*
@@ -1099,78 +1060,46 @@ public class SipService extends Service {
 
         @Override
         public Map<String, String> validateCertificate(final String accountID, final String certificatePath, final String privateKeyPath) throws RemoteException {
-            class isValid extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.isCaptureMuted() thread running...");
                     return Ringservice.validateCertificate(accountID, certificatePath, privateKeyPath).toNative();
                 }
-            }
-
-            isValid runInstance = new isValid();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Map<String, String>) runInstance.getVal();
+            });
         }
 
         @Override
         public Map<String, String> validateCertificateRaw(final String accountID, final byte[] certificateRaw) throws RemoteException {
-            class isValid extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.isCaptureMuted() thread running...");
                     return Ringservice.validateCertificateRaw(accountID, SwigNativeConverter.convertFromNativeToSwig(certificateRaw)).toNative();
                 }
-            }
-
-            isValid runInstance = new isValid();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Map<String, String>) runInstance.getVal();
+            });
         }
 
         @Override
         public Map<String, String> getCertificateDetails(final String certificatePath) throws RemoteException {
-            class isValid extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.isCaptureMuted() thread running...");
                     return Ringservice.getCertificateDetails(certificatePath).toNative();
                 }
-            }
-
-            isValid runInstance = new isValid();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Map<String, String>) runInstance.getVal();
+            });
         }
 
         @Override
         public Map<String, String> getCertificateDetailsRaw(final byte[] certificateRaw) throws RemoteException {
-            class isValid extends SipRunnableWithReturn {
-
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Map<String, String>>() {
                 @Override
                 protected Map<String, String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.isCaptureMuted() thread running...");
                     return Ringservice.getCertificateDetailsRaw(SwigNativeConverter.convertFromNativeToSwig(certificateRaw)).toNative();
                 }
-            }
-
-            isValid runInstance = new isValid();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Map<String, String>) runInstance.getVal();
+            });
         }
 
         @Override
@@ -1216,8 +1145,8 @@ public class SipService extends Service {
         }
 
         @Override
-        public List getConcurrentCalls() throws RemoteException {
-            return new ArrayList(mConferences.values());
+        public List<Conference> getConcurrentCalls() throws RemoteException {
+            return new ArrayList<>(mConferences.values());
         }
 
         @Override
@@ -1238,21 +1167,14 @@ public class SipService extends Service {
 
         @Override
         public boolean isCaptureMuted() throws RemoteException {
-            class IsMuted extends SipRunnableWithReturn {
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<Boolean>() {
 
                 @Override
                 protected Boolean doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.isCaptureMuted() thread running...");
                     return Ringservice.isCaptureMuted();
                 }
-            }
-
-            IsMuted runInstance = new IsMuted();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-
-            return (Boolean) runInstance.getVal();
+            });
         }
 
         @Override
@@ -1270,22 +1192,14 @@ public class SipService extends Service {
 
 
         @Override
-        public List getTlsSupportedMethods(){
-            class TlsMethods extends SipRunnableWithReturn {
-
+        public List<String> getTlsSupportedMethods(){
+            return getExecutor().executeAndReturn(new SipRunnableWithReturn<List<String>>() {
                 @Override
-                protected List doRun() throws SameThreadException {
+                protected List<String> doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getCredentials() thread running...");
-                    StringVect map = Ringservice.getSupportedTlsMethod();
-                    return SwigNativeConverter.convertSwigToNative(map);
+                    return SwigNativeConverter.convertSwigToNative(Ringservice.getSupportedTlsMethod());
                 }
-            }
-
-            TlsMethods runInstance = new TlsMethods();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
-            return (List) runInstance.getVal();
+            });
         }
 
         @Override
@@ -1300,9 +1214,7 @@ public class SipService extends Service {
             }
 
             Credentials runInstance = new Credentials();
-            getExecutor().execute(runInstance);
-            while (!runInstance.isDone()) {
-            }
+            getExecutor().executeSynced(runInstance);
             return (List) runInstance.getVal();
         }
 
@@ -1312,7 +1224,6 @@ public class SipService extends Service {
                 @Override
                 protected void doRun() throws SameThreadException, RemoteException {
                     Log.i(TAG, "SipService.setCredentials() thread running...");
-                    ArrayList<HashMap<String, String>> list = (ArrayList<HashMap<String, String>>) creds;
                     Ringservice.setCredentials(accountID, SwigNativeConverter.convertFromNativeToSwig(creds));
                 }
             });