diff --git a/src/account.cpp b/src/account.cpp
index 47d6c73bd0e3edb75d137a8db7b9bf0aca3b5991..15f935fa83a31546e520f9295afe62f82f4e0fdb 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -885,6 +885,26 @@ QVariant Account::roleData(int role) const
 #undef CAST
 
 
+bool Account::supportScheme( URI::SchemeType type )
+{
+   switch(type) {
+      case URI::SchemeType::NONE :
+         return true;
+      case URI::SchemeType::SIP  :
+      case URI::SchemeType::SIPS :
+         if (protocol() == Account::Protocol::SIP)
+            return true;
+      case URI::SchemeType::IAX  :
+         if (protocol() == Account::Protocol::IAX)
+            return true;
+      case URI::SchemeType::RING :
+         if (protocol() == Account::Protocol::RING)
+            return true;
+   }
+   return false;
+}
+
+
 /*****************************************************************************
  *                                                                           *
  *                                  Setters                                  *
diff --git a/src/account.h b/src/account.h
index 6a5c998a2ce6c1ba658c035270fea902e7afc309..f23a355065d2223e57e4e628c2ae6d9a900ae743 100644
--- a/src/account.h
+++ b/src/account.h
@@ -29,6 +29,7 @@ class QString;
 //Ring
 #include "keyexchangemodel.h"
 #include "tlsmethodmodel.h"
+#include "uri.h"
 #include "typedefs.h"
 class CredentialModel        ;
 class RingToneModel          ;
@@ -295,7 +296,9 @@ class LIB_EXPORT Account : public QObject {
       RegistrationState  registrationState () const;
       Protocol               protocol      () const;
       KeyExchangeModel::Type keyExchange   () const;
-      QVariant roleData            (int role) const;
+
+      Q_INVOKABLE QVariant roleData ( int role             ) const;
+      Q_INVOKABLE bool supportScheme( URI::SchemeType type )      ;
 
       //Setters
       void setId                            (const QByteArray& id   );
diff --git a/src/availableaccountmodel.cpp b/src/availableaccountmodel.cpp
index 4b59206c6739ba811cf9a1602d29dd01e906cee4..e37a1fdb54b29afff45e5a9e545f6cec9fc27592 100644
--- a/src/availableaccountmodel.cpp
+++ b/src/availableaccountmodel.cpp
@@ -26,6 +26,8 @@
 
 //Ring
 #include "private/accountmodel_p.h"
+#include "contactmethod.h"
+#include "uri.h"
 
 class AvailableAccountModelPrivate : public QObject
 {
@@ -38,7 +40,7 @@ public:
    static AvailableAccountModel* m_spInstance     ;
 
    static void     setPriorAccount       ( const Account* account );
-   static Account* firstRegisteredAccount(                        );
+   static Account* firstRegisteredAccount( URI::SchemeType type = URI::SchemeType::NONE );
 
    AvailableAccountModel* q_ptr;
 
@@ -94,14 +96,19 @@ bool AvailableAccountModel::filterAcceptsRow(int source_row, const QModelIndex&
 
 
 ///Return the current account
-Account* AvailableAccountModel::currentDefaultAccount()
+Account* AvailableAccountModel::currentDefaultAccount(ContactMethod* method)
 {
    Account* priorAccount = AvailableAccountModelPrivate::m_spPriorAccount;
-   if(priorAccount && priorAccount->registrationState() == Account::RegistrationState::READY && priorAccount->isEnabled() ) {
+   URI::SchemeType type = (!method) ? URI::SchemeType::NONE : method->uri().schemeType();
+   if(priorAccount
+     && priorAccount->registrationState() == Account::RegistrationState::READY
+     && priorAccount->isEnabled()
+     && (priorAccount->supportScheme(type))
+   ) {
       return priorAccount;
    }
    else {
-      Account* a = AvailableAccountModelPrivate::firstRegisteredAccount();
+      Account* a = AvailableAccountModelPrivate::firstRegisteredAccount(type);
       if (!a)
          a = AccountModel::instance()->getById(DRing::Account::ProtocolNames::IP2IP);
 
@@ -127,10 +134,14 @@ void AvailableAccountModelPrivate::setPriorAccount(const Account* account) {
 }
 
 ///Get the first registerred account (default account)
-Account* AvailableAccountModelPrivate::firstRegisteredAccount()
+Account* AvailableAccountModelPrivate::firstRegisteredAccount(URI::SchemeType type)
 {
    for (Account* current : AccountModel::instance()->d_ptr->m_lAccounts) {
-      if(current && current->registrationState() == Account::RegistrationState::READY && current->isEnabled())
+      if(current
+        && current->registrationState() == Account::RegistrationState::READY
+        && current->isEnabled()
+        && current->supportScheme(type)
+      )
          return current;
    }
    return nullptr;
diff --git a/src/availableaccountmodel.h b/src/availableaccountmodel.h
index 2f4b20fc4e25a323b68e53d4e7c4fa0ec5981443..d71c56f3c1ba7d34b27bc94986852e8f473c7b37 100644
--- a/src/availableaccountmodel.h
+++ b/src/availableaccountmodel.h
@@ -49,7 +49,7 @@ public:
    QItemSelectionModel* selectionModel() const;
 
    //Getter
-   static Account* currentDefaultAccount();
+   static Account* currentDefaultAccount(ContactMethod* method = nullptr);
 
    //Singleton
    static AvailableAccountModel* instance();
diff --git a/src/call.cpp b/src/call.cpp
index 543c99d1609cc9a4a09bd8c6c9ab5a728c558f96..b1eeaa24f5e1d57232453ca31f446d75e56f5d46 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -1250,7 +1250,7 @@ void CallPrivate::call()
    qDebug() << "account = " << m_Account;
    if(!m_Account) {
       qDebug() << "Account is not set, taking the first registered.";
-      m_Account = AvailableAccountModel::currentDefaultAccount();
+      m_Account = AvailableAccountModel::currentDefaultAccount(m_pDialNumber);
    }
    //Calls to empty URI should not be allowed, dring will go crazy
    if ((!m_pDialNumber) || m_pDialNumber->uri().isEmpty()) {
@@ -1276,6 +1276,14 @@ void CallPrivate::call()
       //Warning: m_pDialNumber can become nullptr when linking directly
       m_DringId = callManager.placeCall(m_Account->id(), m_pDialNumber->uri());
 
+      //This can happen when the daemon cannot allocate memory
+      if (m_DringId.isEmpty()) {
+         changeCurrentState(Call::State::FAILURE);
+         qWarning() << "Creating the call to" << m_pDialNumber->uri() << "failed";
+         m_DringId = "FAILED"; //TODO once the ABORTED state is implemented, use it
+         return;
+      }
+
       CallModel::instance()->registerCall(q_ptr);
       setObjectName("Call:"+m_DringId);
 
diff --git a/src/callmodel.cpp b/src/callmodel.cpp
index ca433c19c1ca320a1ff1c072cf3b9aa2836875ba..73f8f578c490f6d48499346a54ca99f294321c75 100644
--- a/src/callmodel.cpp
+++ b/src/callmodel.cpp
@@ -1037,8 +1037,12 @@ void CallModelPrivate::slotCallStateChanged(const QString& callID, const QString
 
    //Add to history
    if (call->lifeCycleState() == Call::LifeCycleState::FINISHED) {
-      //HistoryModel::instance()->add(call);
-      //FIXME check all collection with a "::ADD" filter and add the call
+      if (!call->collection()) {
+         foreach (CollectionInterface* backend, HistoryModel::instance()->collections(CollectionInterface::ADD)) {
+            if (backend->editor<Call>()->addNew(call))
+               call->setCollection(backend);
+         }
+      }
    }
 
    emit q_ptr->callStateChanged(call,previousState);
diff --git a/src/collectionmanagerinterface.h b/src/collectionmanagerinterface.h
index 626ed06437ad53f5d43bbab42c4a87c09e2a9797..7611d2cd03f8be47061c78f8dc74966853ecbb52 100644
--- a/src/collectionmanagerinterface.h
+++ b/src/collectionmanagerinterface.h
@@ -95,12 +95,12 @@ public:
    T2* addBackend(Ts... args, const LoadOptions options = LoadOptions::NONE);
 
    /// Do this manager have active collections
-   virtual bool hasEnabledCollections () const final;
-   virtual bool hasCollections        () const final;
+   virtual bool hasEnabledCollections (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final;
+   virtual bool hasCollections        (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final;
 
    /// List all Collections
-   virtual const QVector< CollectionInterface* > collections       () const final;
-   virtual const QVector< CollectionInterface* > enabledCollections() const final;
+   virtual const QVector< CollectionInterface* > collections       (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final;
+   virtual const QVector< CollectionInterface* > enabledCollections(CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final;
 
    ///Enable / disable a collection
    virtual bool enableBackend( CollectionInterface*  collection, bool enabled) final;
diff --git a/src/collectionmanagerinterface.hpp b/src/collectionmanagerinterface.hpp
index 397677682477c78f188657f200334c10dc1bf398..d9e0831492e0aec49784cec9d0876413b632fbcd 100644
--- a/src/collectionmanagerinterface.hpp
+++ b/src/collectionmanagerinterface.hpp
@@ -33,6 +33,7 @@ public:
    CollectionManagerInterface<T>*  i_ptr;
 
    CollectionMediator<T>* itemMediator() const;
+   inline const QVector< CollectionInterface* > filterCollections(QVector< CollectionInterface* > in, CollectionInterface::SupportedFeatures features) const;
 };
 
 template<class T>
@@ -80,28 +81,70 @@ CollectionManagerInterface<T>::CollectionManagerInterface(QAbstractItemModel* se
 }
 
 template<class T>
-const QVector< CollectionInterface* > CollectionManagerInterface<T>::collections() const
+const QVector< CollectionInterface* > CollectionManagerInterfacePrivate<T>::filterCollections(QVector< CollectionInterface* > in, CollectionInterface::SupportedFeatures features) const
 {
-   return d_ptr->m_lCollections;
+   QVector< CollectionInterface* > out;
+   for (CollectionInterface* col : in) {
+      if ((col->supportedFeatures() & features) == features)
+         out << col;
+   }
+   return out;
 }
 
+/**
+ * Return the list of all collections associated with this manager
+ * @param features An optional set of required features
+ * @note Please note that this method complexity is O(N) when "features" is set
+ */
 template<class T>
