diff --git a/resources.qrc b/resources.qrc
index acaac9674..c76ed448e 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -79,6 +79,8 @@
 <file>./data/images/add.png</file>
 <file>./data/images/recently-played.png</file>
 <file>./data/images/supercollection.png</file>
+<file>./data/images/sipplugin-online.png</file>
+<file>./data/images/sipplugin-offline.png</file>
 <file>./data/topbar-radiobuttons.css</file>
 <file>./data/icons/tomahawk-icon-16x16.png</file>
 <file>./data/icons/tomahawk-icon-32x32.png</file>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5186ddd2b..fdafa8fb1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -64,6 +64,8 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
      tomahawktrayicon.cpp
      audiocontrols.cpp
      settingsdialog.cpp
+     configdelegatebase.cpp
+     sipconfigdelegate.cpp
      resolverconfigdelegate.cpp
      resolversmodel.cpp
      tomahawkwindow.cpp
@@ -104,7 +106,9 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
      tomahawktrayicon.h
      audiocontrols.h
      settingsdialog.h
+     configdelegatebase.h
      resolverconfigdelegate.h
+     sipconfigdelegate.h
      resolversmodel.h
      resolverconfigwrapper.h
      tomahawkwindow.h
diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp
index 2434862db..a5a9290c3 100644
--- a/src/libtomahawk/sip/SipHandler.cpp
+++ b/src/libtomahawk/sip/SipHandler.cpp
@@ -195,8 +195,6 @@ SipHandler::hookUpPlugin( SipPlugin* sip )
     QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) );
     QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) );
 
-    m_allPlugins << sip;
-
     emit pluginAdded( sip );
 }
 
