diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a5e859bf4..6466f60e7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -71,7 +71,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
      settingsdialog.cpp
      diagnosticsdialog.cpp
      configdelegatebase.cpp
-     accountdelegate.cpp
+     sipconfigdelegate.cpp
      resolverconfigdelegate.cpp
      settingslistdelegate.cpp
      resolversmodel.cpp
@@ -122,7 +122,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
      diagnosticsdialog.h
      configdelegatebase.h
      resolverconfigdelegate.h
-     accountdelegate.h
+     sipconfigdelegate.h
      settingslistdelegate.h
      resolversmodel.h
      delegateconfigwrapper.h
diff --git a/src/accountdelegate.cpp b/src/accountdelegate.cpp
deleted file mode 100644
index e2de7bbc1..000000000
--- a/src/accountdelegate.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-    Copyright (C) 2011  Leo Franchi <leo.franchi@kdab.com>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "accountdelegate.h"
-
-#include <QApplication>
-#include <QPainter>
-
-#include "accounts/accountmodel.h"
-#include "accounts/account.h"
-
-#include "utils/tomahawkutils.h"
-#include "utils/logger.h"
-
-#define ICONSIZE 36
-#define WRENCH_SIZE 24
-#define STATUS_ICON_SIZE 18
-#define CHECK_LEFT_EDGE 8
-
-using namespace Tomahawk;
-using namespace Accounts;
-
-AccountDelegate::AccountDelegate( QObject* parent )
-    : ConfigDelegateBase ( parent )
-{
-    connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) );
-}
-
-bool
-AccountDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
-{
-    return ConfigDelegateBase::editorEvent( event, model, option, index );
-}
-
-void
-AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
-{
-    QStyleOptionViewItemV4 opt = option;
-    initStyleOption( &opt, index );
-    const QRect itemRect = opt.rect;
-    const int top = itemRect.top();
-    const int mid = itemRect.height() / 2;
-
-    // one line bold for account name
-    // space below it for account description
-    // checkbox, icon, name, online/offline status, config icon
-    QFont name = opt.font;
-    name.setPointSize( name.pointSize() + 2 );
-    name.setBold( true );
-
-    QFont desc = opt.font;
-    desc.setItalic( true );
-    desc.setPointSize( error.pointSize() - 2 );
-
-    // draw the background
-    const QWidget* w = opt.widget;
-    QStyle* style = w ? w->style() : QApplication::style();
-    style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
-
-    int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING;
-    int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING;
-
-    // draw checkbox first
-    int pos = ( mid ) - ( WRENCH_SIZE / 2 );
-    QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, WRENCH_SIZE, WRENCH_SIZE );
-    opt.rect = checkRect;
-    drawCheckBox( opt, painter, w );
-
-    // draw the icon if it exists
-    pos = mid - ( ICONSIZE / 2 );
-    if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) {
-        QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE );
-
-        painter->save();
-        painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) );
-        painter->restore();
-    }
-
-    // from the right edge--config status and online/offline
-    QRect confRect = QRect( itemRect.width() - WRENCH_SIZE - 2 * PADDING, mid - WRENCH_SIZE / 2 + top, WRENCH_SIZE, WRENCH_SIZE );
-    if( index.data( SipModel::HasConfig ).toBool() ) {
-
-        QStyleOptionToolButton topt;
-        topt.rect = confRect;
-        topt.pos = confRect.topLeft();
-
-        drawConfigWrench( painter, opt, topt );
-    }
-
-
-    // draw the online/offline status
-    const bool hasCapability = ( static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() ) != AccountModel::NoCapabilities );
-    const int quarter = mid - ( itemRect.height() / 4 );
-    const int statusY = hasCapability ? quarter : mid;
-    const int statusX = confRect.left() - 2*PADDING - STATUS_ICON_SIZE;
-
-    QFont statusF = opt.font;
-    statusF.setPointSize( statusF.pointSize() - 2 );
-    QFontMetrics statusFM( statusF );
-
-    QPixmap p;
-    QString statusText;
-    Account::ConnectionState state = static_cast< Account::ConnectionState >( index.data( AccountModel::ConnectionStateRole ).toInt() );
-    if( state == SipPlugin::Connected ) {
-        p = QPixmap( RESPATH "images/sipplugin-online.png" );
-        statusText = tr( "Online" );
-    } else if( state == SipPlugin::Connecting ) {
-        p = QPixmap( RESPATH "images/sipplugin-offline.png" );
-        statusText = tr( "Connecting..." );
-    } else {
-        p = QPixmap( RESPATH "images/sipplugin-offline.png" );
-        statusText = tr( "Offline" );
-    }
-    p = p.scaled( STATUS_ICON_SIZE, STATUS_ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation );
-    painter->drawPixmap( statusX, statusY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE, p );
-    const int width = statusFM.width( statusText );
-    int statusTextX = statusX - PADDING - width;
-    painter->save();
-    painter->setFont( statusF );
-    painter->drawText( QRect( statusTextX, statusY - statusFM.height() / 2 + top, width, statusFM.height() ), statusText );
-
-    // draw optional capability text if it exists
-    if ( hasCapability )
-    {
-        QString capString;
-        AccountModel::BasicCapabilities cap = static_cast< AccountModel::BasicCapabilities >( index.data( AccountModel::BasicCapabilityRole ).toInt() );
-        if ( ( cap & AccountModel::SipCapability ) && ( cap & AccountModel::ResolverCapability ) )
-            capString = tr( "Connect to and play from friends" );
-        else if ( cap & AccountModel::SipCapability )
-            capString = tr( "Connect to friends" );
-        else if ( cap & AccountModel::ResolverCapability )
-            capString = tr( "Find Music");
-
-        // checkbox for capability
-        const int capY = statusY + ( itemRect.height() / 2 );
-        QRect capCheckRect( statusX, capY - STATUS_ICON_SIZE / 2 + top, STATUS_ICON_SIZE, STATUS_ICON_SIZE );
-        opt.rect = capCheckRect;
-        drawCheckBox( opt, painter, w );
-
-        // text to accompany checkbox
-        const int capW = statusFM.width( capString );
-        const int capTextX = statusX - PADDING  - capW;
-        painter->drawText( QRect( capTextX, capY - statusFM.height() / 2 + top, capW, statusFM.height() ) );
-
-        if ( capTextX < statusTextX )
-            statusTextX = capTextX;
-    }
-    painter->restore();
-
-    // name
-    painter->save();
-    painter->setFont( name );
-    QFontMetrics namefm( name );
-    // pos will the top-left point of the text rect
-    pos = mid - ( nameHeight / 2 ) + top;
-    // TODO bound with config icon and offline/online status
-    width = itemRect.width() - statusTextX;
-    QRect nameRect( textLeftEdge, pos, width, namefm.height() );
-    painter->drawText( nameRect, index.data( AccountModel::AccountName ).toString() );
-
-    nameRect.translate( mid, 0 ); // move down by half the hight
-    painter->drawText( nameRect, index.data( AccountModel::DescText ).toString() );
-    painter->restore();
-
-}
-
-QRect
-AccountDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const
-{
-    if ( role == Qt::CheckStateRole )
-    {
-        // the whole resolver checkbox
-        QStyleOptionViewItemV4 opt = option;
-        initStyleOption( &opt, idx );
-        const int mid = opt.rect.height() / 2;
-        const int pos = mid - ( ICONSIZE / 2 );
-        QRect checkRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE );
-
-        return checkRect;
-    } else if ( role == AccountModel::BasicCapabilityRole )
-    {
-        // The capabilities checkbox
-        QStyleOptionViewItemV4 opt = option;
-        initStyleOption( &opt, idx );
-        const int quarter = opt.rect.height() / 4 + opt.rect.height()  / 2;
-        const int leftEdge = opt.rect.width() - PADDING - WRENCH_SIZE - PADDING - WRENCH_SIZE;
-        QRect checkRect( leftEdge, quarter, WRENCH_SIZE, WRENCH_SIZE );
-        return checkRect;
-    }
-    return QRect();
-}
-
-QRect
-AccountDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const
-{
-    if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() )
-    {
-        QStyleOptionViewItemV4 opt = option;
-        initStyleOption( &opt, idx );
-        QRect itemRect = opt.rect;
-        QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE );
-        return confRect;
-    }
-    return QRect();
-}
-
-
-QSize
-AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
-{
-    return ConfigDelegateBase::sizeHint( option, index );
-}
-
-void
-AccountDelegate::askedForEdit( const QModelIndex& idx )
-{
-    emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) );
-}
-
-
diff --git a/src/accounts/twitter/twitteraccount.h b/src/accounts/twitter/twitteraccount.h
index ac7ad5c6e..a440f44bf 100644
--- a/src/accounts/twitter/twitteraccount.h
+++ b/src/accounts/twitter/twitteraccount.h
@@ -56,9 +56,10 @@ class DLLEXPORT TwitterAccount : public Account
 public:
     TwitterAccount( const QString &accountId );
     virtual ~TwitterAccount();