-const QVector< CollectionInterface* > CollectionManagerInterface<T>::enabledCollections() const
+const QVector< CollectionInterface* > CollectionManagerInterface<T>::collections(CollectionInterface::SupportedFeatures features) const
 {
-   return d_ptr->m_lEnabledCollections;
+   if (features != CollectionInterface::SupportedFeatures::NONE)
+      return d_ptr->filterCollections(d_ptr->m_lCollections, features);
+   else
+      return d_ptr->m_lCollections;
 }
 
-/// Do this manager have active collections
+/**
+ * Return the list of all enabled collections associated with this manager
+ * @param features An optional set of required features
+ * @note Please note that this method complexity is O(N) when "features" is set
+ */
 template<class T>
-bool CollectionManagerInterface<T>::hasEnabledCollections() const
+const QVector< CollectionInterface* > CollectionManagerInterface<T>::enabledCollections(CollectionInterface::SupportedFeatures features) const
 {
-   return d_ptr->m_lEnabledCollections.size();
+   if (features != CollectionInterface::SupportedFeatures::NONE)
+      return d_ptr->filterCollections(d_ptr->m_lEnabledCollections, features);
+   else
+      return d_ptr->m_lEnabledCollections;
 }
 
+/**
+ * Return if the manager has enabled collections
+ * @param features An optional set of required features
+ * @note Please note that this method complexity is O(N) when "features" is set
+ */
 template<class T>