@@ -248,16 +246,21 @@ SipHandler::checkSettings()
 void
 SipHandler::loadFromConfig( bool startup )
 {
-    QStringList pluginIds = TomahawkSettings::instance()->enabledSipPlugins();
+    QStringList pluginIds = TomahawkSettings::instance()->sipPlugins();
+    QStringList enabled = TomahawkSettings::instance()->enabledSipPlugins();
     foreach( const QString& pluginId, pluginIds )
     {
         QString pluginFactory = factoryFromId( pluginId );
         if( m_pluginFactories.contains( pluginFactory ) )
         {
             SipPlugin* p = loadPlugin( pluginId );
-            p->connectPlugin( startup );
+            m_allPlugins << p;
 
-            m_enabledPlugins << p;
+            if ( enabled.contains( pluginId ) )
+            {
+                p->connectPlugin( startup );
+                m_enabledPlugins << p;
+            }
         }
     }
     m_connected = true;
diff --git a/src/libtomahawk/sip/SipModel.cpp b/src/libtomahawk/sip/SipModel.cpp
index 86ce30d22..b47d115de 100644
--- a/src/libtomahawk/sip/SipModel.cpp
+++ b/src/libtomahawk/sip/SipModel.cpp
@@ -23,7 +23,7 @@
 #include "sip/SipHandler.h"
 
 SipModel::SipModel( QObject* parent )
-    : QAbstractListModel( parent )
+    : QAbstractItemModel( parent )
 {
     connect( SipHandler::instance(), SIGNAL( stateChanged( SipPlugin*, SipPlugin::ConnectionState ) ), this, SLOT( pluginStateChanged( SipPlugin* ) ) );
 }
@@ -56,15 +56,15 @@ SipModel::data( const QModelIndex& index, int role ) const
     {
         case Qt::DisplayRole:
         case SipModel::PluginName:
-        {
-            p->accountName();
-        }
+            return p->accountName();
         case SipModel::ConnectionStateRole:
             return p->connectionState();
         case SipModel::HasConfig:
             return ( p->configWidget() == 0 );
         case SipModel::FactoryRole:
             return false;
+        case Qt::DecorationRole:
+            return p->icon();
         case Qt::CheckStateRole:
             return SipHandler::instance()->enabledPlugins().contains( p ) ? Qt::Checked : Qt::Unchecked;
         default:
@@ -94,11 +94,44 @@ SipModel::setData( const QModelIndex& index, const QVariant& value, int role )
     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();
+
+    // it's a child of the Add Account, e.g. a factory
+    if( hasIndex( row, column, parent ) ) {
+        createIndex( row, column, 1 /* magic */ );
+    }
+
+    return QModelIndex();
+}
+
+QModelIndex
+SipModel::parent( const QModelIndex& child ) const
+{
+    if( !child.isValid() )
+        return QModelIndex();
+
+    if( child.internalId() == 1 ) {
+        return createIndex( SipHandler::instance()->allPlugins().size() - 1, 0, 0 );
+    }
+
+    return QModelIndex();
+}
 
 int
 SipModel::rowCount( const QModelIndex& parent ) const
 {
-    return SipHandler::instance()->allPlugins().size() + 1;
+    if( !parent.isValid() ) { // top level item
+        if( parent.row() == SipHandler::instance()->allPlugins().count() ) { // last row, this is the factory
+            return SipHandler::instance()->pluginFactories().count();
+        } else {
+            return SipHandler::instance()->allPlugins().size() + 1;
+        }
+    }
+    return 0;
 }
 
 int
diff --git a/src/libtomahawk/sip/SipModel.h b/src/libtomahawk/sip/SipModel.h
index 3e46c19e1..f3f8ca07e 100644
--- a/src/libtomahawk/sip/SipModel.h
+++ b/src/libtomahawk/sip/SipModel.h
@@ -27,7 +27,7 @@
 
 class SipPlugin;
 
-class DLLEXPORT SipModel : public QAbstractListModel
+class DLLEXPORT SipModel : public QAbstractItemModel
 {
     Q_OBJECT
 public:
@@ -35,12 +35,15 @@ public:
         PluginName = Qt::UserRole + 15,
         ConnectionStateRole = Qt::UserRole + 17,
         HasConfig = Qt::UserRole + 18,
-        FactoryRole = Qt::UserRole + 19
+        FactoryRole = Qt::UserRole + 19,
+        ErrorString = Qt::UserRole + 20
     };
 
     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;
diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp
index 4f6ec7156..f10cd0710 100644
--- a/src/libtomahawk/sip/SipPlugin.cpp
+++ b/src/libtomahawk/sip/SipPlugin.cpp
@@ -52,3 +52,15 @@ SipPlugin::configWidget()
 {
     return 0;
 }
+
+QString
+SipPlugin::errorMessage() const
+{
+    return QString();
+}
+
+QIcon
+SipPlugin::icon() const
+{
+    return QIcon();
+}
diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h
index 1c1bc9fb4..470695df7 100644
--- a/src/libtomahawk/sip/SipPlugin.h
+++ b/src/libtomahawk/sip/SipPlugin.h
@@ -35,9 +35,9 @@ public:
     virtual ~SipPluginFactory() {}
 
     // display name for plugin
-    virtual QString prettyName() = 0;
+    virtual QString prettyName() const = 0;
     // internal name
-    virtual QString factoryId() = 0;
+    virtual QString factoryId() const = 0;
     virtual SipPlugin* createPlugin( const QString& pluginId = QString() ) = 0;
 
 protected:
@@ -63,8 +63,10 @@ public:
     virtual const QString friendlyName() const = 0;
     virtual const QString accountName() const = 0;
     virtual ConnectionState connectionState() const = 0;
+    virtual QString errorMessage() const;
     virtual QMenu* menu();
     virtual QWidget* configWidget();
+    virtual QIcon icon() const;
 
 public slots:
     virtual bool connectPlugin( bool startup = false ) = 0;
diff --git a/src/resolverconfigdelegate.cpp b/src/resolverconfigdelegate.cpp
index 0f98e49f8..cec5d4336 100644
--- a/src/resolverconfigdelegate.cpp
+++ b/src/resolverconfigdelegate.cpp
@@ -29,10 +29,9 @@
 #define PADDING 4
 
 ResolverConfigDelegate::ResolverConfigDelegate( QObject* parent )
-    : QStyledItemDelegate( parent )
-    , m_configPressed( false )
+    : ConfigDelegateBase( parent )
 {
-
+    connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( onConfigPressed( QModelIndex ) ) );
 }
 
 void
