diff --git a/src/collectioninterface.cpp b/src/collectioninterface.cpp
index dbdbaf1de5efc71bb8fb913137c904c3a145a9d0..477c3c3e1b57b1563460be2fbf762b88254dad4b 100644
--- a/src/collectioninterface.cpp
+++ b/src/collectioninterface.cpp
@@ -82,22 +82,27 @@ void CollectionInterface::addChildren(CollectionInterface* c)
 
 bool CollectionInterface::add(ItemBase<QObject>* base)
 {
-   return d_ptr->m_pAdd(base);
+   return d_ptr->m_fAdd(base);
 }
 
 bool CollectionInterface::save(ItemBase<QObject>* base)
 {
-   return d_ptr->m_pSave(base);
+   return d_ptr->m_fSave(base);
 }
 
 bool CollectionInterface::edit(ItemBase<QObject>* base)
 {
-   return d_ptr->m_pEdit(base);
+   return d_ptr->m_fEdit(base);
 }
 
 bool CollectionInterface::remove(ItemBase<QObject>* base)
 {
-   return d_ptr->m_pRemove(base);
+   return d_ptr->m_fRemove(base);
+}
+
+int CollectionInterface::size() const
+{
+   return  d_ptr->m_fSize();
 }
 
 QMetaObject CollectionInterface::metaObject()
diff --git a/src/collectioninterface.h b/src/collectioninterface.h
index 3b70a3e536164fa3c893192d6146bf3a9eccca96..1e87d8bc21828481b84febe4112a598bf2d04c4e 100644
--- a/src/collectioninterface.h
+++ b/src/collectioninterface.h
@@ -159,6 +159,12 @@ public:
     */
    virtual bool clear  (    );
 
+   /**
+    * Return the number of elements tracked by this collection.
+    * This can usually be extracted from editor<T>()->items().size();
+    */
+   virtual int size() const;
+
    /**
     * Return a pointer to the model implementing the CollectionManager.
     */
diff --git a/src/collectioninterface.hpp b/src/collectioninterface.hpp
index ae5e4b32ac6f36031789cb67b367015313afc56f..f19988419603429592a0331a66980dee8762ed32 100644
--- a/src/collectioninterface.hpp
+++ b/src/collectioninterface.hpp
@@ -36,10 +36,11 @@ public:
    ///Use Qt introspection to make sure casting is valid
    QMetaObject                    m_pEditorType;
 
-   std::function<bool(ItemBase<QObject>*)>  m_pAdd       ;
-   std::function<bool(ItemBase<QObject>*)>  m_pSave      ;
-   std::function<bool(ItemBase<QObject>*)>  m_pEdit      ;
-   std::function<bool(ItemBase<QObject>*)>  m_pRemove    ;
+   std::function<bool(ItemBase<QObject>*)>  m_fAdd       ;
+   std::function<bool(ItemBase<QObject>*)>  m_fSave      ;
+   std::function<bool(ItemBase<QObject>*)>  m_fEdit      ;
+   std::function<bool(ItemBase<QObject>*)>  m_fRemove    ;
+   std::function<int()                   >  m_fSize      ;
 };
 
 template<typename T>
@@ -52,18 +53,21 @@ d_ptr(new CollectionInterfacePrivate())
    d_ptr->m_pEditor = (void*) editor;
 
    //The cast is safe because the metatype is checked earlier