-bool CollectionManagerInterface<T>::hasCollections() const
+bool CollectionManagerInterface<T>::hasEnabledCollections(CollectionInterface::SupportedFeatures features) const
 {
-   return d_ptr->m_lCollections.size();
+   if (features != CollectionInterface::SupportedFeatures::NONE)
+      return d_ptr->filterCollections(d_ptr->m_lEnabledCollections, features).size();
+   else
+      return d_ptr->m_lEnabledCollections.size();
+}
+
+/**
+ * Return the list of all collections associated with this manager
+ * @param features An optional set of required features
+ * @note Please note that this method complexity is O(N) when "features" is set
+ */
+template<class T>
+bool CollectionManagerInterface<T>::hasCollections(CollectionInterface::SupportedFeatures features) const
+{
+   if (features != CollectionInterface::SupportedFeatures::NONE)
+      return d_ptr->filterCollections(d_ptr->m_lCollections, features).size();
+   else
+      return d_ptr->m_lCollections.size();
 }
 
 template<class T>
diff --git a/src/historymodel.cpp b/src/historymodel.cpp
index a58fa9b52abe21bc022794f30f37b22bb2a00c04..fb76009911146e3de3fbfda6aa0c0144a309dad5 100644
--- a/src/historymodel.cpp
+++ b/src/historymodel.cpp
@@ -325,18 +325,17 @@ void HistoryModelPrivate::add(Call* call)
    LastUsedNumberModel::instance()->addCall(call);
    emit q_ptr->historyChanged();
 