@@ -61,36 +60,32 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op
     style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w );
 
     int rightSplit = itemRect.width();
-    int rectW = opt.rect.height() - 4 * PADDING;
+    int rectW = 24;
     QRect confRect = QRect( rightSplit - rectW - 2 * PADDING, 2 * PADDING + top, rectW, rectW );
+
     // if the resolver has a config widget, paint it first (right-aligned)
     if( index.data( ResolversModel::HasConfig ).toBool() ) {
-        // draw it the same size as the check belox
         QStyleOptionToolButton topt;
-        topt.font = opt.font;
-        topt.icon = QIcon( RESPATH "images/configure.png" );
-        topt.iconSize = QSize( 16, 16 );
         topt.rect = confRect;
-        topt.subControls = QStyle::SC_ToolButton;
-        topt.activeSubControls = QStyle::SC_None;
-        topt.features = QStyleOptionToolButton::None;
         topt.pos = confRect.topLeft();
-        topt.state = m_configPressed ? QStyle::State_On : QStyle::State_Raised;
-        if( opt.state & QStyle::State_MouseOver || m_configPressed )
-            topt.state |= QStyle::State_HasFocus;
-        style->drawComplexControl( QStyle::CC_ToolButton, &topt, painter, w );
+
+        drawConfigWrench( painter, opt, topt );
     }
 
     // draw check
-    confRect.moveTo( 2 * PADDING, 2 * PADDING + top );
-    opt.rect = confRect;
-    opt.checkState == Qt::Checked ? opt.state |= QStyle::State_On : opt.state |= QStyle::State_Off;
-    style->drawPrimitive( QStyle::PE_IndicatorViewItemCheck, &opt, painter, w );
+    QRect checkRect = confRect;
+    checkRect.moveTo( 2 * PADDING, 2 * PADDING + top );
+    opt.rect = checkRect;
+    drawCheckBox( opt, painter, w );
     itemRect.setX( opt.rect.topRight().x() + PADDING );
 
     painter->save();
     painter->setFont( name );
     QRect textRect = itemRect.adjusted( PADDING, PADDING, -PADDING, -PADDING );
+
+    if( index.data( ResolversModel::HasConfig ).toBool() )
+        textRect.setRight( confRect.topLeft().x() - PADDING );
+
     textRect.setBottom( itemRect.height() / 2 + top  );
     QString nameStr = bfm.elidedText( index.data( ResolversModel::ResolverName ).toString(),Qt::ElideRight, textRect.width() );
     painter->drawText( textRect, nameStr );
@@ -106,71 +101,8 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op
 
 }
 