-
+    
     QIcon icon() const { return QIcon( ":/twitter-icon.png" ); }
 
+    bool canSelfAuthenticate() const { return true; }
     void authenticate();
     void deauthenticate();
     bool isAuthenticated() const { return m_isAuthenticated; }
@@ -81,7 +82,7 @@ signals:
 private slots:
     void configDialogAuthedSignalSlot( bool authed );
     void connectAuthVerifyReply( const QTweetUser &user );
-
+    
 private:
     bool m_isAuthenticated;
     QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth;
diff --git a/src/accounts/xmpp/xmppaccount.h b/src/accounts/xmpp/xmppaccount.h
index d7f54514e..9c0b314cf 100644
--- a/src/accounts/xmpp/xmppaccount.h
+++ b/src/accounts/xmpp/xmppaccount.h
@@ -59,6 +59,7 @@ public:
 
     QIcon icon() const { return QIcon( ":/xmpp-icon.png" ); }
 
+    bool canSelfAuthenticate() const { return false; }
     void authenticate();
     void deauthenticate();
     bool isAuthenticated() const { return m_isAuthenticated; }
@@ -76,7 +77,7 @@ private:
     bool m_isAuthenticated;
     QWeakPointer< QWidget > m_configWidget;
     QWeakPointer< XmppSipPlugin > m_xmppSipPlugin;
-
+    
 
     // for settings access
     friend class XmppConfigWidget;
diff --git a/src/configdelegatebase.cpp b/src/configdelegatebase.cpp
index bdf826bfc..ce6f2baae 100644
--- a/src/configdelegatebase.cpp
+++ b/src/configdelegatebase.cpp
@@ -25,8 +25,6 @@
 #include "utils/tomahawkutils.h"
 #include "utils/logger.h"
 
