diff --git a/daemon/src/dbus/callmanager-introspec.xml b/daemon/src/dbus/callmanager-introspec.xml
index c86062e82a331a9f052063557685d6cb4fe8b64e..ad062f2e7e31d374d13ac2c404d3061562cdf492 100644
--- a/daemon/src/dbus/callmanager-introspec.xml
+++ b/daemon/src/dbus/callmanager-introspec.xml
@@ -819,14 +819,23 @@
           <arg type="s" name="accountID" direction="in"/>
           <arg type="s" name="buddySipUri" direction="in"/>
         </method>
-        <method name="setPresenceOnline" tp:name-for-bindings="setPresenceOnline">
+
+        <method name="unsubscribePresence" tp:name-for-bindings="unsubscribePresence">
+          <tp:added version="0.9.7"/>
+          <arg type="s" name="accountID" direction="in"/>
+          <arg type="s" name="buddySipUri" direction="in"/>
+        </method>
+
+       <method name="setPresenceOnline" tp:name-for-bindings="setPresenceOnline">
           <tp:added version="0.9.7"/>
           <arg type="s" name="accountID" direction="in"/>
         </method>
+
         <method name="setPresenceOffline" tp:name-for-bindings="setPresenceOffline">
           <tp:added version="0.9.7"/>
           <arg type="s" name="accountID" direction="in"/>
         </method>
+
         <signal name="newPresenceNotification" tp:name-for-bindings="newPresenceNotification">
           <arg type="s" name="buddyUri"/>
           <arg type="s" name="status"/>
diff --git a/daemon/src/dbus/callmanager.cpp b/daemon/src/dbus/callmanager.cpp
index 08c24e1be95f525eb84acf418df7f3300f5c7686..108fc356257836a44a2f77364abbe4f02f43bd86 100644
--- a/daemon/src/dbus/callmanager.cpp
+++ b/daemon/src/dbus/callmanager.cpp
@@ -403,18 +403,28 @@ CallManager::sendTextMessage(const std::string& callID, const std::string& messa
     ERROR("Could not send \"%s\" text message to %s since SFLphone daemon does not support it, please recompile with instant messaging support", message.c_str(), callID.c_str());
 #endif
 }
+
 void
 CallManager::subscribePresence(const std::string& accountID, const std::string& buddySipUri)
 {
   DEBUG("subscribePresence");
   Manager::instance().subscribePresence(accountID,buddySipUri);
 }
+
+void
+CallManager::unsubscribePresence(const std::string& accountID, const std::string& buddySipUri)
+{
+  DEBUG("unsubscribePresence");
+  Manager::instance().unsubscribePresence(accountID,buddySipUri);
+}
+
 void
 CallManager::setPresenceOnline(const std::string& accountID)
 {
   DEBUG("setPresenceOnline");
   Manager::instance().setPresenceOnline(accountID);
 }
