diff --git a/daemon/configure.ac b/daemon/configure.ac
index 1a644e9e1c78d1f9ccd1422ec6c8a26ca9c0ab44..d81152e04ca4b66fdb3823a0989fc71f9698dcff 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -121,9 +121,6 @@ PKG_CHECK_MODULES(SAMPLERATE, samplerate >= ${LIBSAMPLERATE_MIN_VERSION},, AC_MS
 LIBCCGNU2_MIN_VERSION=1.3.1
 PKG_CHECK_MODULES(CCGNU2, commoncpp >= ${LIBCCGNU2_MIN_VERSION},, AC_MSG_ERROR([Missing common cpp development package: libcommoncpp2-dev]))
 
-LIBCCEXT2_MIN_VERSION=1.3.1
-PKG_CHECK_MODULES(CCEXT2, libccext2 >= ${LIBCCEXT2_MIN_VERSION})
-
 LIBCCRT_MIN_VERSION=1.3.0
 PKG_CHECK_MODULES(CCRTP, libccrtp >= ${LIBCCRT_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev]))
 
diff --git a/daemon/src/audio/alsa/alsalayer.cpp b/daemon/src/audio/alsa/alsalayer.cpp
index d40f78afe10fd83e25a038911be190846c9448f7..05e7731f80d26993a4683eff8d4ed9a0a9fc44ba 100644
--- a/daemon/src/audio/alsa/alsalayer.cpp
+++ b/daemon/src/audio/alsa/alsalayer.cpp
@@ -41,9 +41,7 @@ class AlsaThread : public ost::Thread {
     public:
         AlsaThread(AlsaLayer *alsa);
 
-        ~AlsaThread() {
-            terminate();
-        }
+        ~AlsaThread() { terminate(); }
 
         virtual void run();
 
@@ -53,16 +51,15 @@ class AlsaThread : public ost::Thread {
 };
 
 AlsaThread::AlsaThread(AlsaLayer *alsa)
-    : Thread(), alsa_(alsa)
-{
-}
+    : ost::Thread(), alsa_(alsa)
+{}
 
 /**
  * Reimplementation of run()
  */
 void AlsaThread::run()
 {
-    while (1) {
+    while (alsa_->isStarted_) {
         alsa_->audioCallback();
         Thread::sleep(20);
     }
@@ -93,6 +90,7 @@ AlsaLayer::AlsaLayer()
 // Destructor
 AlsaLayer::~AlsaLayer()
 {
+    isStarted_ = false;
     delete audioThread_;
 
     /* Then close the audio devices */
@@ -678,19 +676,17 @@ void AlsaLayer::audioCallback()
     if (ringtoneHandle_) {
         AudioLoop *file_tone = Manager::instance().getTelephoneFile();
         int ringtoneAvailSmpl = snd_pcm_avail_update(ringtoneHandle_);
-        int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof(SFLDataFormat);
+        int ringtoneAvailBytes = ringtoneAvailSmpl * sizeof(SFLDataFormat);
 
-        SFLDataFormat *out = (SFLDataFormat *) malloc(ringtoneAvailBytes);
+        std::vector<SFLDataFormat> out(ringtoneAvailSmpl, 0);
 
         if (file_tone) {
             DEBUG("playback gain %d", getPlaybackGain());
-            file_tone->getNext(out, ringtoneAvailSmpl, getPlaybackGain());
+            file_tone->getNext(&(*out.begin()), ringtoneAvailSmpl,
+                               getPlaybackGain());
         }
-        else
-            memset(out, 0, ringtoneAvailBytes);
 
-        write(out, ringtoneAvailBytes, ringtoneHandle_);
-        free(out);
+        write(&(*out.begin()), ringtoneAvailBytes, ringtoneHandle_);
     }
 
     // Additionally handle the mic's audio stream
diff --git a/daemon/src/audio/alsa/alsalayer.h b/daemon/src/audio/alsa/alsalayer.h
index bcd5caa9ac786c6b57970938468fe297a7d70584..76a84e2b69388ae2eea461f85ef418abf2de205b 100644
--- a/daemon/src/audio/alsa/alsalayer.h
+++ b/daemon/src/audio/alsa/alsalayer.h
@@ -149,7 +149,7 @@ class AlsaLayer : public AudioLayer {
         }
 
     private:
-
+        friend class AlsaThread;
 
         /**
          * Calls snd_pcm_open and retries if device is busy, since dmix plugin
@@ -241,7 +241,7 @@ class AlsaLayer : public AudioLayer {
         bool is_playback_open_;
         bool is_capture_open_;
 
-        AlsaThread* audioThread_;
+        AlsaThread *audioThread_;
 };
 
 #endif // _ALSA_LAYER_H_
diff --git a/daemon/src/audio/audiorecorder.cpp b/daemon/src/audio/audiorecorder.cpp
index e3fcc8832b132cb75f4b7f59ce7917556c55fb34..c2a062bc49f49e7240bd07fd223031dfce324254 100644
--- a/daemon/src/audio/audiorecorder.cpp
+++ b/daemon/src/audio/audiorecorder.cpp
@@ -34,7 +34,7 @@
 
 int AudioRecorder::count_ = 0;
 
-AudioRecorder::AudioRecorder(AudioRecord  *arec, MainBuffer *mb) : Thread(),
+AudioRecorder::AudioRecorder(AudioRecord  *arec, MainBuffer *mb) : ost::Thread(),
     recorderId_(), mbuffer_(mb), arecord_(arec)
 {
     assert(mb);
@@ -60,7 +60,7 @@ void AudioRecorder::run()
     int bufferLength = 10000;
     SFLDataFormat buffer[bufferLength];
 
-    while (true) {
+    while (isRunning()) {
         int availBytes = mbuffer_->availForGet(recorderId_);
         int toGet = (availBytes < bufferLength) ? availBytes : bufferLength;
 
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.cpp b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
index d03767ead8c84cd0abfd9a1c6b58b36bd9f30e18..180dc0bc25b846f482ed9ed013e8b0399e10bc15 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
@@ -60,8 +60,6 @@ AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string& zidFilename
 {
     DEBUG("AudioZrtpSession initialized");
     initializeZid();
-
-
     DEBUG("AudioZrtpSession: Setting new RTP session with destination %s:%d",
           call_.getLocalIp().c_str(), call_.getLocalAudioPort());
 }
@@ -72,14 +70,6 @@ AudioZrtpSession::~AudioZrtpSession()
     Manager::instance().getMainBuffer()->unBindAll(call_.getCallId());
 }
 
-void AudioZrtpSession::final()
-{
-// tmatth:Oct 25 2011:FIXME:
-// This was crashing...seems like it's not necessary. Double check
-// with valgrind/helgrind
-// delete this;
-}
-
 void AudioZrtpSession::initializeZid()
 {
     if (zidFilename_.empty())
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.h b/daemon/src/audio/audiortp/audio_zrtp_session.h
index c635349efe74dd3bf11e8100eea34eabd2afa367..65a86fa352e3fe24d559c4b10bc51364b694afea 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.h
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.h
@@ -60,8 +60,6 @@ class AudioZrtpSession :
         AudioZrtpSession(SIPCall &call, const std::string& zidFilename);
         ~AudioZrtpSession();
 
-        virtual void final();
-
         // Thread associated method
         virtual void run();
 
diff --git a/daemon/src/audio/pulseaudio/pulselayer.cpp b/daemon/src/audio/pulseaudio/pulselayer.cpp
index 4cc0fcc73d9eccd90a4b6d9a93682c83bee1aa09..e7c0836367fac9a9ad713596859e320762300229 100644
--- a/daemon/src/audio/pulseaudio/pulselayer.cpp
+++ b/daemon/src/audio/pulseaudio/pulselayer.cpp
@@ -124,7 +124,7 @@ PulseLayer::~PulseLayer()
     if (mainloop_)
         pa_threaded_mainloop_free(mainloop_);
 
-    delete[] mic_buffer_;
+    delete [] mic_buffer_;
 }
 
 void PulseLayer::context_state_callback(pa_context* c, void *user_data)
@@ -422,7 +422,7 @@ void PulseLayer::readFromMic()
 
     if (bytes > mic_buf_size_) {
         mic_buf_size_ = bytes;
-        delete[] mic_buffer_;
+        delete [] mic_buffer_;
         mic_buffer_ = new SFLDataFormat[samples];
     }
 
diff --git a/daemon/src/eventthread.cpp b/daemon/src/eventthread.cpp
index b712837fc84aeb7719f78f361165e428a4048cd9..36fbd7be5cf279315a8127b6dd5b2d6ff90fa40a 100644
--- a/daemon/src/eventthread.cpp
+++ b/daemon/src/eventthread.cpp
@@ -31,12 +31,13 @@
 #include "eventthread.h"
 #include "voiplink.h"
 
-EventThread::EventThread(VoIPLink *link) : Thread(), link_(link)
+EventThread::EventThread(VoIPLink *link) : ost::Thread(), link_(link)
 {}
 
 void EventThread::run()
 {
-    while (isRunning())
-        link_->getEvent();
+    while (link_->getEvent())
+        ;  // noop
+    ost::Thread::exit();
 }
 
diff --git a/daemon/src/eventthread.h b/daemon/src/eventthread.h
index 58676b9f5350c73ab6a12b06ca9471e56d083abf..8c48f9d123fb00fe3a26ace4798f69298ade992a 100644
--- a/daemon/src/eventthread.h
+++ b/daemon/src/eventthread.h
@@ -44,7 +44,7 @@ class VoIPLink;
 class EventThread : public ost::Thread {
     public:
         EventThread(VoIPLink* link);
-        virtual void run();
+        void run();
 
     private:
         NON_COPYABLE(EventThread);
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index 17b11d52a86a28fb03ed7f07cfcbb3e338cb57f3..e91792a6d8c4c5416ad4d6253b91dc0bfef5c60a 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -56,6 +56,7 @@ IAXVoIPLink::IAXVoIPLink(const std::string& accountID) :
 
 IAXVoIPLink::~IAXVoIPLink()
 {
+    handlingEvents_ = false;
     delete evThread_;
 
     regSession_ = NULL; // shall not delete it // XXX: but why?
@@ -70,6 +71,7 @@ IAXVoIPLink::init()
 
     for (int port = IAX_DEFAULT_PORTNO, nbTry = 0; nbTry < 3 ; port = rand() % 64000 + 1024, nbTry++) {
         if (iax_init(port) >= 0) {
+            handlingEvents_ = false;
             evThread_->start();
             initDone_ = true;
             break;
@@ -100,7 +102,7 @@ IAXVoIPLink::terminate()
     initDone_ = false;
 }
 
-void
+bool
 IAXVoIPLink::getEvent()
 {
     mutexIAX_.enter();
@@ -133,7 +135,8 @@ IAXVoIPLink::getEvent()
     sendAudioFromMic();
 
     // thread wait 3 millisecond
-    evThread_->sleep(3);
+    ost::Thread::sleep(3);
+    return handlingEvents_;
 }
 
 void
diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h
index 7c74b1a5a8aea52550f5b8d0838ec12388a4abdd..11e264f002ead74a8eb1285008e12e6e2eef58c7 100644
--- a/daemon/src/iax/iaxvoiplink.h
+++ b/daemon/src/iax/iaxvoiplink.h
@@ -62,7 +62,7 @@ class IAXVoIPLink : public VoIPLink {
         /**
          *	Listen to events sent by the call manager ( asterisk, etc .. )
          */
-        void getEvent();
+        bool getEvent();
 
         /**
          * Init the voip link
diff --git a/daemon/src/main.cpp b/daemon/src/main.cpp
index 0d5fe3834359e86fbb01c7fd90f6cf5335a3948f..05af64d9b04eb90390d5414ec6cb03e2f4715edd 100644
--- a/daemon/src/main.cpp
+++ b/daemon/src/main.cpp
@@ -55,7 +55,7 @@ ost::CommandOptionNoArg	help(
     "help", "h", "Print help"
 );
 */
-int main(int argc, char **argv)
+int main(int /*argc*/, char **argv)
 {
     fileutils::set_program_dir(argv[0]);
     // makeCommandOptionParse allocates the object with operator new, so
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 6729a0f3f9e576050596b8cea9a1d19d03b817f9..cf475d5540487739fa0cfc0234b597d433011953 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -86,10 +86,6 @@ ManagerImpl::ManagerImpl() :
     srand(time(NULL));
 }
 
-// never call if we use only the singleton...
-ManagerImpl::~ManagerImpl()
-{}
-
 void ManagerImpl::init(const std::string &config_file)
 {
     path_ = config_file.empty() ? createConfigFile() : config_file;
@@ -126,13 +122,12 @@ void ManagerImpl::terminate()
     std::vector<std::string> callList(getCallList());
     DEBUG("Manager: Hangup %zu remaining call", callList.size());
 
-    for (std::vector<std::string>::iterator iter = callList.begin(); iter != callList.end(); ++iter)
+    for (std::vector<std::string>::iterator iter = callList.begin();
+         iter != callList.end(); ++iter)
         hangupCall(*iter);
 
     saveConfig();
 
-    delete SIPVoIPLink::instance();
-
     // Unload account map AFTER destroying
     // the SIPVoIPLink, the link still needs the accounts for pjsip cleanup
     unloadAccountMap();
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index c4b968fa2d3668d51edfb838685fed3efc299f0f..53ca83746ba061f8a547cca109127badd48ad3c1 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -93,7 +93,6 @@ static const char * const default_conf = "conf";
 class ManagerImpl {
     public:
         ManagerImpl();
-        ~ManagerImpl();
 
         /**
          * General preferences configuration
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 34003068e50a1da008f3e724953c5b54870b28c8..2afd40b29d56c16a70e7c47fddd30d373ad0c522 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -89,7 +89,7 @@ static pj_caching_pool pool_cache, *cp_ = &pool_cache;
 static pj_pool_t *pool_;
 static pjsip_endpoint *endpt_;
 static pjsip_module mod_ua_;
-static pj_thread_t *thread;
+static pj_thread_t *thread_;
 
 void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status);
 void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
@@ -481,15 +481,19 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(this)
     TRY(pjsip_replaces_init_module(endpt_));
 #undef TRY
 
-    evThread_.detach();
+    handlingEvents_ = true;
+    evThread_.start();
 }
 
 SIPVoIPLink::~SIPVoIPLink()
 {
-    if (evThread_.isRunning())
-        evThread_.join();
-    pj_thread_join(thread);
-    pj_thread_destroy(thread);
+    handlingEvents_ = false;
+    if (thread_) {
+        pj_thread_join(thread_);
+        pj_thread_destroy(thread_);
+        DEBUG("PJ thread destroy finished");
+        thread_ = 0;
+    }
 
     const pj_time_val tv = {0, 10};
     pjsip_endpt_handle_events(endpt_, &tv);
@@ -503,25 +507,24 @@ SIPVoIPLink::~SIPVoIPLink()
 
 SIPVoIPLink* SIPVoIPLink::instance()
 {
-    static SIPVoIPLink* instance = NULL;
-
-    if (!instance)
-        instance = new SIPVoIPLink;
-
-    return instance;
+    static SIPVoIPLink instance_;
+    return &instance_;
 }
 
-void
-SIPVoIPLink::getEvent()
+// Called from EventThread::run (not main thread)
+bool SIPVoIPLink::getEvent()
 {
     static pj_thread_desc desc;
 
     // We have to register the external thread so it could access the pjsip frameworks
-    if (!pj_thread_is_registered())
+    if (!pj_thread_is_registered()) {
+        DEBUG("%s: Registering thread", __PRETTY_FUNCTION__);
         pj_thread_register(NULL, desc, &thread);
+    }
 
     static const pj_time_val timeout = {0, 10};
     pjsip_endpt_handle_events(endpt_, &timeout);
+    return handlingEvents_;
 }
 
 void SIPVoIPLink::sendRegister(Account *a)
diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h
index dd2701075c70cd2c7a2efa4cc42da905e62e88ec..9a6c14eeda21f14753b40415d45b3fa6ffc8e07a 100644
--- a/daemon/src/sip/sipvoiplink.h
+++ b/daemon/src/sip/sipvoiplink.h
@@ -46,12 +46,11 @@
 #include <pjnath.h>
 #include <pjnath/stun_config.h>
 ///////////////////////////////
-#include "eventthread.h"
 #include "sipaccount.h"
 #include "voiplink.h"
 #include "siptransport.h"
+#include "eventthread.h"
 
-class EventThread;
 class SIPCall;
 class SIPAccount;
 
@@ -75,7 +74,7 @@ class SIPVoIPLink : public VoIPLink {
         /**
          * Event listener. Each event send by the call manager is received and handled from here
          */
-        virtual void getEvent();
+        virtual bool getEvent();
 
         /**
          * Build and send SIP registration request
diff --git a/daemon/src/voiplink.cpp b/daemon/src/voiplink.cpp
index 6a34ea5f4cf704ba933bfbd3f17ce70d6ca49cf2..49bc2d4d0ecdd8ffc1c7d0f9f092653b6c3fe6d4 100644
--- a/daemon/src/voiplink.cpp
+++ b/daemon/src/voiplink.cpp
@@ -34,7 +34,7 @@
 #include "call.h"
 #include "voiplink.h"
 
-VoIPLink::VoIPLink() : callMap_(), callMapMutex_() {}
+VoIPLink::VoIPLink() : callMap_(), callMapMutex_(), handlingEvents_(false) {}
 
 VoIPLink::~VoIPLink()
 {
diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h
index fa1d34bfd5d754bb02c5aff03771857052256682..f28dfffe19f536bba25c164a79bff88739d7078a 100644
--- a/daemon/src/voiplink.h
+++ b/daemon/src/voiplink.h
@@ -63,7 +63,7 @@ class VoIPLink {
          * Virtual method
          * Event listener. Each event send by the call manager is received and handled from here
          */
-        virtual void getEvent() = 0;
+        virtual bool getEvent() = 0;
 
         /**
          * Virtual method
@@ -183,6 +183,8 @@ class VoIPLink {
         /** Mutex to protect call map */
         ost::Mutex callMapMutex_;
 
+        bool handlingEvents_;
+
         /** Remove a call from the call map (protected by mutex)
          * @param id A Call ID
          */