-QSize
-ResolverConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
+void
+ResolverConfigDelegate::onConfigPressed( const QModelIndex& idx )
 {
-    int width = QStyledItemDelegate::sizeHint( option, index ).width();
-
-    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, 3 * PADDING + bfm.height() + sfm.height() );
-}
-
-bool
-ResolverConfigDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
-{
-//     qDebug() << "EDITOR EVENT!" << ( event->type() == QEvent::MouseButtonRelease );
-
-    QStyleOptionViewItemV4 viewOpt( option );
-    initStyleOption( &viewOpt, index );
-    const QWidget* w = viewOpt.widget;
-    QStyle* style = w ? w->style() : QApplication::style();
-    int top = viewOpt.rect.top();
-
-    if( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick ) {
-        m_configPressed = false;
-
-        int rectW = option.rect.height() - 4 * PADDING;
-        QRect checkRect = QRect( 2 * PADDING, 2 * PADDING + top, rectW, rectW );
-        QMouseEvent* me = static_cast< QMouseEvent* >( event );
-        if( me->button() != Qt::LeftButton || !checkRect.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( 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 ) {
-        int rightSplit = viewOpt.rect.width();
-        int rectW = viewOpt.rect.height() - 4 * PADDING;
-        QRect confRect = QRect( rightSplit - rectW - 2 * PADDING, 2 * PADDING + top, rectW, rectW );
-
-        QMouseEvent* me = static_cast< QMouseEvent* >( event );
-        if( me->button() == Qt::LeftButton && confRect.contains( me->pos() ) ) {
-            m_configPressed = true;
-
-            emit openConfig( index.data( ResolversModel::ResolverPath ).toString() );
-            return true;
-        }
-    }
-
-    return QStyledItemDelegate::editorEvent( event, model, option, index );
+    emit openConfig( idx.data( ResolversModel::ResolverPath ).toString() );
 }
diff --git a/src/resolverconfigdelegate.h b/src/resolverconfigdelegate.h
index 280e63ccb..84ed8f018 100644
--- a/src/resolverconfigdelegate.h
+++ b/src/resolverconfigdelegate.h
@@ -20,23 +20,21 @@
 #ifndef RESOLVERCONFIGDELEGATE_H
 #define RESOLVERCONFIGDELEGATE_H
 
-#include <QStyledItemDelegate>
+#include "configdelegatebase.h"
 
 
-class ResolverConfigDelegate : public QStyledItemDelegate
+class ResolverConfigDelegate : public ConfigDelegateBase
 {
     Q_OBJECT
 public:
     explicit ResolverConfigDelegate(QObject* parent = 0);
     virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
-    virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
-    virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
+
+private slots:
+    void onConfigPressed ( const QModelIndex& );
 
 signals:
     void openConfig( const QString& resolverPath );
-
-private:
-    bool m_configPressed;
 };
 
 #endif // RESOLVERCONFIGDELEGATE_H
diff --git a/src/resolvers/scriptresolver.cpp b/src/resolvers/scriptresolver.cpp
index d119e9e4e..a713f186c 100644
--- a/src/resolvers/scriptresolver.cpp
+++ b/src/resolvers/scriptresolver.cpp
@@ -165,12 +165,6 @@ ScriptResolver::handleMsg( const QByteArray& msg )
                 rp->setMimetype( TomahawkUtils::extensionToMimetype( m.value( "extension" ).toString() ) );
                 Q_ASSERT( !rp->mimetype().isEmpty() );
             }
-            if ( m.contains( "year" ) )
-            {
-                QVariantMap attr;
-                attr[ "releaseyear" ] = m.value( "year" );
-                rp->setAttributes( attr );
-            }
 
             results << rp;
         }
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 409be8a7a..8fd01977c 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -44,6 +44,7 @@
 #include "resolversmodel.h"
 #include "resolverconfigwrapper.h"
 #include "sip/SipModel.h"
+#include "sipconfigdelegate.h"
 
 static QString
 md5( const QByteArray& src )
@@ -70,9 +71,9 @@ SettingsDialog::SettingsDialog( QWidget *parent )
     ui->checkBoxUpnp->setEnabled( !s->preferStaticHostPort() );
 
     // SIP PLUGINS
-//     SipPluginDelegate* ad = new SipPluginDelegate( this );
-//     ui->accountsView->setItemDelegate( ad );
-//     connect( ad, SIGNAL( openConfig( QString ) ), this, SLOT( openSipPluginConfig( QString ) ) );
+    SipConfigDelegate* sipdel = new SipConfigDelegate( this );
+    ui->accountsView->setItemDelegate( sipdel );
+//     connect( sipdel, SIGNAL( openConfig( SipPlugin* ) ), this, SLOT( openSipPluginConfig( SipPlugin* ) ) );
     m_sipModel = new SipModel( this );
     ui->accountsView->setModel( m_sipModel );
 
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index 4e153c586..ab0e58628 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -31,7 +31,20 @@
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_20">
        <item>
-        <widget class="QListView" name="accountsView"/>
+        <widget class="QTreeView" name="accountsView">
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <property name="uniformRowHeights">
+          <bool>false</bool>
+         </property>
+         <property name="animated">
+          <bool>true</bool>
+         </property>
+         <property name="headerHidden">
+          <bool>true</bool>
+         </property>
+        </widget>
        </item>
       </layout>
      </widget>