-#define ROW_HEIGHT 50
-
 ConfigDelegateBase::ConfigDelegateBase ( QObject* parent )
     : QStyledItemDelegate ( parent )
 {
@@ -38,7 +36,23 @@ QSize
 ConfigDelegateBase::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
 {
     int width = QStyledItemDelegate::sizeHint( option, index ).width();
-    return QSize( width, ROW_HEIGHT );
+
+    QStyleOptionViewItemV4 opt = option;
+    initStyleOption( &opt, index );
+
+
+    QFont name = opt.font;
+    name.setPointSize( name.pointSize() + 2 );
+    name.setBold( true );
+
+    QFont path = opt.font;
+    path.setItalic( true );
+    path.setPointSize( path.pointSize() - 1 );
+
+
+    QFontMetrics bfm( name );
+    QFontMetrics sfm( path );
+    return QSize( width, 2 * PADDING + bfm.height() + sfm.height() );
 }
 
 void
@@ -80,24 +94,17 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons
         m_configPressed = QModelIndex();
 
         QMouseEvent* me = static_cast< QMouseEvent* >( event );
-        QList<int> roles = QList<int>() << (int)Qt::CheckStateRole;
-        roles.append( extraCheckRoles() );
+        if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index ).contains( me->pos() ) )
+            return false;
 
-        foreach ( int role, roles )
-        {
-            if( me->button() != Qt::LeftButton || !checkRectForIndex( option, index, role ).contains( me->pos() ) )
-                return false;
-
-            // eat the double click events inside the check rect
-            if( event->type() == QEvent::MouseButtonDblClick ) {
-                return true;
-            }
-
-            Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( role ).toInt() );
-            Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
-            return model->setData( index, newState, role );
+        // eat the double click events inside the check rect
+        if( event->type() == QEvent::MouseButtonDblClick ) {
+            return true;
         }
 
+        Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() );
+        Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
+        return model->setData( index, newState, Qt::CheckStateRole );
 
     } else if( event->type() == QEvent::MouseButtonPress ) {
         QMouseEvent* me = static_cast< QMouseEvent* >( event );
diff --git a/src/configdelegatebase.h b/src/configdelegatebase.h
index 929467a00..d86baad1a 100644
--- a/src/configdelegatebase.h
+++ b/src/configdelegatebase.h
@@ -36,11 +36,10 @@ public:
   virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
 
   // if you want to use a checkbox, you need to have this say where to paint it
-  virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx, int role ) const = 0;
+  virtual QRect checkRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
   // if you want to use a config wrench, you need to have this say where to paint it
   virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const = 0;
 
-  virtual QList<int> extraCheckRoles() const { return QList<int>(); }
 signals:
     void configPressed( const QModelIndex& idx );
 
diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt
index 72e56e0d2..9be5e79e7 100644
--- a/src/libtomahawk/CMakeLists.txt
+++ b/src/libtomahawk/CMakeLists.txt
@@ -61,10 +61,10 @@ set( libSources
 
     accounts/accountmanager.cpp
     accounts/account.cpp
-    accounts/accountmodel.cpp
 
     sip/SipPlugin.cpp
     sip/SipHandler.cpp
+    sip/SipModel.cpp
     sip/sipinfo.cpp
 
     audio/audioengine.cpp
@@ -286,12 +286,12 @@ set( libHeaders
 
     accounts/account.h
     accounts/accountmanager.h
-    accounts/accountmodel.h
 
     EchonestCatalogSynchronizer.h
 
     sip/SipPlugin.h
     sip/SipHandler.h
+    sip/SipModel.h
     sip/sipinfo.h
 
     audio/audioengine.h
diff --git a/src/libtomahawk/accounts/account.h b/src/libtomahawk/accounts/account.h
index 062cd51ef..c8c98c385 100644
--- a/src/libtomahawk/accounts/account.h
+++ b/src/libtomahawk/accounts/account.h
@@ -39,7 +39,7 @@ namespace InfoSystem
 {
     class InfoPlugin;
 }
-
+    
 namespace Accounts
 {
 
@@ -54,11 +54,8 @@ inline QString generateId( const QString &factoryId )
 class DLLEXPORT Account : public QObject
 {
     Q_OBJECT
-
+    
 public:
-    enum AuthErrorCode { AuthError, ConnectionError };
-    enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
-
     explicit Account( const QString &accountId )
         : QObject()
         , m_enabled( false )
@@ -82,9 +79,9 @@ public:
 
     virtual QIcon icon() const = 0;
 
+    virtual bool canSelfAuthenticate() const = 0;
     virtual void authenticate() = 0;
     virtual void deauthenticate() = 0;
-    virtual ConnectionState connectionState() = 0;s
     virtual bool isAuthenticated() const = 0;
 
     virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0;
@@ -136,8 +133,6 @@ public:
     virtual void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); };
 
 signals:
-    void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state );
-
     void configurationChanged();
     void authenticated( bool );
     
@@ -208,4 +203,4 @@ public:
 
 Q_DECLARE_INTERFACE( Tomahawk::Accounts::AccountFactory, "tomahawk.AccountFactory/1.0" )
 
-#endif
+#endif
\ No newline at end of file
diff --git a/src/libtomahawk/accounts/accountmanager.cpp b/src/libtomahawk/accounts/accountmanager.cpp
index 9e33b782c..b340ec4ab 100644
--- a/src/libtomahawk/accounts/accountmanager.cpp
+++ b/src/libtomahawk/accounts/accountmanager.cpp
@@ -187,8 +187,8 @@ AccountManager::addAccountPlugin( Account* account )
 
     foreach( AccountType type, account->types() )
         m_accountsByAccountType[ type ].append( account );
-
-    emit accountAdded( account );
+    //TODO:?
+    //emit pluginAdded( account );
 }
 
 
diff --git a/src/libtomahawk/accounts/accountmanager.h b/src/libtomahawk/accounts/accountmanager.h
index 3cb914042..8020c5759 100644
--- a/src/libtomahawk/accounts/accountmanager.h
+++ b/src/libtomahawk/accounts/accountmanager.h
@@ -52,12 +52,8 @@ public:
     Account* loadPlugin( const QString &accountId );
     QString factoryFromId( const QString& accountId ) const;
     
