diff --git a/src/contact.cpp b/src/contact.cpp
index 3ba5bd688d86c4ec04336ba524e66bdfe3104cf4..f2cce1d60cacc2f49d87c2db111b77d378a704ff 100644
--- a/src/contact.cpp
+++ b/src/contact.cpp
@@ -403,20 +403,20 @@ void Contact::replaceDPointer(Contact* c)
 
 bool Contact::operator==(Contact* other)
 {
-   return this->d == other->d;
+   return other && this->d == other->d;
 }
 
 bool Contact::operator==(const Contact* other) const
 {
-   return this->d == other->d;
+   return other && this->d == other->d;
 }
 
 bool Contact::operator==(Contact& other)
 {
-   return this->d == other.d;
+   return &other && this->d == other.d;
 }
 
 bool Contact::operator==(const Contact& other) const
 {
-   return this->d == other.d;
+   return &other && this->d == other.d;
 }
diff --git a/src/phonedirectorymodel.cpp b/src/phonedirectorymodel.cpp
index 081de6527e3bc7a203c9b56bba6625a7a5a1d7ec..c1155eb04386139a66ea89cb2d581d0bb2f46a01 100644
--- a/src/phonedirectorymodel.cpp
+++ b/src/phonedirectorymodel.cpp
@@ -293,15 +293,21 @@ void PhoneDirectoryModel::setAccount(PhoneNumber* number, Account* account ) {
    if (!hasAtSign) {
       NumberWrapper* wrap = m_hDirectory[strippedUri];
 
-      //Check if a compatible number already exist
-      if (wrap && wrap->numbers.indexOf(number) == -1) {
-         qDebug() << "TODO";
-      }
-
       //Let make sure none is created in the future for nothing
       if (!wrap) {
+         //It wont be a duplicate as none exist for this URI
          wrap = new NumberWrapper();
          m_hDirectory[strippedUri+'@'+account->hostname()] = wrap;
+
+      }
+      else {
+         //After all this, it is possible the number is now a duplicate
+         foreach(PhoneNumber* n, wrap->numbers) {
+            if (n != number && n->account() && n->account() == number->account()) {
+               //qDebug() << "DUPLICATE";
+               number->merge(n);
+            }
+         }
       }
       wrap->numbers << number;
 
@@ -351,9 +357,38 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, const QString& t
  */
 PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Account* account, const QString& type)
 {
-   if (!account)
-      return getNumber(uri,type);
+   return getNumber(uri,nullptr,account,type);
+}
+
+PhoneNumber* PhoneDirectoryModel::fillDetails(NumberWrapper* wrap, Account* account, Contact* contact, const QString& type,bool& hasContact)
+{
+   if (wrap) {
+      foreach(PhoneNumber* number, wrap->numbers) {
+         //Not perfect, but better than ignoring the high probabilities
+         //TODO only do it is hostname match
+         if ((!contact) && account && !number->account())
+            setAccount(number,account);
+
+         //Set a type, this has low probabilities of being invalid
+         if ((!number->hasType()) && (!type.isEmpty())) {
+            number->setCategory(NumberCategoryModel::instance()->getCategory(type));
+         }
+
+         //If the contact has not already been set and account match, set it
+         if (account && account == number->account() && contact && !((*contact) == number->contact()))
+            number->setContact(contact);
+
+         //We already have enough information to confirm the choice
+         if (contact && number->contact() &&((contact->uid()) == number->contact()->uid()))
+            return number;
+         hasContact |= number->contact()!= nullptr;
+      }
+   }
+   return nullptr;
+}
 
+PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact, Account* account, const QString& type)
+{
    const URI strippedUri(uri);
 
    //Try to use a PhoneNumber with a contact when possible, work only after the
@@ -368,64 +403,77 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Account* account
    const bool hasAtSign = strippedUri.hasHostname();
 
    //Try to see if there is a better candidate with a suffix (LAN only)
-   if ( !hasAtSign ) {
+   if ( !hasAtSign && account ) {
       //Append the account hostname
       wrap2 = m_hDirectory[strippedUri+'@'+account->hostname()];
    }
 
-   if (wrap) {
-      foreach(PhoneNumber* number, wrap->numbers) {
-         //Not perfect, but better than ignoring the high probabilities
-         //TODO only do it is hostname match
-         if (!number->account())
-            setAccount(number,account);
-         if ((!number->hasType()) && (!type.isEmpty())) {
-            number->setCategory(NumberCategoryModel::instance()->getCategory(type));
+   //Check
+   PhoneNumber* confirmedCandidate = fillDetails(wrap,account,contact,type,hasContact);
+
+   //URIs can be represented in multiple way, check if a more verbose version
+   //already exist
+   PhoneNumber* confirmedCandidate2 = fillDetails(wrap2,account,contact,type,hasContact);
+
+   PhoneNumber* confirmedCandidate3 = nullptr;
+
+   //Else, try to see if the hostname correspond to the account and flush it
+   //This have to be done after the parent if as the above give "better"
+   //results. It cannot be merged with wrap2 as this check only work if the
+   //candidate has an account.
+   if (hasAtSign && account && strippedUri.hostname() == account->hostname()) {
+     wrap2 = m_hDirectory[strippedUri.userinfo()];
+     if (wrap2) {
+         foreach(PhoneNumber* number, wrap2->numbers) {
+            if (number->account() == account) {
+               if (contact && ((!number->contact()) || (contact->uid() == number->contact()->uid())))
+                  number->setContact(contact);
+               //TODO add alternate URI
+               confirmedCandidate3 = number;
+               break;
+            }
          }
-         hasContact |= number->contact()!= nullptr;
-      }
+     }
    }
 
-   //If the second candidate has a contact, choose it (LAN only)
-   if (wrap2 && (!hasContact)) {
-      foreach(PhoneNumber* number, wrap2->numbers) {
-         //Not perfect, but better than ignoring the high probabilities
-         //TODO only do it is hostname match
-         if (!number->account())
-            setAccount(number,account);
-         if ((!number->hasType()) && (!type.isEmpty())) {
-            number->setCategory(NumberCategoryModel::instance()->getCategory(type));
-         }
-         if (number->contact()) {
-            return number;
-         }
-      }
+   //qDebug() << "-----CANDID" << confirmedCandidate3 << confirmedCandidate << confirmedCandidate2;
+   //If multiple PhoneNumber are confirmed, then they are the same, merge them
+   if (confirmedCandidate3 && (confirmedCandidate || confirmedCandidate2)) {
+      confirmedCandidate3->merge(confirmedCandidate?confirmedCandidate:confirmedCandidate2);
    }
-
-   //Do the opposite, the URI has a suffix, try without
-   if ((!wrap) && account && hasAtSign ) {
-      const QString prefixOnly = strippedUri.userinfo();
-      NumberWrapper* potentialwrap = m_hDirectory[prefixOnly];
-      if (potentialwrap) {
-         foreach(PhoneNumber* number, potentialwrap->numbers) {
-            if (number->account() == account)
-               return number;
-         }
-      }
+   else if (confirmedCandidate && confirmedCandidate2) {
+      if (confirmedCandidate->contact() && !confirmedCandidate2->contact())
+         confirmedCandidate2->merge(confirmedCandidate);
+      else if (confirmedCandidate2->contact() && !confirmedCandidate->contact())
+         confirmedCandidate->merge(confirmedCandidate2);
    }
 
+
+   if (confirmedCandidate2)
+      return confirmedCandidate2;
+   if (confirmedCandidate)
+      return confirmedCandidate;
+   if (confirmedCandidate3)
+      return confirmedCandidate3;
+
    //No better candidates were found than the original assumption, use it
    if (wrap) {
       foreach(PhoneNumber* number, wrap->numbers) {
-         if ((!account) || number->account() == account)
+         if (((!account) || number->account() == account) && ((!contact) || ((*contact) == number->contact()))) {
+            if (contact && (!number->contact() || (contact->uid() == number->contact()->uid())))
+               number->setContact(contact);
             return number;
+         }
       }
    }
 
    //Create the number
+   //qDebug() << "CREATE" << strippedUri << account << contact;
    PhoneNumber* number = new PhoneNumber(strippedUri,NumberCategoryModel::instance()->getCategory(type));
    number->setAccount(account);
    number->setIndex( m_lNumbers.size());
+   if (contact)
+      number->setContact(contact);
    m_lNumbers << number;
    connect(number,SIGNAL(callAdded(Call*)),this,SLOT(slotCallAdded(Call*)));
    connect(number,SIGNAL(changed()),this,SLOT(slotChanged()));
@@ -434,7 +482,7 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Account* account
       m_hDirectory[strippedUri] = wrap;
 
       //Also add its alternative URI, it should be safe to do
-      if ( !hasAtSign && !account->hostname().isEmpty() ) {
+      if ( !hasAtSign && account && !account->hostname().isEmpty() ) {
          if (!wrap2) {
             wrap2 = new NumberWrapper();
             m_hDirectory[strippedUri+'@'+account->hostname()] = wrap2;
@@ -446,53 +494,7 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Account* account
    }
    wrap->numbers << number;
    emit layoutChanged();
-   return number;
-}
 
-PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact, Account* account, const QString& type)
-{
-   if (!contact)
-      return getNumber(uri,account,type);
-
-   const URI strippedUri(uri);
-
-   //See if the number is already loaded
-   NumberWrapper* wrap = m_hDirectory[strippedUri];
-   if (wrap) {
-      //TODO find something better, it is prone to collisions
-      foreach(PhoneNumber* number, wrap->numbers) {
-         if (!number->contact()) {
-            if (!number->account())
-               setAccount(number,account);
-            number->setContact(contact);
-         }
-      }
-      foreach(PhoneNumber* number, wrap->numbers) {
-         if ((!number->hasType()) && (!type.isEmpty())) {
-            number->setCategory(NumberCategoryModel::instance()->getCategory(type));
-         }
-         //Use the operator== check to avoid issues with placeholders
-         if (((!contact) || (number->contact() && (*number->contact()) == (*contact)))
-            && ((!account) || number->account() == account))
-            return number;
-      }
-   }
-
-   //Create the number
-   PhoneNumber* number = new PhoneNumber(strippedUri,NumberCategoryModel::instance()->getCategory(type));
-   number->setAccount(account);
-   number->setContact(contact);
-   number->setIndex(m_lNumbers.size());
-   m_lNumbers << number;
-   connect(number,SIGNAL(callAdded(Call*)),this,SLOT(slotCallAdded(Call*)));
-   connect(number,SIGNAL(changed()),this,SLOT(slotChanged()));
-   if (!wrap) {
-      wrap = new NumberWrapper();
-      m_hDirectory[strippedUri] = wrap;
-      m_hSortedNumbers[strippedUri] = wrap;
-   }
-   wrap->numbers << number;
-   emit layoutChanged();
    return number;
 }
 
diff --git a/src/phonedirectorymodel.h b/src/phonedirectorymodel.h
index 9bfdef7482e26b7b5ff0eeb8eb01cefdfbab00c2..6664faa7a025277b5920c26bfedc36982ba09aef 100644
--- a/src/phonedirectorymodel.h
+++ b/src/phonedirectorymodel.h
@@ -116,6 +116,7 @@ private:
    //Helpers
    void indexNumber(PhoneNumber* number, const QStringList& names   );
    void setAccount (PhoneNumber* number,       Account*     account );
+   PhoneNumber* fillDetails(NumberWrapper* wrap, Account* account, Contact* contact, const QString& type, bool& hasContact);
 
    //Singleton
    static PhoneDirectoryModel* m_spInstance;
diff --git a/src/phonenumber.cpp b/src/phonenumber.cpp
index ad3c58d3d744f24c1400807f2023154fae08cccb..ca7c91a42c9e3a1043acc9070813d7384284e7cf 100644
--- a/src/phonenumber.cpp
+++ b/src/phonenumber.cpp
@@ -521,22 +521,22 @@ bool PhoneNumber::merge(PhoneNumber* other)
 
 bool PhoneNumber::operator==(PhoneNumber* other)
 {
-   return this->d == other->d;
+   return other && this->d == other->d;
 }
 
 bool PhoneNumber::operator==(const PhoneNumber* other) const
 {
-   return this->d == other->d;
+   return other && this->d == other->d;
 }
 
 bool PhoneNumber::operator==(PhoneNumber& other)
 {
-   return this->d == other.d;
+   return &other && this->d == other.d;
 }
 
 bool PhoneNumber::operator==(const PhoneNumber& other) const
 {
-   return this->d == other.d;
+   return &other && this->d == other.d;
 }
 
 /************************************************************************************
diff --git a/src/uri.cpp b/src/uri.cpp
index b2e718f36c39fb64877a316ec34de54bc33989ee..d881a7ae6165a25a13913ea9bcc73b474c954e2f 100644
--- a/src/uri.cpp
+++ b/src/uri.cpp
@@ -27,7 +27,7 @@ URI::URI(const QString& other):QString()
 }
 
 URI::URI(const URI& o):QString(),m_Parsed(o.m_Parsed),m_Hostname(o.m_Hostname),
-   m_HeaderType(o.m_HeaderType),m_Userinfo(o.m_Userinfo)
+   m_HeaderType(o.m_HeaderType),m_Userinfo(o.m_Userinfo),m_Stripped(o.m_Stripped)
 {
    (*static_cast<QString*>(this)) = o.m_Stripped;
 }