-   d_ptr->m_pAdd = [editor](ItemBase<QObject>* item)->bool {
+   d_ptr->m_fAdd = [editor](ItemBase<QObject>* item)->bool {
       return editor->addNew(static_cast<T*>(item));
    };
-   d_ptr->m_pSave = [editor](ItemBase<QObject>* item)->bool {
+   d_ptr->m_fSave = [editor](ItemBase<QObject>* item)->bool {
       return editor->edit(static_cast<T*>(item));
    };
-   d_ptr->m_pEdit = [editor](ItemBase<QObject>* item)->bool {
+   d_ptr->m_fEdit = [editor](ItemBase<QObject>* item)->bool {
       return editor->edit(static_cast<T*>(item));
    };
-   d_ptr->m_pRemove = [editor](ItemBase<QObject>* item)->bool {
+   d_ptr->m_fRemove = [editor](ItemBase<QObject>* item)->bool {
       return editor->remove(static_cast<T*>(item));
    };
+   d_ptr->m_fSize = [editor]()->int {
+      return editor->items().size();
+   };
 }
 
 template<typename T>
diff --git a/src/collectionmodel.cpp b/src/collectionmodel.cpp
index 05e66d0a83ca730b1081fb65f45f166a1492e676..b88f29fc86d6e02bd7c9293c948dedd07f3e3286 100644
--- a/src/collectionmodel.cpp
+++ b/src/collectionmodel.cpp
@@ -33,7 +33,6 @@ CollectionModelPrivate::CollectionModelPrivate(CollectionModel* parent) : QObjec
 
 CollectionModel::CollectionModel(QObject* parent) : QAbstractTableModel(parent), d_ptr(new CollectionModelPrivate(this))
 {
-   connect(PersonModel::instance(),SIGNAL(newBackendAdded(CollectionInterface*)),d_ptr.data(),SLOT(slotUpdate()));
    load();
 }
 
@@ -76,28 +75,34 @@ QVariant CollectionModel::data (const QModelIndex& idx, int role) const
    if (idx.isValid()) {
       CollectionModelPrivate::ProxyItem* item = static_cast<CollectionModelPrivate::ProxyItem*>(idx.internalPointer());
 
-      if (idx.column() > 0)
+      if (idx.column() > 0 && item->collection)
          return d_ptr->m_lExtensions[idx.column()-1]->data(item->collection,idx,role);
 
-      switch(role) {
-         case Qt::DisplayRole:
-            return item->collection->name();
-            break;
-         case Qt::DecorationRole:
-            return item->collection->icon();
-            break;
-//          case Qt::CheckStateRole:
-//             return item->collection->isEnabled()?Qt::Checked:Qt::Unchecked;
-         case Qt::CheckStateRole: {
-            if (ItemModelStateSerializationDelegate::instance())
-               return ItemModelStateSerializationDelegate::instance()->isChecked(item->collection)?Qt::Checked:Qt::Unchecked;
+      if (item->collection) {
+         switch(role) {
+            case Qt::DisplayRole:
+               return item->collection->name();
+               break;
+            case Qt::DecorationRole:
+               return item->collection->icon();
+               break;
+            case Qt::UserRole:
+               return 'x'+QString::number(item->collection->size());
+               break;
+            case Qt::CheckStateRole: {
+               if (ItemModelStateSerializationDelegate::instance()) //TODO do better than that
+                  return ItemModelStateSerializationDelegate::instance()->isChecked(item->collection)?Qt::Checked:Qt::Unchecked;
+            }
+         };
+      }
+      else {
+         switch(role) {
+            case Qt::DisplayRole:
+               return item->m_AltName;
+               break;
          }
-      };
+      }
    }
-   //else {
-//       CollectionModelPrivate::ProxyItem* item = static_cast<CollectionModelPrivate::ProxyItem*>(idx.internalPointer());
-//       return item->model->data(item->model->index(item->row,item->col));
-   //}
    return QVariant();
 }
 
@@ -108,7 +113,7 @@ int CollectionModel::rowCount (const QModelIndex& parent) const
    }
    else {
       CollectionModelPrivate::ProxyItem* item = static_cast<CollectionModelPrivate::ProxyItem*>(parent.internalPointer());
-      return item->collection->children().size();
+      return item->m_Children.size();
    }
 }
 
@@ -123,6 +128,11 @@ Qt::ItemFlags CollectionModel::flags(const QModelIndex& idx) const
    if (!idx.isValid())
       return 0;
    CollectionModelPrivate::ProxyItem* item = static_cast<CollectionModelPrivate::ProxyItem*>(idx.internalPointer());
+
+   //Categories can only be displayed
+   if (!item->collection)
+      return Qt::ItemIsEnabled;
+
    if (idx.column() > 0) {
       //Make sure the cell is disabled if the row is
       Qt::ItemFlags f = d_ptr->m_lExtensions[idx.column()-1]->flags(item->collection,idx);
@@ -140,12 +150,12 @@ bool CollectionModel::setData (const QModelIndex& idx, const QVariant &value, in
    Q_UNUSED(role)
    if (idx.isValid() && idx.column() > 0) {
       CollectionModelPrivate::ProxyItem* item = static_cast<CollectionModelPrivate::ProxyItem*>(idx.internalPointer());
-      return d_ptr->m_lExtensions[idx.column()-1]->setData(item->collection,idx,value,role);
+      return (!item->collection)?false : d_ptr->m_lExtensions[idx.column()-1]->setData(item->collection,idx,value,role);
    }
 
    if (role == Qt::CheckStateRole && idx.column() == 0) {
       CollectionModelPrivate::ProxyItem* item = static_cast<CollectionModelPrivate::ProxyItem*>(idx.internalPointer());
-      if (item) {
+      if (item && item->collection) {
          const bool old = item->collection->isEnabled();
          ItemModelStateSerializationDelegate::instance()->setChecked(item->collection,value==Qt::Checked);
          emit dataChanged(index(idx.row(),0),index(idx.row(),columnCount()-1));
@@ -177,12 +187,9 @@ QModelIndex CollectionModel::index( int row, int column, const QModelIndex& pare
       if (row < parentItem->m_Children.size())
          item = parentItem->m_Children[row];
       else {
-         item = new CollectionModelPrivate::ProxyItem();
-         item->parent = parentItem;
-         item->collection = parentItem->collection->children()[row];
-         parentItem->m_Children << item;
+         return QModelIndex();
       }
-      item->row    = row;
+      item->row    = row; //FIXME dead code?
       item->col    = column;
       return createIndex(row,column,item);
    }
@@ -191,15 +198,9 @@ QModelIndex CollectionModel::index( int row, int column, const QModelIndex& pare
       if (row < d_ptr->m_lTopLevelBackends.size())
          item = d_ptr->m_lTopLevelBackends[row];
       else {
-
-         if (row >= PersonModel::instance()->collections().size())
-            return QModelIndex();
-
-         item = new CollectionModelPrivate::ProxyItem();
-         item->collection = PersonModel::instance()->collections()[row];
-         d_ptr->m_lTopLevelBackends << item;
+         return QModelIndex();
       }
-      item->row = row;
+      item->row = row; //FIXME dead code?
       item->col = column;
       return createIndex(item->row,item->col,item);
    }
@@ -286,26 +287,34 @@ void CollectionModelPrivate::registerNew(CollectionInterface* col)
    if (!col)
       return;
 
-   ProxyItem* item = new ProxyItem();
-   if (col->parent()) {
-      ProxyItem* p = m_hBackendsNodes[col->parent()];
-      item->parent = p;
-      item->row    = p->m_Children.size();
-      item->col    = 0;
-      q_ptr->beginInsertRows(q_ptr->createIndex(p->row,p->col,p),p->m_Children.size(),p->m_Children.size());
-      p->m_Children << item;
-      q_ptr->endInsertRows();
+   ProxyItem* cat = m_hCategories[col->category()];
+   if (col->category().isEmpty()){
+      //TODO implement a default category
    }
-   else {
-      item->parent = nullptr;
-      item->row    = m_lTopLevelBackends.size();
-      item->col    = 0;
+
+   if (!cat) {
+      cat              = new ProxyItem();
+      cat->parent      = nullptr;
+      cat->row         = m_lTopLevelBackends.size();
+      cat->col         = 0;
+      cat->m_AltName   = col->category();
+      cat->collection  = nullptr;
 
       q_ptr->beginInsertRows(QModelIndex(),m_lTopLevelBackends.size(),m_lTopLevelBackends.size());
-      m_lTopLevelBackends << item;
+      m_lTopLevelBackends << cat;
       q_ptr->endInsertRows();
    }
 
+   ProxyItem* item = new ProxyItem();
+   ProxyItem* par = col->parent()?m_hBackendsNodes[col->parent()] : cat;
+
+   item->parent = par;
+   item->row    = par->m_Children.size();
+   item->col    = 0;
+   q_ptr->beginInsertRows(q_ptr->createIndex(par->row,par->col,par),par->m_Children.size(),par->m_Children.size());
+   par->m_Children << item;
+   q_ptr->endInsertRows();
+
 
    item->collection      = col ;
    m_hBackendsNodes[col] = item;
diff --git a/src/private/collectionmodel_p.h b/src/private/collectionmodel_p.h
index 5dff0d4d836543cc6390fec4a60642e48fe411c8..bb095e997fd5b699115eb1f63b056fa07acefc45 100644
--- a/src/private/collectionmodel_p.h
+++ b/src/private/collectionmodel_p.h
@@ -44,11 +44,13 @@ public:
       CollectionInterface* collection;
       ProxyItem* parent;
       QVector<ProxyItem*> m_Children;
+      QString m_AltName;
    };
 
    QHash<CollectionInterface*,ProxyItem*> m_hBackendsNodes;
    QVector<ProxyItem*>                    m_lTopLevelBackends;
    QVector<CollectionExtensionInterface*> m_lExtensions;
+   QHash<QString,ProxyItem*>              m_hCategories;
    static CollectionModel*                m_spInstance;
 
    //Helper