+
 void
 CallManager::setPresenceOffline(const std::string& accountID)
 {
diff --git a/daemon/src/dbus/callmanager.h b/daemon/src/dbus/callmanager.h
index 0e7c94a59d4361d6304af4f1b0c1f5d0a7a739a5..9dc59048ee0ec6af642bb704fd54acbc32e7a785 100644
--- a/daemon/src/dbus/callmanager.h
+++ b/daemon/src/dbus/callmanager.h
@@ -129,6 +129,7 @@ class CallManager
 
         /* Presence subscription */
         void subscribePresence(const std::string& accountID, const std::string& buddySipUri);
+        void unsubscribePresence(const std::string& accountID, const std::string& buddySipUri);
         /* Presence Publication for IP2IP */
         void setPresenceOnline(const std::string& accountID);
         void setPresenceOffline(const std::string& accountID);
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index eb7b8fe8eaec6bc59567ea573d70cd8211b3f783..e25f509e6bc02d8164e4a2aa0581b6e600b128e8 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -85,8 +85,6 @@
 #include <sys/types.h> // mkdir(2)
 #include <sys/stat.h>  // mkdir(2)
 
-#include "sip/sipbuddy.h"
-
 ManagerImpl::ManagerImpl() :
     preferences(), voipPreferences(),
     hookPreference(),  audioPreference(), shortcutPreferences(),
@@ -2899,16 +2897,23 @@ void ManagerImpl::startAudioDriverStream()
 void ManagerImpl::subscribePresence(const std::string& accountID, const std::string& buddySipUri)
 {
     SIPAccount *account = Manager::instance().getSipAccount(accountID);
-    SIPBuddy *b = new SIPBuddy(buddySipUri, account);
-    b->subscribe();
+    account->addBuddy(buddySipUri);
 }
+
+void ManagerImpl::unsubscribePresence(const std::string& accountID, const std::string& buddySipUri)
+{
+    SIPAccount *account = Manager::instance().getSipAccount(accountID);
+    account->removeBuddy(buddySipUri);
+}
+
 void ManagerImpl::setPresenceOnline(const std::string& accountID)
 {
     SIPAccount *account = Manager::instance().getSipAccount(accountID);
-    account->notifyServers("open","");
+    account->notifyServerSubscription("open","");
 }
+
 void ManagerImpl::setPresenceOffline(const std::string& accountID)
 {
     SIPAccount *account = Manager::instance().getSipAccount(accountID);
-    account->notifyServers("close","");
+    account->notifyServerSubscription ("close","");
 }
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index 6bf5d2377369ca765d057943f4802fd3abed549d..03a994a3ad46164e9d52a0eeea85ecfdaa3e94af 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -1045,8 +1045,9 @@ class ManagerImpl {
          * Subscribe to buddySipUri for an accountID
          */
        void subscribePresence(const std::string& accountID, const std::string& buddySipUri);
+       void unsubscribePresence(const std::string& accountID, const std::string& buddySipUri);
 
-        /**
+       /**
          * push a presence for a account
          * only used for IP2IP accounts
          */
diff --git a/daemon/src/sip/presence_subscription.h b/daemon/src/sip/presence_subscription.h
index 2d71875af943ac08dc34ef57c409b4c723cb6cc4..32483b68cb5ce0a9d24fc5a554c5ba9bb1ee5ac7 100644
--- a/daemon/src/sip/presence_subscription.h
+++ b/daemon/src/sip/presence_subscription.h
@@ -8,6 +8,7 @@
 #ifndef SERVERPRESENCESUB_H
 #define	SERVERPRESENCESUB_H
 
+#include <string>
 #include "logger.h"
 #include <pjsip-simple/evsub.h>
 #include"pjsip-simple/presence.h"
@@ -22,17 +23,25 @@ public:
         , dlg(d)
         , expires (-1) {};
 
+    char            *remote;    /**< Remote URI.			    */
+    std::string	    accId;	    /**< Account ID.			    */
+
     void setExpires(int ms) {
         expires = ms;
     }
 
-    inline void notify(const std::string &newPresenceState, const std::string &newChannelState) {
-        DEBUG("notifying %s", remote);
+    /*bool operator==(const PresenceSubscription & s) const {
+        return (!(strcmp(remote,s.remote)));
+    }*/
+    bool match(PresenceSubscription * s){
+        // servers match if they have the same remote uri and the account ID.
+      return ((!(strcmp(remote,s->remote))) && (accId==s->accId));
+    }
+
 
-        pjsip_pres_status pres_status;
-        pjsip_tx_data *tdata;
+    inline void notify(const std::string &newPresenceState, const std::string &newChannelState) {
+        DEBUG("################################################notifying %s", remote);
 
-        pjsip_pres_get_status(sub, &pres_status);
 
         /* Only send NOTIFY once subscription is active. Some subscriptions
          * may still be in NULL (when app is adding a new buddy while in the
@@ -42,6 +51,11 @@ public:
          */
         if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_ACTIVE
                 /* && (pres_status.info[0].basic_open != getStatus()) */) {
+            DEBUG("Active");
+
+            pjsip_tx_data *tdata;
+            pjsip_pres_status pres_status;
+            pjsip_pres_get_status(sub, &pres_status);
 
             pres_status.info[0].basic_open = newPresenceState == "open"? true: false;
 
@@ -59,6 +73,10 @@ public:
                 pjsip_pres_send_request(sub, tdata);
             }
         }
+        else{
+           DEBUG("Inactive");
+
+        }
     }
 
     friend void pres_evsub_on_srv_state( pjsip_evsub *sub, pjsip_event *event);
@@ -67,10 +85,9 @@ public:
 private:
     NON_COPYABLE(PresenceSubscription);
     pjsip_evsub	    *sub;	    /**< The evsub.			    */
-    char            *remote;	    /**< Remote URI.			    */
-    std::string	    accId;	    /**< Account ID.			    */
     pjsip_dialog    *dlg;	    /**< Dialog.			    */
     int		     expires;	    /**< "expires" value in the request.    */
 };
 