-    QList< Account* > accounts() const { return m_accounts; };
-    QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; }
-
-signals:
-    void accountAdded( Tomahawk::Accounts::Account* );
-    void accountRemoved( Tomahawk::Accounts::Account* );
+    QList< Account* > getAccounts() { return m_accounts; };
+    QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; }
 
 private:
     QList< Account* > m_accounts;
@@ -71,4 +67,4 @@ private:
 
 };
 
-#endif
+#endif
\ No newline at end of file
diff --git a/src/libtomahawk/accounts/accountmodel.cpp b/src/libtomahawk/accounts/accountmodel.cpp
deleted file mode 100644
index 5bd33f293..000000000
--- a/src/libtomahawk/accounts/accountmodel.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
- 4/*
-    Copyright (C) 2011  Leo Franchi <lfranchi@kde.org>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "accountmodel.h"
-
-#include "tomahawksettings.h"
-#include "accounts/accountmanager.h"
-#include "accounts/account.h"
-
-#include "utils/logger.h"
-
-using namespace Tomahawk;
-using namespace Accounts;
-
-AccountModel::AccountModel( QObject* parent )
-    : QAbstractListModel( parent )
-{
-    connect( AccountManager::instance(), SIGNAL( accountAdded( Tomahawk::Accounts::Account* ) ), this, SLOT( accountAdded( Tomahawk::Accounts::Account* ) ) );
-    connect( AccountManager::instance(), SIGNAL( accountRemoved( Tomahawk::Accounts::Account* ) ), this, SLOT( accountRemoved( Tomahawk::Accounts::Account* ) ) );
-}
-
-
-AccountModel::~AccountModel()
-{
-}
-
-
-QVariant
-AccountModel::data( const QModelIndex& index, int role ) const
-{
-    if( !index.isValid() )
-        return QVariant();
-
-    QList< Account* > accounts = AccountManager::instance()->accounts();
-    Q_ASSERT( index.row() <= accounts.size() );
-    Account* account = accounts[ index.row() ];
-    switch( role )
-    {
-    case Qt::DisplayRole:
-    case AccountModel::AccountName:
-        return account->accountServiceName();
-    case AccountModel::ConnectionStateRole:
-        return account->connectionState();
-    case AccountModel::HasConfig:
-        return ( account->configurationWidget() != 0 );
-    case Qt::DecorationRole:
-        return account->icon();
-    case AccountModel::AccountData:
-        return QVariant::fromValue< QObject* >( account );
-    case Qt::CheckStateRole:
-        return account->enabled() ? Qt::Checked : Qt::Unchecked;
-    default:
-        return QVariant();
-    }
-    return QVariant();
-}
-
-
-bool
-AccountModel::setData( const QModelIndex& index, const QVariant& value, int role )
-{
-    Q_ASSERT( index.isValid() && index.row() <= AccountManager::instance()->accounts().count() );
-
-    if ( role == Qt::CheckStateRole ) {
-        Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
-        QList< Account* > accounts = AccountManager::instance()->accounts();
-        Account* account = accounts[ index.row() ];
-
-        if( state == Qt::Checked && !account->enabled() ) {
-            account->setEnabled( true );
-        } else if( state == Qt::Unchecked ) {
-            account->setEnabled( false );
-        }
-        dataChanged( index, index );
-
-        return true;
-    }
-    else if ( role == BasicCapabilityRole )
-    {
-        // TODO
-    }
-    return false;
-}
-
-int
-AccountModel::rowCount( const QModelIndex& parent ) const
-{
-    return AccountManager::instance()->accounts().size();
-}
-
-Qt::ItemFlags
-AccountModel::flags( const QModelIndex& index ) const
-{
-    return QAbstractListModel::flags( index ) | Qt::ItemIsUserCheckable;
-}
-
-
-void
-AccountModel::accountAdded( Account* account )
-{
-    Q_UNUSED( p );
-    // we assume account plugins are added at the end of the list.
-    Q_ASSERT( AccountManager::instance()->accounts().last() == account );
-    if ( account->types().contains( SipType ) )
-        connect( account->sipPlugin(), SIGNAL( stateChanged( SipPlugin::ConnectionState ) ), this, SLOT( sipStateChanged( SipPlugin::ConnectionState ) ) );
-
-    int size = AccountManager::instance()->accounts().count() - 1;
-    beginInsertRows( QModelIndex(), size, size );
-    endInsertRows();
-}
-
-
-void
-AccountModel::accountRemoved( Account* account )
-{
-    int idx = AccountManager::instance()->allPlugins().indexOf( account );
-    beginRemoveRows( QModelIndex(), idx, idx );
-    endRemoveRows();
-}
-
-
-void
-AccountModel::sipStateChanged( SipPlugin::ConnectionState state  )
-{
-    SipPlugin* p = qobject_cast< SipPlugin* >( sender() );
-    Q_ASSERT( a );
-
-    for ( int i = 0; i < AccountManager::instance()->accounts().size(); i++ )
-    {
-        if ( AccountManager::instance()->accounts()[i] &&
-             AccountManager::instance()->accounts()[i]->sipPlugin() &&
-             AccountManager::instance()->accounts()[i]->sipPlugin() == p )
-        {
-            QModelIndex idx = index( i, 0, QModelIndex() );
-            emit dataChanged( idx, idx );
-            return;
-        }
-    }
-}
-
diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp
index 7254eb229..5c9c4d496 100644
--- a/src/libtomahawk/sip/SipHandler.cpp
+++ b/src/libtomahawk/sip/SipHandler.cpp
@@ -174,7 +174,7 @@ void
 SipHandler::loadFromAccountManager()
 {
     tDebug() << Q_FUNC_INFO;
-    QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType );
+    QList< Tomahawk::Accounts::Account* > accountList = Tomahawk::Accounts::AccountManager::instance()->getAccounts( Tomahawk::Accounts::SipType );
     foreach( Tomahawk::Accounts::Account* account, accountList )
     {
         tDebug() << Q_FUNC_INFO << "adding plugin " << account->accountId();
diff --git a/src/libtomahawk/sip/SipModel.cpp b/src/libtomahawk/sip/SipModel.cpp
new file mode 100644
index 000000000..093d81c88
--- /dev/null
+++ b/src/libtomahawk/sip/SipModel.cpp
@@ -0,0 +1,227 @@
+/*
+    Copyright (C) 2011  Leo Franchi <lfranchi@kde.org>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "SipModel.h"
+
+#include "tomahawksettings.h"
+#include "sip/SipHandler.h"
+#include "sip/SipPlugin.h"
+
+#include "utils/logger.h"
+
+
+SipModel::SipModel( QObject* parent )
+    : QAbstractItemModel( parent )
+{
+    connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) );
+    connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( pluginAdded( SipPlugin* ) ) );
+    connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( pluginRemoved( SipPlugin* ) ) );
+
+    // TODO disable inline factories for now
+    /*
+    foreach( SipPluginFactory* f, SipHandler::instance()->pluginFactories() ) {
+        if( f->isCreatable() )
+            m_factories << f;
+    } */
+
+}
+
+
+SipModel::~SipModel()
+{
+}
+
+
+QVariant
+SipModel::data( const QModelIndex& index, int role ) const
+{
+    if( !index.isValid() )
+        return QVariant();
+
+    if( !index.parent().isValid() && index.row() == SipHandler::instance()->allPlugins().count() ) { // last row, this is the factory
+        if( role == Qt::DisplayRole )
+            return tr( "Add New Account..." );
+        else if( role == FactoryRole )
+            return true;
+        else
+            return QVariant();
+    }
+
+    if( !index.parent().isValid() ) { // account
+        QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins();
+        Q_ASSERT( index.row() <= plugins.size() );
+        SipPlugin* p = plugins[ index.row() ];
+        switch( role )
+        {
+            case Qt::DisplayRole:
+            case SipModel::PluginName:
+                return p->account()->accountServiceName();
+            case SipModel::ConnectionStateRole:
+                return p->connectionState();
+            case SipModel::HasConfig:
+                return ( p->account()->configurationWidget() != 0 );
+            case SipModel::FactoryRole:
+                return false;
+            case Qt::DecorationRole:
+                return p->icon();
+            case SipModel::SipPluginData:
+                return QVariant::fromValue< QObject* >( p );
+            case Qt::CheckStateRole:
+                return p->account()->enabled() ? Qt::Checked : Qt::Unchecked;
+            default:
+                return QVariant();
+        }
+    }
+
+    /*
+     * m_factories never actually populated yet, so just disable
+    if( index.parent().isValid() ) { // this is a factory type
+        SipPluginFactory* p = m_factories.at( index.row() );
+        switch( role )
+        {
+        case Qt::DisplayRole:
+            return p->prettyName();
+        case SipModel::FactoryItemRole:
+            return true;
+        case SipModel::FactoryItemIcon:
+            return p->icon();
+        case SipModel::SipPluginFactoryData:
+            return QVariant::fromValue< QObject* >( p );
+        default:
+            return QVariant();
+        }
+    }
+    */
+    return QVariant();
+}
+
+
+bool
+SipModel::setData( const QModelIndex& index, const QVariant& value, int role )
+{
+    Q_ASSERT( index.isValid() && index.row() <= SipHandler::instance()->allPlugins().count() );
+
+    if( role == Qt::CheckStateRole ) {
+        Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
+        QList< SipPlugin* > plugins = SipHandler::instance()->allPlugins();
+        SipPlugin* p = plugins[ index.row() ];
+
+        if( state == Qt::Checked && !p->account()->enabled() ) {
+            p->account()->setEnabled( true );
+        } else if( state == Qt::Unchecked ) {
+            p->account()->setEnabled( false );
+        }
+        dataChanged( index, index );
+
+        return true;
+    }
+    return false;
+}
+
+
+QModelIndex
+SipModel::index( int row, int column, const QModelIndex& parent ) const
+{
+    if( !parent.isValid() )
+        return hasIndex( row, column, parent ) ? createIndex( row, column, 0 ) : QModelIndex();
+
+//     qDebug() << "Creating index for non-top level row!";
+    // it's a child of the Add Account, e.g. a factory
+    if( hasIndex( row, column, parent ) ) {
+        return createIndex( row, column, 1 /* magic */ );
+    }
+
+    return QModelIndex();
+}
+
+
+QModelIndex
+SipModel::parent( const QModelIndex& child ) const
+{
+    if( !child.isValid() )
+        return QModelIndex();
+
+    if( child.internalId() == 1 ) {
+        return index( SipHandler::instance()->allPlugins().size(), 0, QModelIndex() );
+    }
+
+    return QModelIndex();
+}
+
+
+int
+SipModel::rowCount( const QModelIndex& parent ) const
+{
+    if( !parent.isValid() ) // invalid root node
+        return SipHandler::instance()->allPlugins().size() /* TODO inline factories disabled + 1*/;
+    if( parent.isValid() && !parent.parent().isValid() ) { // top level item
+        if( parent.row() == SipHandler::instance()->allPlugins().count() ) {// last row, this is the factory
+            //return m_factories.count();
+        }
+    }
+
+    return 0;
+}
+
+
+int
+SipModel::columnCount(const QModelIndex& parent) const
+{
+    Q_UNUSED( parent );
+    return 1;
+}
+
+
+Qt::ItemFlags
+SipModel::flags( const QModelIndex& index ) const
+{
+    if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() )
+        return QAbstractItemModel::flags( index ) & ~Qt::ItemIsSelectable;
+    return QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable;
+}
+
+
+void
+SipModel::pluginAdded( SipPlugin* p )
+{
+    Q_UNUSED( p );
+    // we assume sip plugins are added at the end of the list.
+    Q_ASSERT( SipHandler::instance()->allPlugins().last() == p );
+    int size = SipHandler::instance()->allPlugins().count() - 1;
+    beginInsertRows( QModelIndex(), size, size );
+    endInsertRows();
+}
+
+
+void
+SipModel::pluginRemoved( SipPlugin* p )
+{
+    int idx = SipHandler::instance()->allPlugins().indexOf( p );
+    beginRemoveRows( QModelIndex(), idx, idx );
+    endRemoveRows();
+}
+
+
+void
+SipModel::pluginStateChanged( SipPlugin* p )
+{
+    int at = SipHandler::instance()->allPlugins().indexOf( p );
+    QModelIndex idx = index( at, 0, QModelIndex() );
+    emit dataChanged( idx, idx );
+}
+
diff --git a/src/libtomahawk/accounts/accountmodel.h b/src/libtomahawk/sip/SipModel.h
similarity index 56%
rename from src/libtomahawk/accounts/accountmodel.h
rename to src/libtomahawk/sip/SipModel.h
index 9f02363d2..7f4901032 100644
--- a/src/libtomahawk/accounts/accountmodel.h
+++ b/src/libtomahawk/sip/SipModel.h
@@ -1,4 +1,5 @@
 /*
+    <one line to give the program's name and a brief idea of what it does.>
     Copyright (C) 2011  Leo Franchi <lfranchi@kde.org>
 
     This program is free software: you can redistribute it and/or modify
@@ -20,57 +21,43 @@
 #define SIPMODEL_H
 
 #include "dllmacro.h"
-#include "sip/SipPlugin.h"
 
 #include <QModelIndex>
 #include <QStringList>
 
-namespace Tomahawk
-{
-namespace Accounts
-{
+class SipPlugin;
 
-class Account;
-
-class DLLEXPORT AccountModel : public QAbstractListModel
+class DLLEXPORT SipModel : public QAbstractItemModel
 {
     Q_OBJECT
 public:
-    enum BasicCapabilities
-    {
-        NoCapabilities = 0,
-        SipCapability = 0x1,
-        ResolverCapability = 0x2
-    };
-
     enum Roles {
-        AccountName = Qt::UserRole + 15,
-        AccountIcon = Qt::UserRole + 16,
-        HeadlineText = Qt::UserRole + 17,
-        DescText = Qt::UserRole + 18,
-        BasicCapabilityRole = Qt::UserRole + 19,
-        ConnectionStateRole = Qt::UserRole + 20,
-        HasConfig = Qt::UserRole + 21,
-        ErrorString = Qt::UserRole + 22,
-        AccountData = Qt::UserRole + 23 // raw plugin
+        PluginName = Qt::UserRole + 15,
+        ConnectionStateRole = Qt::UserRole + 17,
+        HasConfig = Qt::UserRole + 18,
+        FactoryRole = Qt::UserRole + 19,
+        ErrorString = Qt::UserRole + 20,
+        FactoryItemRole = Qt::UserRole + 21,
+        FactoryItemIcon = Qt::UserRole + 22,
+        SipPluginData = Qt::UserRole + 23,
+        SipPluginFactoryData = Qt::UserRole + 24
     };
 
-    explicit AccountModel( QObject* parent = 0 );
-    virtual ~AccountModel();
+    explicit SipModel( QObject* parent = 0 );
+    virtual ~SipModel();
 
+    virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const;
+    virtual QModelIndex parent ( const QModelIndex& child ) const;
     virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
     virtual int rowCount( const QModelIndex& parent = QModelIndex() ) const;
+    virtual int columnCount( const QModelIndex& parent ) const;
     virtual Qt::ItemFlags flags(const QModelIndex& index) const;
     virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
 
 private slots:
-    void accountAdded( Tomahawk::Accounts::Account* p );
-    void accountRemoved( Tomahawk::Accounts::Account* p );
-    void sipStateChanged( SipPlugin::ConnectionState state  );
+    void pluginAdded( SipPlugin* p );
+    void pluginRemoved( SipPlugin* p );
+    void pluginStateChanged( SipPlugin* p );
 };
 
-}
-
-}
-
 #endif // SIPMODEL_H
diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h
index 5cb1ec7de..f0b591aa6 100644
--- a/src/libtomahawk/sip/SipPlugin.h
+++ b/src/libtomahawk/sip/SipPlugin.h
@@ -40,6 +40,9 @@ class DLLEXPORT SipPlugin : public QObject
     Q_OBJECT
 
 public:
+    enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
+    enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
+
     SipPlugin();
     explicit SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent = 0 );
     virtual ~SipPlugin();
@@ -104,7 +107,7 @@ private slots:
 
 protected:
     Tomahawk::Accounts::Account *m_account;
-
+    
 private:
     QString m_cachedError;
     QStringList m_peersOnline;
diff --git a/src/sipconfigdelegate.cpp b/src/sipconfigdelegate.cpp
new file mode 100644
index 000000000..20cfcb891
--- /dev/null
+++ b/src/sipconfigdelegate.cpp
@@ -0,0 +1,282 @@
+/*
+    Copyright (C) 2011  Leo Franchi <leo.franchi@kdab.com>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "sipconfigdelegate.h"
+
+#include <QApplication>
+#include <QPainter>
+
+#include "sip/SipModel.h"
+#include "sip/SipPlugin.h"
+
+#include "utils/tomahawkutils.h"
+#include "utils/logger.h"
+
+#define ICONSIZE 24
+#define CHECK_LEFT_EDGE 8
+
+
+SipConfigDelegate::SipConfigDelegate( QObject* parent )
+    : ConfigDelegateBase ( parent )
+{
+    connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) );
+}
+
+bool
+SipConfigDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
+{
+    return ConfigDelegateBase::editorEvent( event, model, option, index );
+}
+
+void
+SipConfigDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
+{
+    QStyleOptionViewItemV4 opt = option;
+    initStyleOption( &opt, index );
+    QRect itemRect = opt.rect;
+    int top = itemRect.top();
+    int mid = itemRect.height() / 2;
+
+    // one line bold for account name
+    // space below it fro an error
+    // checkbox, icon, name, online/offline status, config icon
+    QFont name = opt.font;
+    name.setPointSize( name.pointSize() + 2 );
+    name.setBold( true );
+
+    QFont error = opt.font;
+    error.setItalic( true );
+    error.setPointSize( error.pointSize() - 2 );
+
+    // draw the background
+    const QWidget* w = opt.widget;
+    QStyle* style = w ? w->style() : QApplication::style();
+    style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
+
+    int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING;
+    int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING;
+
+    if( index.data( SipModel::FactoryRole ).toBool() ) { // this is the "add new account" row
+        // draw a border and background
+        painter->save();
+        painter->setRenderHints( QPainter::Antialiasing );
+        painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 150 ) );
+        QPainterPath roundedRect;
+        roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 );
+        painter->drawPath( roundedRect );
+        painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) );
+        painter->fillPath( roundedRect, painter->brush() );
+        painter->restore();
+
+        // draw "+" icon in checkbox column
+        int rectW = 18;
+        int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ;
+        int pos = ( mid ) - ( rectW / 2 );
+        QRect plusRect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW );
+        QPixmap p( RESPATH "images/list-add.png" );
+        painter->drawPixmap( plusRect, p );
+
+        // draw text
+        QFont f = opt.font;
+        f.setPointSize( f.pointSize() );
+        f.setBold( true );
+        QFontMetrics fm( f );
+        QString text = index.data( Qt::DisplayRole ).toString();
+        QRect textR = fm.boundingRect( text );
+        textR.moveLeft( textLeftEdge );
+        textR.moveTop( mid - ( textR.height() / 2 ) + top );
+        textR.setRight( itemRect.right() );
+        painter->setFont( f );
+        painter->drawText( textR, text );
+    } else if( index.data( SipModel::FactoryItemRole ).toBool() ) { // this is an account type
+
+//         ConfigDelegateBase::paint( painter, opt, index );
+//         int indent = 10;
+        // draw a border and background
+        painter->save();
+        painter->setRenderHints( QPainter::Antialiasing );
+        painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) );
+        QPainterPath roundedRect;
+        roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 );
+        painter->drawPath( roundedRect );
+        painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 180 ) );
+        painter->fillPath( roundedRect, painter->brush() );
+        painter->restore();
+
+        QIcon icon = index.data( SipModel::FactoryItemIcon ).value< QIcon >();
+        if( !icon.isNull() ) {
+            int rectW = 18;
+            int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ;
+            int pos = ( mid ) - ( rectW / 2 );
+            QRect rect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW );
+            QPixmap p( icon.pixmap( rect.size() ) );
+            painter->drawPixmap( rect, p );
+        }
+
+        // draw text
+        QFont f = opt.font;
+        f.setPointSize( f.pointSize() );
+        f.setBold( true );
+        QFontMetrics fm( f );
+        QString text = index.data( Qt::DisplayRole ).toString();
+        QRect textR = fm.boundingRect( text );
+        textR.moveLeft( textLeftEdge );
+        textR.moveTop( mid - ( textR.height() / 2 ) + top );
+        textR.setRight( itemRect.right() );
+        painter->setFont( f );
+        painter->drawText( textR, text );
+    } else { // this is an existing account to show
+        // draw checkbox first
+        int pos = ( mid ) - ( ICONSIZE / 2 );
+        QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, ICONSIZE, ICONSIZE );
+        opt.rect = checkRect;
+        drawCheckBox( opt, painter, w );
+
+        // draw the icon if it exists
+        pos = ( mid ) - ( ICONSIZE / 2 );
+        if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) {
+            QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE );
+
+            painter->save();
+            painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) );
+            painter->restore();
+        }
+
+        // from the right edge--config status and online/offline
+        QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, mid - ICONSIZE / 2 + top, ICONSIZE, ICONSIZE );
+        if( index.data( SipModel::HasConfig ).toBool() ) {
+
+            QStyleOptionToolButton topt;
+            topt.rect = confRect;
+            topt.pos = confRect.topLeft();
+
+            drawConfigWrench( painter, opt, topt );
+        }
+
+        // draw the online/offline status
+        int statusIconSize = 18;
+        int statusX = confRect.left() - 2*PADDING - statusIconSize;
+        QFont statusF = opt.font;
+        statusF.setPointSize( statusF.pointSize() - 2 );
+        QFontMetrics statusFM( statusF );
+
+        QPixmap p;
+        QString statusText;
+        SipPlugin::ConnectionState state = static_cast< SipPlugin::ConnectionState >( index.data( SipModel::ConnectionStateRole ).toInt() );
+        if( state == SipPlugin::Connected ) {
+            p = QPixmap( RESPATH "images/sipplugin-online.png" );
+            statusText = tr( "Online" );
+        } else if( state == SipPlugin::Connecting ) {
+            p = QPixmap( RESPATH "images/sipplugin-offline.png" );
+            statusText = tr( "Connecting..." );
+        } else {
+            p = QPixmap( RESPATH "images/sipplugin-offline.png" );
+            statusText = tr( "Offline" );
+        }
+        p = p.scaled( statusIconSize, statusIconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation );
+        painter->drawPixmap( statusX, mid - statusIconSize / 2 + top, statusIconSize, statusIconSize, p );
+        int width = statusFM.width( statusText );
+        statusX = statusX - PADDING - width;
+        painter->save();
+        painter->setFont( statusF );
+        painter->drawText( QRect( statusX, mid - statusFM.height() / 2 + top, width, statusFM.height() ), statusText );
+        painter->restore();
+
+        // name
+        painter->save();
+        QFontMetrics namefm( name );
+        int nameHeight = namefm.boundingRect( "test" ).height();
+        // pos will the top-left point of the text rect
+        pos = mid - ( nameHeight / 2 );
+        // TODO bound with config icon and offline/online status
+        width = itemRect.width() - textLeftEdge;
+
+        if( !index.data( SipModel::ErrorString ).toString().isEmpty() ) { // error, show that too
+            QRect errorRect( textLeftEdge, mid + top, width, mid - PADDING + 1 );
+
+            QFontMetrics errorFm( error );
+            QString str = errorFm.elidedText( index.data( SipModel::ErrorString ).toString(), Qt::ElideRight, errorRect.width() );
+            painter->setFont( error );
+            painter->drawText( errorRect, str );
+
+            pos = mid - errorRect.height() - 2; // move the name rect up
+        }
+        QString nameStr = namefm.elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, width );
+        painter->setFont( name );
+        painter->drawText( QRect( textLeftEdge, pos + top, width, nameHeight + 1 ), nameStr );
+        painter->restore();
+    }
+}
+
+QRect
+SipConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const
+{
+    if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() )
+    {
+        QStyleOptionViewItemV4 opt = option;
+        initStyleOption( &opt, idx );
+        int mid = opt.rect.height() / 2;
+        int pos = ( mid ) - ( ICONSIZE / 2 );
+        QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE );
+
+        return checkRect;
+    }
+    return QRect();
+}
+
+QRect
+SipConfigDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const
+{
+    if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() )
+    {
+        QStyleOptionViewItemV4 opt = option;
+        initStyleOption( &opt, idx );
+        QRect itemRect = opt.rect;
+        QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE );
+        return confRect;
+    }
+    return QRect();
+}
+
+
+QSize
+SipConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
+{
+    if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) { // this is the "add new account" row
+        // enough space for one line of text
+        QStyleOptionViewItemV4 opt = option;
+        initStyleOption( &opt, index );
+        int width = QStyledItemDelegate::sizeHint( option, index ).width();
+
+        QFont name = opt.font;
+        name.setPointSize( name.pointSize() + 1 );
+        name.setBold( true );
+        QFontMetrics sfm( name );
+        return QSize( width, 3 * PADDING + sfm.height() );
+    } else { // this is an existing account to show
+        return ConfigDelegateBase::sizeHint( option, index );
+    }
+}
+
+void
+SipConfigDelegate::askedForEdit( const QModelIndex& idx )
+{
+    emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) );
+}
+
+
diff --git a/src/accountdelegate.h b/src/sipconfigdelegate.h
similarity index 80%
rename from src/accountdelegate.h
rename to src/sipconfigdelegate.h
index e1fba2092..cccc82a61 100644
--- a/src/accountdelegate.h
+++ b/src/sipconfigdelegate.h
@@ -21,35 +21,26 @@
 
 #include "configdelegatebase.h"
 
-namespace Tomahawk
-{
-namespace Accounts
-{
-
-class Account;
-
-class AccountDelegate : public ConfigDelegateBase
+class SipPlugin;
+class SipPluginFactory;
+class SipConfigDelegate : public ConfigDelegateBase
 {
     Q_OBJECT
 public:
-    AccountDelegate( QObject* parent = 0);
+    SipConfigDelegate( QObject* parent = 0);
 
     virtual void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
     virtual bool editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
     virtual QSize sizeHint ( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
 
-    virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx, int role ) const;
+    virtual QRect checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const;
     virtual QRect configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const;
-
-    virtual QList<int> extraCheckRoles() const { return QList<int>() << (int)AccountModel::BasicCapabilityRole; }
 private slots:
     void askedForEdit( const QModelIndex& idx );
 
 signals:
-    void openConfig( Account* );
+    void sipFactoryClicked( SipPluginFactory* );
+    void openConfig( SipPlugin* );
 };
 
-}
-}
-
 #endif // SIPCONFIGDELEGATE_H
diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp
index 18194dff8..6e48af576 100644
--- a/src/tomahawkapp.cpp
+++ b/src/tomahawkapp.cpp
@@ -505,7 +505,7 @@ void
 TomahawkApp::initSIP()
 {
     tDebug() << Q_FUNC_INFO;
-    foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->accounts() )
+    foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() )
     {
         tDebug() << Q_FUNC_INFO << "testing account with name " << account->accountServiceName();
         if ( account->configurationWidget() && account->configuration().isEmpty() )