+   /*
    // Loop until it find a compatible backend
    //HACK only support a single active history backend
    if (!call->collection()) {
-      foreach (CollectionInterface* backend, q_ptr->collections()) {
-         if (backend->supportedFeatures() & CollectionInterface::ADD) {
-            if (backend->editor<Call>()->addNew(call)) {
-               call->setCollection(backend);
-               break;
-            }
+      foreach (CollectionInterface* backend, q_ptr->collections(CollectionInterface::ADD)) {
+         if (backend->editor<Call>()->addNew(call)) {
+            call->setCollection(backend);
+            break;
          }
       }
-   }
+   }*/
 }
 
 ///Set if the history has a limit
diff --git a/src/uri.cpp b/src/uri.cpp
index 943129e5158c2de11affc44d914a15d4da131f51..b745bd63a2d9be594e20db6f7fd23fccb932d463 100644
--- a/src/uri.cpp
+++ b/src/uri.cpp
@@ -131,9 +131,20 @@ bool URI::hasHostname() const
    return !d_ptr->m_Hostname.isEmpty();
 }
 
+/**
+ * Return the URI SchemeType
+ */
+URI::SchemeType URI::schemeType() const
+{
+   if (!d_ptr->m_Parsed)
+      const_cast<URI*>(this)->d_ptr->parse();
+   return d_ptr->m_HeaderType;
+}
+
 ///Keep a cache of the values to avoid re-parsing them
 void URIPrivate::parse()
 {
+   //TODO DHT hashes have 40 chars or 45 with sips:/ring: is set
    if (q_ptr->indexOf('@') != -1) {
       const QStringList split = q_ptr->split('@');
       m_Hostname = split[1];//split[1].left(split[1].size())
diff --git a/src/uri.h b/src/uri.h
index d4119c7d223ac0bb842d6b2d6a074637407d6e38..f3353b4757805085b406784dd2a8d68a12810016 100644
--- a/src/uri.h
+++ b/src/uri.h
@@ -85,6 +85,7 @@ public:
       SIP  ,
       SIPS ,
       IAX  ,
+      RING ,
    };
 
    ///Strings associated with SchemeType
@@ -93,6 +94,7 @@ public:
       /*SIP  = */ "sip:" ,
       /*SIPS = */ "sips:",
       /*IAX  = */ "iax:" ,
+      /*RING = */ "ring:",
    };
 
    /**
@@ -111,10 +113,11 @@ public:
       sctp   , /*!<                                                       */
    };
 
-   QString hostname   () const;
-   QString fullUri    () const;
-   QString userinfo   () const;
-   bool    hasHostname() const;
+   QString    hostname    () const;
+   QString    fullUri     () const;
+   QString    userinfo    () const;
+   bool       hasHostname () const;
+   SchemeType schemeType  () const;
 
    URI& operator=(const URI&);