+
 #endif	/* SERVERPRESENCESUB_H */
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 1bbcdcbfe9d36f895808d80d6d1c063212e8dd8f..9b0f3f9b9ef606ceae3c8222c751c3f3b65cddbc 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -47,10 +47,12 @@
 #include <algorithm>
 #include <cstdlib>
 
+
 #ifdef SFL_VIDEO
 #include "video/libav_utils.h"
 #endif
 
+
 const char * const SIPAccount::IP2IP_PROFILE = "IP2IP";
 const char * const SIPAccount::OVERRTP_STR = "overrtp";
 const char * const SIPAccount::SIPINFO_STR = "sipinfo";
@@ -111,7 +113,8 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , keepAliveTimer_()
     , keepAliveTimerActive_(false)
     , link_(SIPVoIPLink::instance())
-    , serverSubscriptions ()
+    , serverSubscriptions_ ()
+    , buddies_ ()
     , receivedParameter_("")
     , rPort_(-1)
     , via_addr_()
@@ -1206,6 +1209,39 @@ VoIPLink* SIPAccount::getVoIPLink()
     return link_;
 }
 
+
+/*
+ * Buddy list management
+ *
+ */
+void SIPAccount::addBuddy(const std::string& buddySipUri){
+    std::list< SIPBuddy *>::iterator buddyIt;
+
+    for (buddyIt = buddies_.begin(); buddyIt != buddies_.end(); buddyIt++)
+        if((*buddyIt)->getURI()==buddySipUri){
+            DEBUG("Buddy:%s exist in the list, Resubscribe.",buddySipUri.c_str());
+            (*buddyIt)->subscribe(); // The buddy won't add the subscription if it allready exists.
+            return;
+        }
+
+    DEBUG("New buddy subscription added.");
+    SIPBuddy *b = new SIPBuddy(buddySipUri, this);
+    b->subscribe();
+    buddies_.push_back(b);
+}
+
+void SIPAccount::removeBuddy(const std::string& buddySipUri){
+    std::list< SIPBuddy *>::iterator buddyIt;
+
+    for (buddyIt = buddies_.begin(); buddyIt != buddies_.end(); buddyIt++)
+        if((*buddyIt)->getURI()==buddySipUri){
+            DEBUG("Found buddy:%s in list. Unsubscribe.",buddySipUri.c_str());
+            (*buddyIt)->unsubscribe();
+            return;
+        }
+}
+
+
 bool SIPAccount::isIP2IP() const
 {
     return accountID_ == IP2IP_PROFILE;
@@ -1220,23 +1256,32 @@ bool SIPAccount::isIP2IP() const
 
 /* Presence : Method used to add serverSubscription to PresenceSubscription list in case of IP2IP accounts */
 void SIPAccount::addServerSubscription(PresenceSubscription *s) {
-    serverSubscriptions.push_back(s);
-    DEBUG("server subscription added");
+    std::list< PresenceSubscription *>::iterator serverIt;
+    for (serverIt = serverSubscriptions_.begin(); serverIt != serverSubscriptions_.end(); serverIt++)
+        if((*serverIt)->match(s)){
+            DEBUG("Server already subscribed. Replace it with a new fresh uas.");
+            serverSubscriptions_.remove(*serverIt);
+        }
+    DEBUG("Server subscription added.");
+    serverSubscriptions_.push_back(s);
 }
 
-/* Presence : Method used to remove serverSubscription to PresenceSubscription list in case of IP2IP accounts */
-void SIPAccount::removerServerSubscription(PresenceSubscription *s) {
-    serverSubscriptions.remove(s);
+/* Presence : Method used to remove serverSubscription to PresenceSubscription list in: case of IP2IP accounts */
+void SIPAccount::removeServerSubscription(PresenceSubscription *s) {
+    serverSubscriptions_.remove(s);
+    delete s;
     DEBUG("server subscription removed");
 }
 
 /* Presence : Method used to notify each serverSubscription of a new presencein case of IP2IP accounts */
-void SIPAccount::notifyServers(const std::string &newPresenceStatus, const std::string &newChannelStatus) {
+void SIPAccount::notifyServerSubscription(const std::string &newPresenceStatus, const std::string &newChannelStatus) {
     std::list< PresenceSubscription *>::iterator serverIt;
     DEBUG("iterating through servers");
-    for (serverIt = serverSubscriptions.begin(); serverIt != serverSubscriptions.end(); serverIt++)
+    for (serverIt = serverSubscriptions_.begin(); serverIt != serverSubscriptions_.end(); serverIt++)
         (*serverIt)->notify(newPresenceStatus, newChannelStatus);
 }
+
+
 /*
  * Presence Management for IP2IP accounts
  *
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index af031db29efbc5a701f95cd5059d80c1bd9fe995..1df0b17153dafc7f80374fbd4b07712bd301f927 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -43,6 +43,7 @@
 #include "pjsip-ua/sip_regc.h"
 #include "noncopyable.h"
 
+#include "sipbuddy.h"
 #include "presence_subscription.h"
 typedef std::vector<pj_ssl_cipher> CipherArray;
 
@@ -516,12 +517,14 @@ class SIPAccount : public Account {
         /* Returns true if the username and/or hostname match this account */
         bool matches(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
 
-        //void addBuddy(const std::string &uri, bool subscribe);
-        //void removeBuddy(const std::string &uri);
+        //int getBuddy(const std::string& buddySipUri, SIPBuddy *b);
+        void addBuddy(const std::string& buddySipUri);
+        void removeBuddy(const std::string& buddySipUri);
         void addServerSubscription(PresenceSubscription *s);
-        void removerServerSubscription(PresenceSubscription *s);
-        void notifyServers(const std::string &newPresenceStatus, const std::string &newChannelStatus);
-    private:
+        void removeServerSubscription(PresenceSubscription *s);
+        void notifyServerSubscription(const std::string &newPresenceStatus, const std::string &newChannelStatus);
+        bool compareServerSubscription(PresenceSubscription *first, PresenceSubscription *second);
+private:
         NON_COPYABLE(SIPAccount);
 
         bool fullMatch(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
@@ -768,11 +771,15 @@ class SIPAccount : public Account {
          */
         pjsip_host_port via_addr_;
 
+         /**
+         * server subscription
+         */
+        std::list< PresenceSubscription *> serverSubscriptions_;
 
         /**
-         * Server subscription (added by ELOI)
+         * buddies
          */
-        std::list< PresenceSubscription *> serverSubscriptions;
+        std::list< SIPBuddy *> buddies_;
 
 };
 
diff --git a/daemon/src/sip/sipbuddy.cpp b/daemon/src/sip/sipbuddy.cpp
index 2316b4e352e5209ee8165ddc44be54046de820f5..6b383125ab46e96d36eb07ae645824955a9c8e00 100644
--- a/daemon/src/sip/sipbuddy.cpp
+++ b/daemon/src/sip/sipbuddy.cpp
@@ -367,16 +367,17 @@ pj_status_t SIPBuddy::updatePresence() {
         pj_status_t retStatus;
 
         if (sub == NULL) {
+            DEBUG("Buddy already unsubscribed sub=NULL.");
             return PJ_SUCCESS;
         }
 
         if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
+            DEBUG("Buddy already unsubscribed sub=TERMINATED.");
             pjsip_evsub_terminate(sub, PJ_FALSE); // = NULL;
             return PJ_SUCCESS;
         }
 
         DEBUG("Buddy %s: unsubscribing..", uri.ptr);
-
         retStatus = pjsip_pres_initiate(sub, 300, &tdata);
         if (retStatus == PJ_SUCCESS) {
             //	pjsua_process_msg_data(tdata, NULL);
@@ -554,3 +555,8 @@ void SIPBuddy::unsubscribe() {
     monitor = false;
     updatePresence();
 }
+
+bool SIPBuddy::match(SIPBuddy *b){
+    //return !(strcmp(b->getURI(),getURI()));
+    return (b->getURI()==getURI());
+}
diff --git a/daemon/src/sip/sipbuddy.h b/daemon/src/sip/sipbuddy.h
index 0a385c9c7921e78751d5ac9ce55b710abc4d03ca..5035ade267973a92905195898eb1196f0abb259d 100644
--- a/daemon/src/sip/sipbuddy.h
+++ b/daemon/src/sip/sipbuddy.h
@@ -61,6 +61,7 @@ class SIPBuddy {
 public:
     SIPBuddy(const std::string &uri, SIPAccount *acc);
     ~SIPBuddy();
+    bool match(SIPBuddy *b);
     void subscribe();
     void unsubscribe();
     bool isSubscribed();
diff --git a/daemon/src/sip/sipvoip_pres.cpp b/daemon/src/sip/sipvoip_pres.cpp
index 3c558613bcca6fd3269eace5c8248aa732901126..3f5d650c797d2b95b12765f4ada1140c6c7be9ac 100644
--- a/daemon/src/sip/sipvoip_pres.cpp
+++ b/daemon/src/sip/sipvoip_pres.cpp
@@ -29,7 +29,7 @@
  *  as that of the covered work.
  */
 
-#ifdef HAVE_CONFIG_H
+#ifdef have_config_h
 #include "config.h"
 #endif
 
@@ -71,13 +71,11 @@ void pres_evsub_on_srv_state(pjsip_evsub *sub, pjsip_event *event) {
 //    PJSUA_LOCK(); /* ebail : FIXME figure out if locking is necessary or not */
     presenceSub = (PresenceSubscription *) pjsip_evsub_get_mod_data(sub,
             ((SIPVoIPLink*) (acc->getVoIPLink()))->getModId() /*my_mod_pres.id*/);
-    WARN("Presence subscription to %s is %s", presenceSub->remote, pjsip_evsub_get_state_name(sub));
+    WARN("Presence server subscription to %s is %s", presenceSub->remote, pjsip_evsub_get_state_name(sub));
 
     if (presenceSub) {
         pjsip_evsub_state state;
 
-        WARN("Server subscription to %s is %s", presenceSub->remote, pjsip_evsub_get_state_name(sub));
-
         state = pjsip_evsub_get_state(sub);
 
         /*  ebail : FIXME check if ths code is usefull */
@@ -95,6 +93,7 @@ void pres_evsub_on_srv_state(pjsip_evsub *sub, pjsip_event *event) {
         if (state == PJSIP_EVSUB_STATE_TERMINATED) {
             pjsip_evsub_set_mod_data(sub, ((SIPVoIPLink*) (acc->getVoIPLink()))->getModId(), NULL);
 //	    pj_list_erase(uapres);
+            acc->removeServerSubscription(presenceSub);
         }
     }
 //    PJSUA_UNLOCK(); /* ebail : FIXME figure out if unlocking is necessary or not */
@@ -194,6 +193,7 @@ pj_bool_t my_pres_on_rx_request(pjsip_rx_data *rdata) {
 //    pjsip_evsub_add_header(sub, &acc->cfg.sub_hdr_list);
     int modId = ((SIPVoIPLink*) (acc->getVoIPLink()))->getModId();
     pjsip_evsub_set_mod_data(sub, modId/*my_mod_pres.id*/, presenceSub);
+    //DEBUG("***************** presenceSub.name:%s",sub->mod_name);
     acc->addServerSubscription(presenceSub);
     /* Add server subscription to the list: */
 //    pj_list_push_back(&pjsua_var.acc[acc_id].pres_srv_list, uapres);
@@ -293,7 +293,6 @@ pj_bool_t my_pres_on_rx_request(pjsip_rx_data *rdata) {
             tdata->msg->body = body;
         }
         // process_msg_data
-
         status = pjsip_pres_send_request(sub, tdata);
     }
 
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 860db2af03e29dfbbbb6f2db6f2d721f770bedb4..a5b85e7130e4ca5b1d61909795513fbcccf471d6 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -2313,7 +2313,7 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
         return;
 
     // Reference: http://www.cs.columbia.edu/~hgs/rtp/faq.html#ports
-    // We only want to set ports to new values if they haven't been set
+      // We only want to set ports to new values if they haven't been set
     if (call->getLocalAudioPort() == 0) {
         const unsigned callLocalAudioPort = getRandomEvenNumber(16384, 32766);
         call->setLocalAudioPort(callLocalAudioPort);
@@ -2344,7 +2344,7 @@ void SIPVoIPLink::setPresenceState(const std::string &accId, const std::string&
 #else
     SIPAccount *acc = Manager::instance().getSipAccount(accId);
     /*no need of channelStatte. We put it to NULL */
-    acc->notifyServers(presenceState, NULL);
+    acc->notifyServerSubscription(presenceState, NULL);
 #endif
 }
 std::string SIPVoIPLink::getPresenceState() {