[rhythmbox] convert plugins to libpeas



commit 10d3c766781a2ae52aab23da47045849d1a3bf92
Author: Jonathan Matthew <jonathan d14n org>
Date:   Sat Apr 23 22:54:24 2011 +1000

    convert plugins to libpeas

 Makefile.am                                        |    2 +-
 configure.ac                                       |    8 +-
 plugins/Makefile.am                                |   32 +-
 .../{ => }/artdisplay/CoverArtDatabase.py          |    0
 .../{ => }/artdisplay/EmbeddedCoverArtSearch.py    |    0
 .../{ => }/artdisplay/LastFMCoverArtSearch.py      |    0
 .../{ => }/artdisplay/LocalCoverArtSearch.py       |    0
 plugins/artdisplay/Makefile.am                     |   19 +-
 .../{ => }/artdisplay/MusicBrainzCoverArtSearch.py |    0
 .../{ => }/artdisplay/PodcastCoverArtSearch.py     |    0
 ...rtdisplay.rb-plugin.in => artdisplay.plugin.in} |    5 +-
 .../{artdisplay/__init__.py => artdisplay.py}      |   49 ++-
 plugins/artdisplay/artdisplay/Makefile.am          |   11 -
 plugins/audiocd/Makefile.am                        |   11 +-
 .../{audiocd.rb-plugin.in => audiocd.plugin.in}    |    5 +-
 plugins/audiocd/rb-audiocd-plugin.c                |   74 ++--
 plugins/audiocd/rb-audiocd-source.c                |   35 +-
 plugins/audiocd/rb-audiocd-source.h                |    4 +-
 plugins/audioscrobbler/Makefile.am                 |   20 +-
 .../audioscrobbler/audioscrobbler-preferences.ui   |  139 ++----
 ...bbler.rb-plugin.in => audioscrobbler.plugin.in} |    4 +-
 plugins/audioscrobbler/rb-audioscrobbler-account.c |   13 +-
 plugins/audioscrobbler/rb-audioscrobbler-account.h |    1 +
 .../audioscrobbler/rb-audioscrobbler-play-order.c  |   13 +-
 .../audioscrobbler/rb-audioscrobbler-play-order.h  |    1 +
 plugins/audioscrobbler/rb-audioscrobbler-plugin.c  |  185 +++-----
 .../rb-audioscrobbler-profile-page.c               |   27 +-
 .../rb-audioscrobbler-profile-page.h               |    4 +-
 .../rb-audioscrobbler-radio-source.c               |   22 +-
 .../rb-audioscrobbler-radio-source.h               |    2 +
 .../rb-audioscrobbler-radio-track-entry-type.c     |   15 +-
 .../rb-audioscrobbler-radio-track-entry-type.h     |    2 +
 plugins/audioscrobbler/rb-audioscrobbler-service.c |   15 +-
 plugins/audioscrobbler/rb-audioscrobbler-service.h |    1 +
 plugins/audioscrobbler/rb-audioscrobbler-user.c    |   15 +-
 plugins/audioscrobbler/rb-audioscrobbler-user.h    |    2 +
 plugins/audioscrobbler/rb-audioscrobbler.c         |   16 +-
 plugins/audioscrobbler/rb-audioscrobbler.h         |    2 +-
 plugins/brasero-disc-recorder/Makefile.am          |    8 +-
 ...recorder.rb-plugin.in => cd-recorder.plugin.in} |    4 +-
 .../rb-disc-recorder-plugin.c                      |   79 ++--
 plugins/context/{ => }/context/AlbumTab.py         |   10 +-
 plugins/context/{ => }/context/ArtistTab.py        |   11 +-
 plugins/context/{ => }/context/ContextView.py      |   65 ++--
 plugins/context/{ => }/context/LastFM.py           |    3 +
 plugins/context/{ => }/context/LinksTab.py         |    9 +-
 plugins/context/{ => }/context/LyricsTab.py        |   10 +-
 plugins/context/Makefile.am                        |   27 +-
 .../{context.rb-plugin.in => context.plugin.in}    |    5 +-
 .../context/{context/__init__.py => context.py}    |   16 +-
 plugins/context/context/Makefile.am                |   12 -
 plugins/daap/Makefile.am                           |   28 +-
 plugins/daap/{daap.rb-plugin.in => daap.plugin.in} |    4 +-
 plugins/daap/rb-daap-container-record.c            |   22 +-
 plugins/daap/rb-daap-container-record.h            |    2 +
 plugins/daap/rb-daap-plugin.c                      |  458 ++++++++----------
 plugins/daap/rb-daap-plugin.h                      |   20 +-
 plugins/daap/rb-daap-record-factory.c              |   20 +-
 plugins/daap/rb-daap-record-factory.h              |    2 +
 plugins/daap/rb-daap-record.c                      |   26 +-
 plugins/daap/rb-daap-record.h                      |    2 +
 plugins/daap/rb-daap-source.c                      |   33 +-
 plugins/daap/rb-daap-source.h                      |    5 +-
 plugins/daap/rb-daap-src.c                         |    2 +-
 plugins/daap/rb-daap-src.h                         |    2 +-
 plugins/daap/rb-dacp-pairing-page.c                |   36 +-
 plugins/daap/rb-dacp-pairing-page.h                |    7 +-
 plugins/daap/rb-dacp-player.c                      |   19 +-
 plugins/daap/rb-dacp-player.h                      |    2 +
 plugins/daap/rb-dmap-container-db-adapter.c        |   20 +-
 plugins/daap/rb-dmap-container-db-adapter.h        |    2 +
 plugins/daap/rb-rhythmdb-dmap-db-adapter.c         |   19 +-
 plugins/daap/rb-rhythmdb-dmap-db-adapter.h         |    2 +
 .../daap/rb-rhythmdb-query-model-dmap-db-adapter.c |   21 +-
 .../daap/rb-rhythmdb-query-model-dmap-db-adapter.h |   16 +-
 plugins/dbus-media-server/Makefile.am              |    6 +-
 ...er.rb-plugin.in => dbus-media-server.plugin.in} |    4 +-
 .../rb-dbus-media-server-plugin.c                  |   43 +-
 plugins/fmradio/Makefile.am                        |   10 +-
 .../{fmradio.rb-plugin.in => fmradio.plugin.in}    |    4 +-
 plugins/fmradio/rb-fm-radio-plugin.c               |   58 +--
 plugins/fmradio/rb-fm-radio-source.c               |   21 +-
 plugins/fmradio/rb-fm-radio-source.h               |    3 +-
 plugins/fmradio/rb-radio-tuner-v4l2.c              |   14 +-
 plugins/fmradio/rb-radio-tuner.h                   |    2 +-
 plugins/generic-player/Makefile.am                 |   15 +-
 ...layer.rb-plugin.in => generic-player.plugin.in} |    5 +-
 .../rb-generic-player-playlist-source.c            |   56 +--
 .../rb-generic-player-playlist-source.h            |    3 +-
 plugins/generic-player/rb-generic-player-plugin.c  |  106 ++---
 plugins/generic-player/rb-generic-player-source.c  |   20 +-
 plugins/generic-player/rb-generic-player-source.h  |    6 +-
 plugins/generic-player/rb-nokia770-source.c        |   24 +-
 plugins/generic-player/rb-nokia770-source.h        |    6 +-
 plugins/generic-player/rb-psp-source.c             |   24 +-
 plugins/generic-player/rb-psp-source.h             |    6 +-
 plugins/im-status/Makefile.am                      |    8 +-
 ...{im-status.rb-plugin.in => im-status.plugin.in} |    4 +-
 .../{im-status/__init__.py => im-status.py}        |   23 +-
 plugins/ipod/Makefile.am                           |   12 +-
 plugins/ipod/{ipod.rb-plugin.in => ipod.plugin.in} |    4 +-
 plugins/ipod/rb-ipod-db.c                          |   13 +-
 plugins/ipod/rb-ipod-db.h                          |    1 +
 plugins/ipod/rb-ipod-plugin.c                      |   88 ++--
 plugins/ipod/rb-ipod-source.c                      |   23 +-
 plugins/ipod/rb-ipod-source.h                      |    5 +-
 plugins/ipod/rb-ipod-static-playlist-source.c      |   16 +-
 plugins/ipod/rb-ipod-static-playlist-source.h      |    2 +-
 plugins/iradio/Makefile.am                         |   17 +-
 .../{iradio.rb-plugin.in => iradio.plugin.in}      |    5 +-
 plugins/iradio/rb-iradio-plugin.c                  |   67 +--
 plugins/iradio/rb-iradio-source-search.c           |   12 +-
 plugins/iradio/rb-iradio-source-search.h           |    2 +
 plugins/iradio/rb-iradio-source.c                  |   39 +-
 plugins/iradio/rb-iradio-source.h                  |    5 +-
 plugins/iradio/rb-station-properties-dialog.c      |   28 +-
 plugins/iradio/rb-station-properties-dialog.h      |    5 +-
 .../{ => }/jamendo/JamendoConfigureDialog.py       |   28 +-
 .../jamendo/{ => }/jamendo/JamendoSaxHandler.py    |    0
 plugins/jamendo/{ => }/jamendo/JamendoSource.py    |   29 +-
 plugins/jamendo/Makefile.am                        |   17 +-
 plugins/jamendo/jamendo-prefs.ui                   |  275 ++++--------
 .../{jamendo.rb-plugin.in => jamendo.plugin.in}    |    5 +-
 .../jamendo/{jamendo/__init__.py => jamendo.py}    |   41 +-
 plugins/jamendo/jamendo/Makefile.am                |    8 -
 plugins/lirc/Makefile.am                           |   13 +-
 plugins/lirc/{lirc.rb-plugin.in => lirc.plugin.in} |    4 +-
 plugins/lirc/rb-lirc-plugin.c                      |   63 ++--
 plugins/lyrics/{ => }/lyrics/AstrawebParser.py     |    6 +-
 plugins/lyrics/{ => }/lyrics/DarkLyricsParser.py   |    5 +-
 plugins/lyrics/{ => }/lyrics/LeoslyricsParser.py   |    6 +-
 plugins/lyrics/{ => }/lyrics/LyrcParser.py         |    0
 plugins/lyrics/{ => }/lyrics/LyricWikiParser.py    |    0
 .../lyrics/{ => }/lyrics/LyricsConfigureDialog.py  |   29 +-
 plugins/lyrics/{ => }/lyrics/LyricsParse.py        |    0
 plugins/lyrics/{ => }/lyrics/LyricsSites.py        |    0
 plugins/lyrics/Makefile.am                         |   30 +-
 plugins/lyrics/{ => }/lyrics/TerraParser.py        |    0
 plugins/lyrics/{ => }/lyrics/WinampcnParser.py     |    0
 plugins/lyrics/lyrics-prefs.ui                     |  249 ++++------
 .../{lyrics.rb-plugin.in => lyrics.plugin.in}      |    5 +-
 plugins/lyrics/{lyrics/__init__.py => lyrics.py}   |   37 +-
 plugins/lyrics/lyrics/Makefile.am                  |   15 -
 .../magnatune/{ => }/magnatune/BuyAlbumHandler.py  |    0
 .../magnatune/{ => }/magnatune/MagnatuneSource.py  |   84 ++--
 plugins/magnatune/Makefile.am                      |   18 +-
 .../magnatune/{ => }/magnatune/TrackListHandler.py |    0
 plugins/magnatune/magnatune-prefs.ui               |  500 +++++++++-----------
 ...{magnatune.rb-plugin.in => magnatune.plugin.in} |    5 +-
 .../{magnatune/__init__.py => magnatune.py}        |  201 ++++----
 plugins/magnatune/magnatune/Makefile.am            |    8 -
 plugins/mmkeys/Makefile.am                         |    6 +-
 .../{mmkeys.rb-plugin.in => mmkeys.plugin.in}      |    5 +-
 plugins/mmkeys/rb-mmkeys-plugin.c                  |   43 +-
 plugins/mpris/Makefile.am                          |    6 +-
 .../mpris/{mpris.rb-plugin.in => mpris.plugin.in}  |    4 +-
 plugins/mpris/rb-mpris-plugin.c                    |   64 ++--
 plugins/mtpdevice/Makefile.am                      |   12 +-
 ...{mtpdevice.rb-plugin.in => mtpdevice.plugin.in} |    4 +-
 plugins/mtpdevice/rb-mtp-gst-sink.c                |    2 +-
 plugins/mtpdevice/rb-mtp-gst-src.c                 |    2 +-
 plugins/mtpdevice/rb-mtp-plugin.c                  |   86 ++--
 plugins/mtpdevice/rb-mtp-source.c                  |   22 +-
 plugins/mtpdevice/rb-mtp-source.h                  |    5 +-
 plugins/mtpdevice/rb-mtp-thread.c                  |   12 +-
 plugins/mtpdevice/rb-mtp-thread.h                  |    1 +
 plugins/notification/Makefile.am                   |    9 +-
 ...ication.rb-plugin.in => notification.plugin.in} |    4 +-
 plugins/notification/rb-notification-plugin.c      |   51 +-
 plugins/power-manager/Makefile.am                  |    6 +-
 ...anager.rb-plugin.in => power-manager.plugin.in} |    5 +-
 plugins/power-manager/rb-power-manager-plugin.c    |   65 ++--
 plugins/pythonconsole/Makefile.am                  |    6 +-
 ...onsole.rb-plugin.in => pythonconsole.plugin.in} |    4 +-
 plugins/pythonconsole/pythonconsole.py             |   33 +-
 plugins/rb-plugin-macros.h                         |   99 ++++
 plugins/rb/Loader.py                               |    2 +-
 plugins/rb/Makefile.am                             |    3 +-
 plugins/rb/rb.plugin                               |    7 +
 plugins/rb/{__init__.py => rb.py}                  |   14 +-
 plugins/rbzeitgeist/Makefile.am                    |    8 +-
 ...eitgeist.rb-plugin.in => rbzeitgeist.plugin.in} |    5 +-
 .../{rbzeitgeist/__init__.py => rbzeitgeist.py}    |   37 +-
 plugins/replaygain/Makefile.am                     |   15 +-
 plugins/replaygain/{ => }/replaygain/config.py     |   22 +-
 plugins/replaygain/{ => }/replaygain/player.py     |    0
 ...eplaygain.rb-plugin.in => replaygain.plugin.in} |    5 +-
 .../{replaygain/__init__.py => replaygain.py}      |   26 +-
 plugins/replaygain/replaygain/Makefile.am          |    6 -
 plugins/sample-python/Makefile.am                  |    8 +-
 ...python.rb-plugin.in => sample-python.plugin.in} |    4 +-
 plugins/sample-python/sample-python.py             |   21 +-
 plugins/sample-vala/Makefile.am                    |    6 +-
 plugins/sample-vala/rb-sample-vala-plugin.vala     |   12 +-
 ...ple-vala.rb-plugin.in => sample-vala.plugin.in} |    4 +-
 plugins/sample/Makefile.am                         |    8 +-
 plugins/sample/rb-sample-plugin.c                  |   70 +--
 .../{sample.rb-plugin.in => sample.plugin.in}      |    4 +-
 plugins/sendto/Makefile.am                         |    8 +-
 .../{sendto.rb-plugin.in => sendto.plugin.in}      |    5 +-
 plugins/sendto/{__init__.py => sendto.py}          |   16 +-
 shell/rb-shell.c                                   |    2 +-
 202 files changed, 2569 insertions(+), 2584 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 38967c4..fb6eeac 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ DISTCHECK_CONFIGURE_FLAGS = --disable-schemas-install --enable-gtk-doc --disable
 distuninstallcheck_listfiles = find . -type f -print | grep -v '^\./var/scrollkeeper'
 
 SUBDIRS = macros lib metadata rhythmdb widgets sources podcast \
-	backends shell bindings remote data po help tests doc
+	backends shell bindings plugins remote data po help tests doc
 
 INCLUDES = rhythmbox.h
 
diff --git a/configure.ac b/configure.ac
index bfead77..124b1a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -634,7 +634,9 @@ PLUGIN_LIBTOOL_FLAGS="-module -avoid-version"
 AC_SUBST(PLUGIN_LIBTOOL_FLAGS)
 
 PLUGINDIR='${libdir}/rhythmbox/plugins'
+PLUGINDATADIR='${datadir}/rhythmbox/plugins'
 AC_SUBST(PLUGINDIR)
+AC_SUBST(PLUGINDATADIR)
 
 dnl ================================================================
 dnl Python plugins
@@ -829,25 +831,19 @@ plugins/mtpdevice/Makefile
 plugins/iradio/Makefile
 plugins/lirc/Makefile
 plugins/lyrics/Makefile
-plugins/lyrics/lyrics/Makefile
 plugins/sample-python/Makefile
 plugins/sample-vala/Makefile
 plugins/pythonconsole/Makefile
 plugins/artdisplay/Makefile
-plugins/artdisplay/artdisplay/Makefile
 plugins/magnatune/Makefile
-plugins/magnatune/magnatune/Makefile
 plugins/jamendo/Makefile
-plugins/jamendo/jamendo/Makefile
 plugins/generic-player/Makefile
 plugins/rb/Makefile
 plugins/power-manager/Makefile
 plugins/mmkeys/Makefile
 plugins/context/Makefile
-plugins/context/context/Makefile
 plugins/sendto/Makefile
 plugins/replaygain/Makefile
-plugins/replaygain/replaygain/Makefile
 plugins/mpris/Makefile
 plugins/dbus-media-server/Makefile
 plugins/rbzeitgeist/Makefile
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 084bed1..6d42f16 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,4 +1,7 @@
-SUBDIRS = 						\
+pluginincludedir = $(includedir)/rhythmbox/plugins
+plugininclude_HEADERS = rb-plugin-macros.h
+
+SUBDIRS =						\
 	audiocd						\
 	dbus-media-server				\
 	generic-player					\
@@ -8,25 +11,22 @@ SUBDIRS = 						\
 	power-manager					\
 	sample
 
-if WITH_LIRC
-SUBDIRS += lirc
-endif
-
 if ENABLE_PYTHON
-SUBDIRS += 						\
-	pythonconsole					\
-	sample-python					\
+SUBDIRS +=						\
 	artdisplay					\
+	context						\
+	im-status					\
+	jamendo						\
 	lyrics						\
 	magnatune					\
-	jamendo						\
-	coherence					\
-	im-status					\
-	context						\
-	sendto						\
-	replaygain					\
+	pythonconsole					\
 	rbzeitgeist					\
+	replaygain					\
+	sample-python					\
+	sendto						\
 	rb
+
+# coherence
 endif
 
 if ENABLE_VALA
@@ -34,6 +34,10 @@ SUBDIRS +=						\
 	sample-vala
 endif
 
+if WITH_LIRC
+SUBDIRS += lirc
+endif
+
 if USE_IPOD
 SUBDIRS += ipod
 endif
diff --git a/plugins/artdisplay/artdisplay/CoverArtDatabase.py b/plugins/artdisplay/CoverArtDatabase.py
similarity index 100%
rename from plugins/artdisplay/artdisplay/CoverArtDatabase.py
rename to plugins/artdisplay/CoverArtDatabase.py
diff --git a/plugins/artdisplay/artdisplay/EmbeddedCoverArtSearch.py b/plugins/artdisplay/EmbeddedCoverArtSearch.py
similarity index 100%
rename from plugins/artdisplay/artdisplay/EmbeddedCoverArtSearch.py
rename to plugins/artdisplay/EmbeddedCoverArtSearch.py
diff --git a/plugins/artdisplay/artdisplay/LastFMCoverArtSearch.py b/plugins/artdisplay/LastFMCoverArtSearch.py
similarity index 100%
rename from plugins/artdisplay/artdisplay/LastFMCoverArtSearch.py
rename to plugins/artdisplay/LastFMCoverArtSearch.py
diff --git a/plugins/artdisplay/artdisplay/LocalCoverArtSearch.py b/plugins/artdisplay/LocalCoverArtSearch.py
similarity index 100%
rename from plugins/artdisplay/artdisplay/LocalCoverArtSearch.py
rename to plugins/artdisplay/LocalCoverArtSearch.py
diff --git a/plugins/artdisplay/Makefile.am b/plugins/artdisplay/Makefile.am
index 8ffb46c..02bf92f 100644
--- a/plugins/artdisplay/Makefile.am
+++ b/plugins/artdisplay/Makefile.am
@@ -1,15 +1,22 @@
 # Art Display Python Plugin
 
-SUBDIRS = artdisplay
-
 plugindir = $(PLUGINDIR)/artdisplay
+plugindatadir = $(PLUGINDATADIR)/artdisplay
+plugin_PYTHON = 			\
+	EmbeddedCoverArtSearch.py	\
+	PodcastCoverArtSearch.py	\
+	LastFMCoverArtSearch.py		\
+	LocalCoverArtSearch.py		\
+	CoverArtDatabase.py		\
+	MusicBrainzCoverArtSearch.py	\
+	artdisplay.py
 
-plugin_in_files = artdisplay.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = artdisplay.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
-artworkdir = $(plugindir)
+artworkdir = $(plugindatadir)
 artwork_DATA = rhythmbox-missing-artwork.svg lastfm_red_small.png
 
 EXTRA_DIST = $(plugin_in_files) $(artwork_DATA)
diff --git a/plugins/artdisplay/artdisplay/MusicBrainzCoverArtSearch.py b/plugins/artdisplay/MusicBrainzCoverArtSearch.py
similarity index 100%
rename from plugins/artdisplay/artdisplay/MusicBrainzCoverArtSearch.py
rename to plugins/artdisplay/MusicBrainzCoverArtSearch.py
diff --git a/plugins/artdisplay/artdisplay/PodcastCoverArtSearch.py b/plugins/artdisplay/PodcastCoverArtSearch.py
similarity index 100%
rename from plugins/artdisplay/artdisplay/PodcastCoverArtSearch.py
rename to plugins/artdisplay/PodcastCoverArtSearch.py
diff --git a/plugins/artdisplay/artdisplay.rb-plugin.in b/plugins/artdisplay/artdisplay.plugin.in
similarity index 89%
rename from plugins/artdisplay/artdisplay.rb-plugin.in
rename to plugins/artdisplay/artdisplay.plugin.in
index fa819ce..7b6918d 100644
--- a/plugins/artdisplay/artdisplay.rb-plugin.in
+++ b/plugins/artdisplay/artdisplay.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=artdisplay
-IAge=1
+IAge=2
+Depends=rb
 _Name=Cover art
 _Description=Fetch album covers from the Internet
 Authors=James Livingston <doclivingston gmail com>
diff --git a/plugins/artdisplay/artdisplay/__init__.py b/plugins/artdisplay/artdisplay.py
similarity index 95%
rename from plugins/artdisplay/artdisplay/__init__.py
rename to plugins/artdisplay/artdisplay.py
index 5fc303a..9263e6b 100644
--- a/plugins/artdisplay/artdisplay/__init__.py
+++ b/plugins/artdisplay/artdisplay.py
@@ -32,7 +32,7 @@ from warnings import warn
 from CoverArtDatabase import CoverArtDatabase
 
 import rb
-from gi.repository import Gtk, Gdk, GdkPixbuf, Gio
+from gi.repository import Gtk, Gdk, GdkPixbuf, Gio, Peas
 from gi.repository import RB
 
 FADE_STEPS = 10
@@ -368,19 +368,22 @@ class ArtDisplayWidget (FadingImage):
 gobject.type_register (ArtDisplayWidget)
 
 
-class ArtDisplayPlugin (RB.Plugin):
+class ArtDisplayPlugin (gobject.GObject, Peas.Activatable):
+	__gtype_name__ = 'ArtDisplayPlugin'
+	object = gobject.property(type=gobject.GObject)
+
 	def __init__ (self):
-		RB.Plugin.__init__ (self)
+		gobject.GObject.__init__ (self)
 
-	def activate (self, shell):
-		self.shell = shell
-		sp = shell.get_player ()
+	def do_activate (self):
+		shell = self.object
+		sp = shell.props.shell_player
 		self.player_cb_ids = (
 			sp.connect ('playing-song-changed', self.playing_entry_changed),
 			sp.connect ('playing-changed', self.playing_changed)
 		)
 		self.emitting_uri_notify = False
-		db = shell.get_property ("db")
+		db = shell.props.db
 		self.db_cb_ids = (
 			db.connect_after ('entry-extra-metadata-request::rb:coverArt', self.cover_art_request),
 			db.connect_after ('entry-extra-metadata-notify::rb:coverArt', self.cover_art_notify),
@@ -388,7 +391,7 @@ class ArtDisplayPlugin (RB.Plugin):
 			db.connect_after ('entry-extra-metadata-notify::rb:coverArt-uri', self.cover_art_uri_notify),
 			db.connect_after ('entry-extra-metadata-gather', self.cover_art_uri_gather),
 		)
-		self.art_widget = ArtDisplayWidget (self.find_file (ART_MISSING_ICON + ".svg"))
+		self.art_widget = ArtDisplayWidget (rb.find_plugin_file (self, ART_MISSING_ICON + ".svg"))
 		self.art_widget.connect ('pixbuf-dropped', self.on_set_pixbuf)
 		self.art_widget.connect ('uri-dropped', self.on_set_uri)
 		self.art_widget.connect ('get-max-size', self.get_max_art_size)
@@ -400,15 +403,15 @@ class ArtDisplayPlugin (RB.Plugin):
 		self.current_entry, self.current_pixbuf = None, None
 		self.playing_entry_changed (sp, sp.get_playing_entry ())
 
-	def deactivate (self, shell):
-		self.shell = None
+	def do_deactivate (self):
 
-		sp = shell.get_player ()
+		shell = self.object
+		sp = shell.props.shell_player
 		for id in self.player_cb_ids:
 			sp.disconnect (id)
 		self.player_cb_ids = ()
 
-		db = shell.get_property ("db")
+		db = shell.props.db
 		for id in self.db_cb_ids:
 			db.disconnect (id)
 		self.db_cb_ids = ()
@@ -416,6 +419,7 @@ class ArtDisplayPlugin (RB.Plugin):
 		shell.remove_widget (self.art_container, RB.ShellUILocation.SIDEBAR)
 		self.art_widget.disconnect_handlers ()
 		self.art_widget = None
+		self.art_container = None
 		self.art_db = None
 
 	def playing_changed (self, sp, playing):
@@ -433,7 +437,9 @@ class ArtDisplayPlugin (RB.Plugin):
 		# Intitates search in the database (which checks art cache, internet etc.)
 		self.current_entry = entry
 		self.current_pixbuf = None
-		db = self.shell.get_property ("db")
+
+		shell = self.object
+		db = shell.props.db
 		self.art_db.get_pixbuf(db, entry, True, self.on_get_pixbuf_completed)
 
 	def on_get_pixbuf_completed(self, entry, pixbuf, uri, tooltip_image, tooltip_text):
@@ -446,7 +452,7 @@ class ArtDisplayPlugin (RB.Plugin):
 			elif tooltip_image.startswith("/"):
 				pb = GdkPixbuf.Pixbuf.new_from_file(tooltip_image)
 			else:
-				f = self.find_file(tooltip_image)
+				f = rb.find_plugin_file (self, tooltip_image)
 				pb = GdkPixbuf.Pixbuf.new_from_file(f)
 			self.art_widget.set (entry, pixbuf, uri, pb, tooltip_text, False)
 
@@ -454,7 +460,8 @@ class ArtDisplayPlugin (RB.Plugin):
 			# This might be from a playing-changed signal,
 			# in which case consumers won't be ready yet.
 			def idle_emit_art():
-				db = self.shell.get_property ("db")
+				shell = self.object
+				db = shell.props.db
 				db.emit_entry_extra_metadata_notify (entry, "rb:coverArt", pixbuf)
 				if uri:
 					self.emitting_uri_notify = True
@@ -545,17 +552,20 @@ class ArtDisplayPlugin (RB.Plugin):
 			metadata ['rb:coverArt-uri'] = self.art_widget.current_uri
 
 	def on_set_pixbuf (self, widget, entry, pixbuf):
-		db = self.shell.get_property ("db")
+		shell = self.object
+		db = shell.props.db
 		self.art_db.set_pixbuf (db, entry, pixbuf, self.on_get_pixbuf_completed)
 
 	def on_set_uri (self, widget, entry, uri):
-		db = self.shell.get_property ("db")
+		shell = self.object
+		db = shell.props.db
 		self.art_db.set_pixbuf_from_uri (db, entry, uri, self.on_get_pixbuf_completed)
 
 	def get_max_art_size (self, widget):
 		# limit the art image to a third of the window height to prevent it from
 		# forcing the window to resize, obscuring everything else, and so on.
-		(width, height) = self.shell.props.window.get_size()
+		shell = self.object
+		(width, height) = shell.props.window.get_size()
 		return height / 3
 
 	def on_button_press (self, widget, event):
@@ -570,4 +580,5 @@ class ArtDisplayPlugin (RB.Plugin):
 			return
 
 		f = Gio.file_new_for_uri(self.art_widget.current_uri)
-		Gtk.show_uri(self.shell.props.window.get_screen(), f.get_uri(), event.time)
+		shell = self.object
+		Gtk.show_uri(shell.props.window.get_screen(), f.get_uri(), event.time)
diff --git a/plugins/audiocd/Makefile.am b/plugins/audiocd/Makefile.am
index 3a81ca2..ea3d1c4 100644
--- a/plugins/audiocd/Makefile.am
+++ b/plugins/audiocd/Makefile.am
@@ -1,4 +1,5 @@
 plugindir = $(PLUGINDIR)/audiocd
+plugindatadir = $(PLUGINDATADIR)/audiocd
 plugin_LTLIBRARIES = libaudiocd.la
 
 libaudiocd_la_SOURCES =					\
@@ -53,19 +54,19 @@ endif
 libaudiocd_la_LIBADD += $(NULL)
 
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA = 					\
 	album-info.ui					\
 	multiple-album.ui
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = audiocd-ui.xml
 
-plugin_in_files = audiocd.rb-plugin.in
+plugin_in_files = audiocd.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(gtkbuilder_DATA) $(uixml_DATA) $(plugin_in_files) sj-metadata-marshal.list
 
diff --git a/plugins/audiocd/audiocd.rb-plugin.in b/plugins/audiocd/audiocd.plugin.in
similarity index 89%
rename from plugins/audiocd/audiocd.rb-plugin.in
rename to plugins/audiocd/audiocd.plugin.in
index b086c04..ad334ba 100644
--- a/plugins/audiocd/audiocd.rb-plugin.in
+++ b/plugins/audiocd/audiocd.plugin.in
@@ -1,6 +1,7 @@
-[RB Plugin]
+[Plugin]
 Module=audiocd
-IAge=1
+IAge=2
+Builtin=true
 _Name=Audio CD Player
 _Description=Support for playing of audio CDs as music source
 Authors=James Livingston, Jonathan Matthew
diff --git a/plugins/audiocd/rb-audiocd-plugin.c b/plugins/audiocd/rb-audiocd-plugin.c
index 2297506..33a23d8 100644
--- a/plugins/audiocd/rb-audiocd-plugin.c
+++ b/plugins/audiocd/rb-audiocd-plugin.c
@@ -41,7 +41,7 @@
 
 #include <gst/gst.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-shell-player.h"
@@ -50,6 +50,7 @@
 #include "rb-audiocd-source.h"
 #include "rb-player.h"
 #include "rb-encoder.h"
+#include "rb-file-helpers.h"
 
 
 #define RB_TYPE_AUDIOCD_PLUGIN		(rb_audiocd_plugin_get_type ())
@@ -61,7 +62,7 @@
 
 typedef struct
 {
-	RBPlugin    parent;
+	PeasExtensionBase parent;
 
 	RBShell    *shell;
 	guint       ui_merge_id;
@@ -72,33 +73,16 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBAudioCdPluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 GType	rb_audiocd_plugin_get_type		(void) G_GNUC_CONST;
 
 static void rb_audiocd_plugin_init (RBAudioCdPlugin *plugin);
-static void rb_audiocd_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
-RB_PLUGIN_REGISTER(RBAudioCdPlugin, rb_audiocd_plugin)
-
-static void
-rb_audiocd_plugin_class_init (RBAudioCdPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_audiocd_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-
-	RB_PLUGIN_REGISTER_TYPE(rb_audiocd_source);
-}
+RB_DEFINE_PLUGIN(RB_TYPE_AUDIOCD_PLUGIN, RBAudioCdPlugin, rb_audiocd_plugin,)
 
 static void
 rb_audiocd_plugin_init (RBAudioCdPlugin *plugin)
@@ -107,16 +91,6 @@ rb_audiocd_plugin_init (RBAudioCdPlugin *plugin)
 }
 
 static void
-rb_audiocd_plugin_finalize (GObject *object)
-{
-/*
-	RBAudioCdPlugin *plugin = RB_AUDIOCD_PLUGIN (object);
-*/
-	rb_debug ("RBAudioCdPlugin finalising");
-	G_OBJECT_CLASS (rb_audiocd_plugin_parent_class)->finalize (object);
-}
-
-static void
 rb_audiocd_plugin_playing_uri_changed_cb (RBShellPlayer   *player,
 					  const char      *uri,
 					  RBAudioCdPlugin *plugin)
@@ -249,12 +223,15 @@ create_source_cb (RBRemovableMediaManager *rmm,
 {
 	RBSource *source = NULL;
 	GVolume *volume = NULL;
+	RBShell *shell;
+
+	g_object_get (plugin, "object", &shell, NULL);
 
 	if (rb_audiocd_is_mount_audiocd (mount)) {
 
 		volume = g_mount_get_volume (mount);
 		if (volume != NULL) {
-			source = rb_audiocd_source_new (RB_PLUGIN (plugin), plugin->shell, volume);
+			source = rb_audiocd_source_new (G_OBJECT (plugin), shell, volume);
 			g_object_unref (volume);
 		}
 	}
@@ -269,9 +246,9 @@ create_source_cb (RBRemovableMediaManager *rmm,
 			char *filename;
 			GtkUIManager *uimanager;
 
-			g_object_get (plugin->shell, "ui-manager", &uimanager, NULL);
+			g_object_get (shell, "ui-manager", &uimanager, NULL);
 
-			filename = rb_plugin_find_file (RB_PLUGIN (plugin), "audiocd-ui.xml");
+			filename = rb_find_plugin_data_file (G_OBJECT (plugin), "audiocd-ui.xml");
 			if (filename != NULL) {
 				plugin->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager, filename, NULL);
 				gtk_ui_manager_ensure_update (uimanager);
@@ -284,25 +261,26 @@ create_source_cb (RBRemovableMediaManager *rmm,
 		}
 	}
 
+	g_object_unref (shell);
 	return source;
 }
 
 static void
-impl_activate (RBPlugin *plugin,
-	       RBShell  *shell)
+impl_activate (PeasActivatable *plugin)
 {
 	RBAudioCdPlugin         *pi = RB_AUDIOCD_PLUGIN (plugin);
 	RBRemovableMediaManager *rmm;
 	gboolean                 scanned;
 	GObject                 *shell_player;
 	RBPlayer                *player_backend;
+	RBShell                 *shell;
 
 	pi->sources = g_hash_table_new_full (g_direct_hash,
 					     g_direct_equal,
 					     g_object_unref,
 					     g_object_unref);
 
-	pi->shell = shell;
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell, "removable-media-manager", &rmm, NULL);
 
 
@@ -359,6 +337,8 @@ impl_activate (RBPlugin *plugin,
 	g_signal_connect_object (shell_player, "playing-uri-changed",
 				 G_CALLBACK (rb_audiocd_plugin_playing_uri_changed_cb),
 				 plugin, 0);
+
+	g_object_unref (shell);
 }
 
 static void
@@ -374,14 +354,15 @@ _delete_cb (GVolume         *volume,
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell  *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBAudioCdPlugin         *plugin = RB_AUDIOCD_PLUGIN (bplugin);
 	RBRemovableMediaManager *rmm = NULL;
 	GtkUIManager            *uimanager = NULL;
+	RBShell                 *shell;
 
-	g_object_get (G_OBJECT (shell),
+	g_object_get (plugin, "object", &shell, NULL);
+	g_object_get (shell,
 		      "removable-media-manager", &rmm,
 		      "ui-manager", &uimanager,
 		      NULL);
@@ -397,4 +378,15 @@ impl_deactivate	(RBPlugin *bplugin,
 
 	g_object_unref (uimanager);
 	g_object_unref (rmm);
+	g_object_unref (shell);
+}
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_audiocd_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_audiocd_source_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_AUDIOCD_PLUGIN);
 }
diff --git a/plugins/audiocd/rb-audiocd-source.c b/plugins/audiocd/rb-audiocd-source.c
index 9c36402..3a96579 100644
--- a/plugins/audiocd/rb-audiocd-source.c
+++ b/plugins/audiocd/rb-audiocd-source.c
@@ -39,7 +39,6 @@
 #include <gst/gst.h>
 #include <gst/cdda/gstcddabasesrc.h>
 
-#include "rb-plugin.h"
 #include "rhythmdb.h"
 #include "rb-shell.h"
 #include "rb-audiocd-source.h"
@@ -47,6 +46,7 @@
 #include "rb-debug.h"
 #include "rb-dialog.h"
 #include "rb-builder-helpers.h"
+#include "rb-file-helpers.h"
 
 #ifdef HAVE_SJ_METADATA_GETTER
 #include "sj-metadata-getter.h"
@@ -139,18 +139,16 @@ typedef struct
 	GtkActionGroup *action_group;
 } RBAudioCdSourcePrivate;
 
-RB_PLUGIN_DEFINE_TYPE (RBAudioCdSource, rb_audiocd_source, RB_TYPE_REMOVABLE_MEDIA_SOURCE)
+G_DEFINE_DYNAMIC_TYPE (RBAudioCdSource, rb_audiocd_source, RB_TYPE_REMOVABLE_MEDIA_SOURCE)
 #define AUDIOCD_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOCD_SOURCE, RBAudioCdSourcePrivate))
 
 /* entry type */
 typedef struct _RhythmDBEntryType RBAudioCdEntryType;
 typedef struct _RhythmDBEntryTypeClass RBAudioCdEntryTypeClass;
 
-static void rb_audiocd_entry_type_class_init (RBAudioCdEntryTypeClass *klass);
-static void rb_audiocd_entry_type_init (RBAudioCdEntryType *etype);
 GType rb_audiocd_entry_type_get_type (void);
 
-G_DEFINE_TYPE (RBAudioCdEntryType, rb_audiocd_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
+G_DEFINE_DYNAMIC_TYPE (RBAudioCdEntryType, rb_audiocd_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
 
 #ifdef HAVE_SJ_METADATA_GETTER
 static AlbumDetails* multiple_album_dialog (GList *albums, RBAudioCdSource *source);
@@ -176,6 +174,11 @@ rb_audiocd_entry_type_class_init (RBAudioCdEntryTypeClass *klass)
 }
 
 static void
+rb_audiocd_entry_type_class_finalize (RBAudioCdEntryTypeClass *klass)
+{
+}
+
+static void
 rb_audiocd_entry_type_init (RBAudioCdEntryType *etype)
 {
 }
@@ -232,6 +235,11 @@ rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
 }
 
 static void
+rb_audiocd_source_class_finalize (RBAudioCdSourceClass *klass)
+{
+}
+
+static void
 rb_audiocd_source_init (RBAudioCdSource *self)
 {
 }
@@ -304,7 +312,7 @@ rb_audiocd_source_constructed (GObject *object)
 	GtkTreeViewColumn *extract;
 	GtkWidget *widget;
 	GtkAction *action;
-	RBPlugin *plugin;
+	GObject *plugin;
 	RBShell *shell;
 	char *ui_file;
 	int toggle_width;
@@ -379,7 +387,7 @@ rb_audiocd_source_constructed (GObject *object)
 
 	/* set up the album info widgets */
 	g_object_get (source, "plugin", &plugin, NULL);
-	ui_file = rb_plugin_find_file (plugin, "album-info.ui");
+	ui_file = rb_find_plugin_data_file (G_OBJECT (plugin), "album-info.ui");
 	g_object_unref (plugin);
 
 	if (ui_file == NULL) {
@@ -446,7 +454,7 @@ rb_audiocd_source_constructed (GObject *object)
 }
 
 RBSource *
-rb_audiocd_source_new (RBPlugin *plugin,
+rb_audiocd_source_new (GObject *plugin,
 		       RBShell *shell,
 		       GVolume *volume)
 {
@@ -732,7 +740,7 @@ multiple_album_dialog (GList *albums, RBAudioCdSource *source)
 	GtkBuilder *builder;
 	GtkTreeViewColumn *column;
 	GtkCellRenderer *text_renderer;
-	RBPlugin *plugin;
+	GObject *plugin;
 	char *builder_file;
 
 	gdk_threads_enter ();
@@ -741,7 +749,7 @@ multiple_album_dialog (GList *albums, RBAudioCdSource *source)
 	g_assert (plugin != NULL);
 
 	/* create dialog */
-	builder_file = rb_plugin_find_file (plugin, "multiple-album.ui");
+	builder_file = rb_find_plugin_data_file (plugin, "multiple-album.ui");
 	g_object_unref (plugin);
 
 	if (builder_file == NULL) {
@@ -1438,3 +1446,10 @@ copy_tracks_cmd (GtkAction *action, RBAudioCdSource *source)
 	g_object_unref (model);
 	g_object_unref (library);
 }
+
+void
+_rb_audiocd_source_register_type (GTypeModule *module)
+{
+	rb_audiocd_source_register_type (module);
+	rb_audiocd_entry_type_register_type (module);
+}
diff --git a/plugins/audiocd/rb-audiocd-source.h b/plugins/audiocd/rb-audiocd-source.h
index 870d271..e18f496 100644
--- a/plugins/audiocd/rb-audiocd-source.h
+++ b/plugins/audiocd/rb-audiocd-source.h
@@ -51,11 +51,11 @@ typedef struct
 	RBRemovableMediaSourceClass parent;
 } RBAudioCdSourceClass;
 
-RBSource *		rb_audiocd_source_new			(RBPlugin *plugin,
+RBSource *		rb_audiocd_source_new			(GObject *plugin,
 								 RBShell  *shell,
 								 GVolume  *volume);
 GType			rb_audiocd_source_get_type		(void);
-GType			rb_audiocd_source_register_type		(GTypeModule *module);
+void			_rb_audiocd_source_register_type	(GTypeModule *module);
 
 gboolean		rb_audiocd_is_mount_audiocd		(GMount *mount);
 
diff --git a/plugins/audioscrobbler/Makefile.am b/plugins/audioscrobbler/Makefile.am
index fbcff38..e9d611b 100644
--- a/plugins/audioscrobbler/Makefile.am
+++ b/plugins/audioscrobbler/Makefile.am
@@ -1,6 +1,7 @@
 NULL =
 
 plugindir = $(PLUGINDIR)/audioscrobbler
+plugindatadir = $(PLUGINDATADIR)/audioscrobbler
 plugin_LTLIBRARIES = libaudioscrobbler.la
 
 libaudioscrobbler_la_SOURCES = \
@@ -55,26 +56,29 @@ INCLUDES = 						\
 	$(GNOME_KEYRING_CFLAGS)				\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA =					\
 	audioscrobbler-preferences.ui			\
 	audioscrobbler-profile.ui
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA =						\
 	audioscrobbler-profile-ui.xml			\
 	audioscrobbler-radio-ui.xml
 
-plugin_in_files = audioscrobbler.rb-plugin.in
+plugin_in_files = audioscrobbler.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-BUILT_SOURCES =							\
-	$(plugin_in_files:.rb-plugin.in=.rb-plugin) 		\
+BUILT_SOURCES =						\
+	$(plugin_in_files:.plugin.in=.plugin) 		\
 	$(NULL)
 
-plugin_DATA = 					\
-	$(BUILT_SOURCES)			\
+plugin_DATA =							\
+	$(BUILT_SOURCES)					\
+	$(NULL)
+
+plugindata_DATA = 						\
 	$(top_srcdir)/plugins/audioscrobbler/Last.fm-icon.png	\
 	$(top_srcdir)/plugins/audioscrobbler/Libre.fm-icon.png	\
 	$(NULL)
diff --git a/plugins/audioscrobbler/audioscrobbler-preferences.ui b/plugins/audioscrobbler/audioscrobbler-preferences.ui
index dbd8f3c..0668ed8 100644
--- a/plugins/audioscrobbler/audioscrobbler-preferences.ui
+++ b/plugins/audioscrobbler/audioscrobbler-preferences.ui
@@ -2,27 +2,47 @@
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
-  <object class="GtkDialog" id="config_dialog">
-    <property name="border_width">5</property>
-    <property name="resizable">False</property>
-    <property name="destroy_with_parent">True</property>
-    <property name="type_hint">normal</property>
-    <signal name="response" handler="config_dialog_response_cb"/>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+  <object class="GtkVBox" id="config">
+    <property name="visible">True</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">4</property>
+    <child>
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Which Audioscrobbler services do you wish to use?</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkHBox" id="hbox2">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
         <child>
-          <object class="GtkVBox" id="vbox1">
+          <object class="GtkLabel" id="label2">
+            <property name="visible">True</property>
+            <property name="xpad">8</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox2">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
-            <property name="spacing">4</property>
             <child>
-              <object class="GtkLabel" id="label1">
+              <object class="GtkCheckButton" id="lastfm_enabled_check">
+                <property name="label" translatable="yes">Last.fm</property>
                 <property name="visible">True</property>
-                <property name="xalign">0</property>
-                <property name="label" translatable="yes">Which Audioscrobbler services do you wish to use?</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="image">lastfm_image</property>
+                <property name="draw_indicator">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -31,99 +51,30 @@
               </packing>
             </child>
             <child>
-              <object class="GtkHBox" id="hbox1">
-                <property name="visible">True</property>
-                <child>
-                  <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="xpad">8</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox2">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <object class="GtkCheckButton" id="lastfm_enabled_check">
-                        <property name="label" translatable="yes">Last.fm</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="image">lastfm_image</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="lastfm_enabled_check_toggled_cb"/>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkCheckButton" id="librefm_enabled_check">
-                        <property name="label" translatable="yes">Libre.fm</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="image">librefm_image</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="librefm_enabled_check_toggled_cb"/>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="button1">
-                <property name="label">gtk-close</property>
+              <object class="GtkCheckButton" id="librefm_enabled_check">
+                <property name="label" translatable="yes">Libre.fm</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
+                <property name="receives_default">False</property>
+                <property name="image">librefm_image</property>
+                <property name="draw_indicator">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
-                <property name="position">0</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
     </child>
-    <action-widgets>
-      <action-widget response="0">button1</action-widget>
-    </action-widgets>
   </object>
   <object class="GtkImage" id="lastfm_image">
     <property name="visible">True</property>
diff --git a/plugins/audioscrobbler/audioscrobbler.rb-plugin.in b/plugins/audioscrobbler/audioscrobbler.plugin.in
similarity index 94%
rename from plugins/audioscrobbler/audioscrobbler.rb-plugin.in
rename to plugins/audioscrobbler/audioscrobbler.plugin.in
index fb11d3f..5cc1631 100644
--- a/plugins/audioscrobbler/audioscrobbler.rb-plugin.in
+++ b/plugins/audioscrobbler/audioscrobbler.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=audioscrobbler
-IAge=1
+IAge=2
 _Name=Last.fm
 _Description=Submits song information to Last.fm and plays Last.fm radio streams
 Icon=as-powered.png
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.c b/plugins/audioscrobbler/rb-audioscrobbler-account.c
index 80b060c..d50ef00 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.c
@@ -112,7 +112,7 @@ enum
 
 static guint rb_audioscrobbler_account_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (RBAudioscrobblerAccount, rb_audioscrobbler_account, G_TYPE_OBJECT)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerAccount, rb_audioscrobbler_account, G_TYPE_OBJECT)
 
 RBAudioscrobblerAccount *
 rb_audioscrobbler_account_new (RBAudioscrobblerService *service)
@@ -189,6 +189,11 @@ rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass)
 }
 
 static void
+rb_audioscrobbler_account_class_finalize (RBAudioscrobblerAccountClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_account_init (RBAudioscrobblerAccount *account)
 {
 	account->priv = RB_AUDIOSCROBBLER_ACCOUNT_GET_PRIVATE (account);
@@ -729,3 +734,9 @@ rb_audioscrobbler_account_login_status_get_type (void)
 
 	return etype;
 }
+
+void
+_rb_audioscrobbler_account_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_account_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.h b/plugins/audioscrobbler/rb-audioscrobbler-account.h
index 8e49dac..1575725 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.h
@@ -72,6 +72,7 @@ typedef struct
 } RBAudioscrobblerAccountClass;
 
 GType                           rb_audioscrobbler_account_get_type (void);
+void				_rb_audioscrobbler_account_register_type (GTypeModule *module);
 
 RBAudioscrobblerAccount *       rb_audioscrobbler_account_new (RBAudioscrobblerService *service);
 
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-play-order.c b/plugins/audioscrobbler/rb-audioscrobbler-play-order.c
index 2c12dd8..72f5dc1 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-play-order.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-play-order.c
@@ -32,7 +32,7 @@
 
 static void rb_audioscrobbler_play_order_class_init (RBAudioscrobblerPlayOrderClass *klass);
 
-G_DEFINE_TYPE (RBAudioscrobblerPlayOrder, rb_audioscrobbler_play_order, RB_TYPE_PLAY_ORDER)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerPlayOrder, rb_audioscrobbler_play_order, RB_TYPE_PLAY_ORDER)
 
 RBPlayOrder *
 rb_audioscrobbler_play_order_new (RBShellPlayer *player)
@@ -93,3 +93,14 @@ rb_audioscrobbler_play_order_class_init (RBAudioscrobblerPlayOrderClass *klass)
 	porder->get_previous = rb_audioscrobbler_play_order_get_previous;
 }
 
+
+static void
+rb_audioscrobbler_play_order_class_finalize (RBAudioscrobblerPlayOrderClass *klass)
+{
+}
+
+void
+_rb_audioscrobbler_play_order_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_play_order_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-play-order.h b/plugins/audioscrobbler/rb-audioscrobbler-play-order.h
index 406ac73..3f94644 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-play-order.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-play-order.h
@@ -52,6 +52,7 @@ typedef struct
 } RBAudioscrobblerPlayOrderClass;
 
 GType			rb_audioscrobbler_play_order_get_type	(void);
+void			_rb_audioscrobbler_play_order_register_type (GTypeModule *module);
 
 RBPlayOrder *		rb_audioscrobbler_play_order_new	(RBShellPlayer *player);
 
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-plugin.c b/plugins/audioscrobbler/rb-audioscrobbler-plugin.c
index 793a62b..1dee83c 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-plugin.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-plugin.c
@@ -35,14 +35,23 @@
 #include <glib.h>
 #include <glib-object.h>
 
+#include <libpeas-gtk/peas-gtk.h>
+
 #include <lib/rb-builder-helpers.h>
 #include <lib/rb-debug.h>
+#include <lib/rb-file-helpers.h>
 #include <sources/rb-display-page-group.h>
-#include <shell/rb-plugin.h>
+#include <plugins/rb-plugin-macros.h>
 #include <shell/rb-shell.h>
 
-#include "rb-audioscrobbler-service.h"
+#include "rb-audioscrobbler-account.h"
+#include "rb-audioscrobbler.h"
+#include "rb-audioscrobbler-play-order.h"
 #include "rb-audioscrobbler-profile-page.h"
+#include "rb-audioscrobbler-radio-source.h"
+#include "rb-audioscrobbler-radio-track-entry-type.h"
+#include "rb-audioscrobbler-service.h"
+#include "rb-audioscrobbler-user.h"
 
 #define RB_TYPE_AUDIOSCROBBLER_PLUGIN		(rb_audioscrobbler_plugin_get_type ())
 #define RB_AUDIOSCROBBLER_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_AUDIOSCROBBLER_PLUGIN, RBAudioscrobblerPlugin))
@@ -53,8 +62,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
-	RBShell *shell;
+	PeasExtensionBase parent;
 
 	GtkWidget *config_dialog;
 
@@ -71,94 +79,60 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBAudioscrobblerPluginClass;
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_audioscrobbler_plugin_get_type		(void) G_GNUC_CONST;
-
-static void rb_audioscrobbler_plugin_init (RBAudioscrobblerPlugin *plugin);
-static void rb_audioscrobbler_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
-static GtkWidget *impl_create_configure_dialog (RBPlugin *bplugin);
-static void init_config_dialog (RBAudioscrobblerPlugin *plugin);
-void config_dialog_response_cb (GtkWidget *dialog, gint response,
-                                RBAudioscrobblerPlugin *plugin);
-void lastfm_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
-                                      RBAudioscrobblerPlugin *plugin);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
+
+static GtkWidget *impl_create_configure_widget (PeasGtkConfigurable *bplugin);
+static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface);
+
 static void lastfm_settings_changed_cb (GSettings *settings,
 					const char *key,
 					RBAudioscrobblerPlugin *plugin);
-void librefm_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
-                                       RBAudioscrobblerPlugin *plugin);
 static void librefm_settings_changed_cb (GSettings *settings,
 					 const char *key,
 					 RBAudioscrobblerPlugin *plugin);
 
-RB_PLUGIN_REGISTER(RBAudioscrobblerPlugin, rb_audioscrobbler_plugin)
-
-static void
-rb_audioscrobbler_plugin_class_init (RBAudioscrobblerPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_audioscrobbler_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-	plugin_class->create_configure_dialog = impl_create_configure_dialog;
-}
+RB_DEFINE_PLUGIN(RB_TYPE_AUDIOSCROBBLER_PLUGIN,
+		 RBAudioscrobblerPlugin,
+		 rb_audioscrobbler_plugin,
+		 (G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE,
+						peas_gtk_configurable_iface_init)))
 
 static void
 rb_audioscrobbler_plugin_init (RBAudioscrobblerPlugin *plugin)
 {
 	rb_debug ("RBAudioscrobblerPlugin initialising");
-}
 
-static void
-rb_audioscrobbler_plugin_finalize (GObject *object)
-{
-	rb_debug ("RBAudioscrobblerPlugin finalising");
-
-	G_OBJECT_CLASS (rb_audioscrobbler_plugin_parent_class)->finalize (object);
+	plugin->lastfm_settings = g_settings_new_with_path (AUDIOSCROBBLER_SETTINGS_SCHEMA,
+							    AUDIOSCROBBLER_SETTINGS_PATH "/Last.fm");
+	plugin->librefm_settings = g_settings_new_with_path (AUDIOSCROBBLER_SETTINGS_SCHEMA,
+							     AUDIOSCROBBLER_SETTINGS_PATH "/Libre.fm");
 }
 
 static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
-	gboolean enabled;
 	RBAudioscrobblerPlugin *plugin;
 
 	plugin = RB_AUDIOSCROBBLER_PLUGIN (bplugin);
 
-	plugin->shell = shell;
-	init_config_dialog (plugin);
-
-	plugin->lastfm_settings = g_settings_new_with_path (AUDIOSCROBBLER_SETTINGS_SCHEMA,
-							    AUDIOSCROBBLER_SETTINGS_PATH "/Last.fm");
 	g_signal_connect_object (plugin->lastfm_settings,
 				 "changed",
 				 G_CALLBACK (lastfm_settings_changed_cb),
 				 plugin, 0);
-	enabled = g_settings_get_boolean (plugin->lastfm_settings, AUDIOSCROBBLER_SERVICE_ENABLED_KEY);
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->lastfm_enabled_check), enabled);
+	lastfm_settings_changed_cb (plugin->lastfm_settings, AUDIOSCROBBLER_SERVICE_ENABLED_KEY, plugin);
 
-	plugin->librefm_settings = g_settings_new_with_path (AUDIOSCROBBLER_SETTINGS_SCHEMA,
-							     AUDIOSCROBBLER_SETTINGS_PATH "/Libre.fm");
 	g_signal_connect_object (plugin->librefm_settings,
 				 "changed",
 				 G_CALLBACK (librefm_settings_changed_cb),
 				 plugin, 0);
-	enabled = g_settings_get_boolean (plugin->librefm_settings, AUDIOSCROBBLER_SERVICE_ENABLED_KEY);
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->librefm_enabled_check), enabled);
+	librefm_settings_changed_cb (plugin->librefm_settings, AUDIOSCROBBLER_SERVICE_ENABLED_KEY, plugin);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBAudioscrobblerPlugin *plugin = RB_AUDIOSCROBBLER_PLUGIN (bplugin);
 
@@ -189,61 +163,40 @@ impl_deactivate	(RBPlugin *bplugin,
 }
 
 static GtkWidget *
-impl_create_configure_dialog (RBPlugin *bplugin)
+impl_create_configure_widget (PeasGtkConfigurable *bplugin)
 {
 	RBAudioscrobblerPlugin *plugin;
-	plugin = RB_AUDIOSCROBBLER_PLUGIN (bplugin);
-
-	if (plugin->config_dialog == NULL) {
-		init_config_dialog (plugin);
-	}
-
-	gtk_widget_show_all (plugin->config_dialog);
-	return plugin->config_dialog;
-}
-
-static void
-init_config_dialog (RBAudioscrobblerPlugin *plugin)
-{
 	char *builderfile;
 	GtkBuilder *builder;
+	GtkWidget *widget;
 
-	if (plugin->config_dialog != NULL) {
-		return;
-	}
+	plugin = RB_AUDIOSCROBBLER_PLUGIN (bplugin);
 
-	builderfile = rb_plugin_find_file (RB_PLUGIN (plugin), "audioscrobbler-preferences.ui");
+	builderfile = rb_find_plugin_data_file (G_OBJECT (plugin), "audioscrobbler-preferences.ui");
 	if (builderfile == NULL) {
 		g_warning ("can't find audioscrobbler-preferences.ui");
-		return;
+		return NULL;
 	}
 
 	builder = rb_builder_load (builderfile, plugin);
 	g_free (builderfile);
 
-	plugin->config_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "config_dialog"));
-	gtk_widget_hide_on_delete (plugin->config_dialog);
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "config"));
+	g_object_ref_sink (widget);
 
 	plugin->lastfm_enabled_check = GTK_WIDGET (gtk_builder_get_object (builder, "lastfm_enabled_check"));
+	g_settings_bind (plugin->lastfm_settings, AUDIOSCROBBLER_SERVICE_ENABLED_KEY, plugin->lastfm_enabled_check, "active", G_SETTINGS_BIND_DEFAULT);
 	plugin->librefm_enabled_check = GTK_WIDGET (gtk_builder_get_object (builder, "librefm_enabled_check"));
+	g_settings_bind (plugin->librefm_settings, AUDIOSCROBBLER_SERVICE_ENABLED_KEY, plugin->librefm_enabled_check, "active", G_SETTINGS_BIND_DEFAULT);
 
 	g_object_unref (builder);
+	return widget;
 }
 
-void
-config_dialog_response_cb (GtkWidget *dialog, gint response,
-                           RBAudioscrobblerPlugin *plugin)
-{
-	gtk_widget_hide (dialog);
-}
-
-void
-lastfm_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
-                                 RBAudioscrobblerPlugin *plugin)
+static void
+peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface)
 {
-	g_settings_set_boolean (plugin->lastfm_settings,
-				AUDIOSCROBBLER_SERVICE_ENABLED_KEY,
-				gtk_toggle_button_get_active (togglebutton));
+	iface->create_configure_widget = impl_create_configure_widget;
 }
 
 static void
@@ -257,14 +210,16 @@ lastfm_settings_changed_cb (GSettings *settings,
 	}
 
 	enabled = g_settings_get_boolean (settings, key);
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->lastfm_enabled_check),
-	                              enabled);
 	if (enabled == TRUE && plugin->lastfm_page == NULL) {
 		RBAudioscrobblerService *lastfm;
+		RBShell *shell;
+
 		lastfm = rb_audioscrobbler_service_new_lastfm ();
-		plugin->lastfm_page = rb_audioscrobbler_profile_page_new (plugin->shell,
-		                                                          RB_PLUGIN (plugin),
+		g_object_get (plugin, "object", &shell, NULL);
+		plugin->lastfm_page = rb_audioscrobbler_profile_page_new (shell,
+		                                                          G_OBJECT (plugin),
 		                                                          lastfm);
+		g_object_unref (shell);
 		g_object_unref (lastfm);
 	} else if (enabled == FALSE && plugin->lastfm_page != NULL) {
 		rb_display_page_delete_thyself (plugin->lastfm_page);
@@ -272,15 +227,6 @@ lastfm_settings_changed_cb (GSettings *settings,
 	}
 }
 
-void
-librefm_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
-                                  RBAudioscrobblerPlugin *plugin)
-{
-	g_settings_set_boolean (plugin->librefm_settings,
-				AUDIOSCROBBLER_SERVICE_ENABLED_KEY,
-				gtk_toggle_button_get_active (togglebutton));
-}
-
 static void
 librefm_settings_changed_cb (GSettings *settings,
 			     const char *key,
@@ -292,19 +238,40 @@ librefm_settings_changed_cb (GSettings *settings,
 	}
 
 	enabled = g_settings_get_boolean (settings, key);
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->librefm_enabled_check),
-	                              enabled);
-
 	if (enabled == TRUE && plugin->librefm_page == NULL) {
 		RBAudioscrobblerService *librefm;
+		RBShell *shell;
 
 		librefm = rb_audioscrobbler_service_new_librefm ();
-		plugin->librefm_page = rb_audioscrobbler_profile_page_new (plugin->shell,
-		                                                           RB_PLUGIN (plugin),
+		g_object_get (plugin, "object", &shell, NULL);
+		plugin->librefm_page = rb_audioscrobbler_profile_page_new (shell,
+		                                                           G_OBJECT (plugin),
 		                                                           librefm);
 		g_object_unref (librefm);
+		g_object_unref (shell);
 	} else if (enabled == FALSE && plugin->librefm_page != NULL) {
 		rb_display_page_delete_thyself (plugin->librefm_page);
 		plugin->librefm_page = NULL;
 	}
 }
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_audioscrobbler_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_account_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_play_order_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_profile_page_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_radio_source_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_radio_track_entry_type_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_service_register_type (G_TYPE_MODULE (module));
+	_rb_audioscrobbler_user_register_type (G_TYPE_MODULE (module));
+
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_AUDIOSCROBBLER_PLUGIN);
+	peas_object_module_register_extension_type (module,
+						    PEAS_GTK_TYPE_CONFIGURABLE,
+						    RB_TYPE_AUDIOSCROBBLER_PLUGIN);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c
index 457c0f1..fd10dd3 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-page.c
@@ -117,8 +117,6 @@ struct _RBAudioscrobblerProfilePagePrivate {
 };
 
 
-static void rb_audioscrobbler_profile_page_class_init (RBAudioscrobblerProfilePageClass *klass);
-static void rb_audioscrobbler_profile_page_init (RBAudioscrobblerProfilePage *page);
 static void rb_audioscrobbler_profile_page_constructed (GObject *object);
 static void rb_audioscrobbler_profile_page_dispose (GObject* object);
 static void rb_audioscrobbler_profile_page_finalize (GObject *object);
@@ -253,10 +251,10 @@ static GtkActionEntry profile_actions [] =
 };
 
 
-G_DEFINE_TYPE (RBAudioscrobblerProfilePage, rb_audioscrobbler_profile_page, RB_TYPE_DISPLAY_PAGE)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerProfilePage, rb_audioscrobbler_profile_page, RB_TYPE_DISPLAY_PAGE)
 
 RBDisplayPage *
-rb_audioscrobbler_profile_page_new (RBShell *shell, RBPlugin *plugin, RBAudioscrobblerService *service)
+rb_audioscrobbler_profile_page_new (RBShell *shell, GObject *plugin, RBAudioscrobblerService *service)
 {
 	RBDisplayPage *page;
 	RhythmDB *db;
@@ -270,7 +268,7 @@ rb_audioscrobbler_profile_page_new (RBShell *shell, RBPlugin *plugin, RBAudioscr
 	g_object_get (service, "name", &name, NULL);
 
 	icon_name = g_strconcat (rb_audioscrobbler_service_get_name (service), "-icon.png", NULL);
-	icon_path = rb_plugin_find_file (plugin, icon_name);
+	icon_path = rb_find_plugin_data_file (plugin, icon_name);
 	gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR, &icon_size, NULL);
 	icon_pixbuf = gdk_pixbuf_new_from_file_at_size (icon_path, icon_size, icon_size, NULL);
 
@@ -323,6 +321,11 @@ rb_audioscrobbler_profile_page_class_init (RBAudioscrobblerProfilePageClass *kla
 }
 
 static void
+rb_audioscrobbler_profile_page_class_finalize (RBAudioscrobblerProfilePageClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_profile_page_init (RBAudioscrobblerProfilePage *page)
 {
 	page->priv = G_TYPE_INSTANCE_GET_PRIVATE (page, RB_TYPE_AUDIOSCROBBLER_PROFILE_PAGE, RBAudioscrobblerProfilePagePrivate);
@@ -528,7 +531,7 @@ init_login_ui (RBAudioscrobblerProfilePage *page)
 static void
 init_profile_ui (RBAudioscrobblerProfilePage *page)
 {
-	RBPlugin *plugin;
+	GObject *plugin;
 	char *builder_file;
 	GtkBuilder *builder;
 	GtkWidget *combo_container;
@@ -536,7 +539,7 @@ init_profile_ui (RBAudioscrobblerProfilePage *page)
 
 	g_object_get (page, "plugin", &plugin, NULL);
 
-	builder_file = rb_plugin_find_file (plugin, "audioscrobbler-profile.ui");
+	builder_file = rb_find_plugin_data_file (plugin, "audioscrobbler-profile.ui");
 	g_assert (builder_file != NULL);
 	builder = rb_builder_load (builder_file, page);
 
@@ -598,13 +601,13 @@ init_actions (RBAudioscrobblerProfilePage *page)
 	char *ui_file;
 	RBShell *shell;
 	RBShellPlayer *player;
-	RBPlugin *plugin;
+	GObject *plugin;
 	GtkUIManager *ui_manager;
 	RhythmDBEntry *entry;
 	char *group_name;
 
 	g_object_get (page, "shell", &shell, "plugin", &plugin, "ui-manager", &ui_manager, NULL);
-	ui_file = rb_plugin_find_file (plugin, "audioscrobbler-profile-ui.xml");
+	ui_file = rb_find_plugin_data_file (plugin, "audioscrobbler-profile-ui.xml");
 	page->priv->ui_merge_id = gtk_ui_manager_add_ui_from_file (ui_manager, ui_file, NULL);
 
 	page->priv->profile_action_group = _rb_display_page_register_action_group (RB_DISPLAY_PAGE (page),
@@ -1951,3 +1954,9 @@ impl_delete_thyself (RBDisplayPage *bpage)
 
 	g_object_unref (ui_manager);
 }
+
+void
+_rb_audioscrobbler_profile_page_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_profile_page_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-page.h b/plugins/audioscrobbler/rb-audioscrobbler-profile-page.h
index 056281a..fc27c6b 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-page.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-page.h
@@ -32,7 +32,6 @@
 #include <sources/rb-display-page.h>
 #include <sources/rb-source.h>
 #include <shell/rb-shell.h>
-#include <shell/rb-plugin.h>
 
 #include "rb-audioscrobbler-service.h"
 
@@ -60,8 +59,9 @@ typedef struct
 } RBAudioscrobblerProfilePageClass;
 
 GType 		rb_audioscrobbler_profile_page_get_type (void);
+void 		_rb_audioscrobbler_profile_page_register_type (GTypeModule *module);
 RBDisplayPage  *rb_audioscrobbler_profile_page_new (RBShell *shell,
-						    RBPlugin *plugin,
+						    GObject *plugin,
 						    RBAudioscrobblerService *service);
 void 		rb_audioscrobbler_profile_page_remove_radio_station (RBAudioscrobblerProfilePage *page,
 								     RBSource *station);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
index c505a99..958148c 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
@@ -47,6 +47,7 @@
 #include "rb-debug.h"
 #include "rb-display-page-tree.h"
 #include "rb-util.h"
+#include "rb-file-helpers.h"
 
 
 /* radio type stuff */
@@ -195,8 +196,6 @@ struct _RBAudioscrobblerRadioSourcePrivate
 
 #define RB_AUDIOSCROBBLER_RADIO_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_RADIO_SOURCE, RBAudioscrobblerRadioSourcePrivate))
 
-static void rb_audioscrobbler_radio_source_class_init (RBAudioscrobblerRadioSourceClass *klass);
-static void rb_audioscrobbler_radio_source_init (RBAudioscrobblerRadioSource *source);
 static void rb_audioscrobbler_radio_source_constructed (GObject *object);
 static void rb_audioscrobbler_radio_source_dispose (GObject *object);
 static void rb_audioscrobbler_radio_source_finalize (GObject *object);
@@ -295,7 +294,7 @@ static GtkActionEntry rb_audioscrobbler_radio_source_actions [] =
 	  G_CALLBACK (delete_station_action_cb) }
 };
 
-G_DEFINE_TYPE (RBAudioscrobblerRadioSource, rb_audioscrobbler_radio_source, RB_TYPE_STREAMING_SOURCE)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerRadioSource, rb_audioscrobbler_radio_source, RB_TYPE_STREAMING_SOURCE)
 
 RBSource *
 rb_audioscrobbler_radio_source_new (RBAudioscrobblerProfilePage *parent,
@@ -307,7 +306,7 @@ rb_audioscrobbler_radio_source_new (RBAudioscrobblerProfilePage *parent,
 {
 	RBSource *source;
 	RBShell *shell;
-	RBPlugin *plugin;
+	GObject *plugin;
 	RhythmDB *db;
 
 	g_object_get (parent, "shell", &shell, "plugin", &plugin, NULL);
@@ -414,6 +413,11 @@ rb_audioscrobbler_radio_source_class_init (RBAudioscrobblerRadioSourceClass *kla
 }
 
 static void
+rb_audioscrobbler_radio_source_class_finalize (RBAudioscrobblerRadioSourceClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_radio_source_init (RBAudioscrobblerRadioSource *source)
 {
 	source->priv = RB_AUDIOSCROBBLER_RADIO_SOURCE_GET_PRIVATE (source);
@@ -435,7 +439,7 @@ rb_audioscrobbler_radio_source_constructed (GObject *object)
 	GtkWidget *error_info_bar_content_area;
 	GtkWidget *password_info_bar_label;
 	GtkWidget *password_info_bar_content_area;
-	RBPlugin *plugin;
+	GObject *plugin;
 	GtkUIManager *ui_manager;
 	char *ui_file;
 
@@ -511,7 +515,7 @@ rb_audioscrobbler_radio_source_constructed (GObject *object)
 
 	/* merge ui */
 	g_object_get (source, "plugin", &plugin, "ui-manager", &ui_manager, NULL);
-	ui_file = rb_plugin_find_file (plugin, "audioscrobbler-radio-ui.xml");
+	ui_file = rb_find_plugin_data_file (plugin, "audioscrobbler-radio-ui.xml");
 	source->priv->ui_merge_id = gtk_ui_manager_add_ui_from_file (ui_manager, ui_file, NULL);
 
 	/* actions */
@@ -1546,3 +1550,9 @@ impl_delete_thyself (RBDisplayPage *page)
 	g_object_unref (ui_manager);
 	g_object_unref (db);
 }
+
+void
+_rb_audioscrobbler_radio_source_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_radio_source_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.h b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.h
index c0cdc12..f38d857 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.h
@@ -77,6 +77,8 @@ typedef struct
 } RBAudioscrobblerRadioSourceClass;
 
 GType rb_audioscrobbler_radio_source_get_type (void);
+void _rb_audioscrobbler_radio_source_register_type (GTypeModule *module);
+
 RBSource *rb_audioscrobbler_radio_source_new (RBAudioscrobblerProfilePage *parent,
                                               RBAudioscrobblerService *service,
                                               const char *username,
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.c b/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.c
index 5201588..021b2d7 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.c
@@ -31,11 +31,9 @@
 typedef struct _RhythmDBEntryType RBAudioscrobblerRadioEntryType;
 typedef struct _RhythmDBEntryTypeClass RBAudioscrobblerRadioEntryTypeClass;
 
-static void rb_audioscrobbler_radio_entry_type_class_init (RBAudioscrobblerRadioEntryTypeClass *klass);
-static void rb_audioscrobbler_radio_entry_type_init (RBAudioscrobblerRadioEntryType *etype);
 GType rb_audioscrobbler_radio_entry_type_get_type (void);
 
-G_DEFINE_TYPE (RBAudioscrobblerRadioEntryType, rb_audioscrobbler_radio_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerRadioEntryType, rb_audioscrobbler_radio_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
 
 static RhythmDBEntryType *radio_track_entry_type = NULL;
 
@@ -58,6 +56,11 @@ rb_audioscrobbler_radio_entry_type_class_init (RBAudioscrobblerRadioEntryTypeCla
 }
 
 static void
+rb_audioscrobbler_radio_entry_type_class_finalize (RBAudioscrobblerRadioEntryTypeClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_radio_entry_type_init (RBAudioscrobblerRadioEntryType *etype)
 {
 }
@@ -83,3 +86,9 @@ rb_audioscrobbler_radio_track_register_entry_type (RhythmDB *db)
 
 	rhythmdb_register_entry_type (db, radio_track_entry_type);
 }
+
+void
+_rb_audioscrobbler_radio_track_entry_type_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_radio_entry_type_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.h b/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.h
index 3c8e758..5d0f54c 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-radio-track-entry-type.h
@@ -48,6 +48,8 @@ RhythmDBEntryType *rb_audioscrobbler_radio_track_get_entry_type (void);
 
 void rb_audioscrobbler_radio_track_register_entry_type (RhythmDB *db);
 
+void _rb_audioscrobbler_radio_track_entry_type_register_type (GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* #ifndef __RB_AUDIOSCROBBLER_RADIO_TRACK_ENTRY_TYPE_H */
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-service.c b/plugins/audioscrobbler/rb-audioscrobbler-service.c
index c5bfe24..b3bd80a 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-service.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-service.c
@@ -58,8 +58,6 @@ struct _RBAudioscrobblerServicePrivate {
 
 #define RB_AUDIOSCROBBLER_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_SERVICE, RBAudioscrobblerServicePrivate))
 
-static void rb_audioscrobbler_service_class_init (RBAudioscrobblerServiceClass *klass);
-static void rb_audioscrobbler_service_init (RBAudioscrobblerService *service);
 static void rb_audioscrobbler_service_finalize (GObject *object);
 static void rb_audioscrobbler_service_get_property (GObject *object,
                                                     guint prop_id,
@@ -82,7 +80,7 @@ enum
 	PROP_API_SECRET,
 };
 
-G_DEFINE_TYPE (RBAudioscrobblerService, rb_audioscrobbler_service, G_TYPE_OBJECT)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerService, rb_audioscrobbler_service, G_TYPE_OBJECT)
 
 RBAudioscrobblerService *
 rb_audioscrobbler_service_new_lastfm (void)
@@ -182,6 +180,11 @@ rb_audioscrobbler_service_class_init (RBAudioscrobblerServiceClass *klass)
 }
 
 static void
+rb_audioscrobbler_service_class_finalize (RBAudioscrobblerServiceClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_service_init (RBAudioscrobblerService *service)
 {
 	service->priv = RB_AUDIOSCROBBLER_SERVICE_GET_PRIVATE (service);
@@ -323,3 +326,9 @@ rb_audioscrobbler_service_get_api_secret (RBAudioscrobblerService *service)
 {
 	return service->priv->api_secret;
 }
+
+void
+_rb_audioscrobbler_service_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_service_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-service.h b/plugins/audioscrobbler/rb-audioscrobbler-service.h
index 5ac91c8..45edf53 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-service.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-service.h
@@ -60,6 +60,7 @@ typedef struct {
 } RBAudioscrobblerServiceClass;
 
 GType rb_audioscrobbler_service_get_type (void);
+void _rb_audioscrobbler_service_register_type (GTypeModule *module);
 
 RBAudioscrobblerService *rb_audioscrobbler_service_new_lastfm (void);
 RBAudioscrobblerService *rb_audioscrobbler_service_new_librefm (void);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-user.c b/plugins/audioscrobbler/rb-audioscrobbler-user.c
index 81f5889..cd9f619 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-user.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-user.c
@@ -134,8 +134,6 @@ struct _RBAudioscrobblerUserPrivate {
 
 #define RB_AUDIOSCROBBLER_USER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_USER, RBAudioscrobblerUserPrivate))
 
-static void rb_audioscrobbler_user_class_init (RBAudioscrobblerUserClass *klass);
-static void rb_audioscrobbler_user_init (RBAudioscrobblerUser *user);
 static void rb_audioscrobbler_user_constructed (GObject *object);
 static void rb_audioscrobbler_user_dispose (GObject* object);
 static void rb_audioscrobbler_user_finalize (GObject *object);
@@ -242,7 +240,7 @@ enum {
 
 static guint rb_audioscrobbler_user_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (RBAudioscrobblerUser, rb_audioscrobbler_user, G_TYPE_OBJECT)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobblerUser, rb_audioscrobbler_user, G_TYPE_OBJECT)
 
 RBAudioscrobblerUser *
 rb_audioscrobbler_user_new (RBAudioscrobblerService *service)
@@ -342,6 +340,11 @@ rb_audioscrobbler_user_class_init (RBAudioscrobblerUserClass *klass)
 }
 
 static void
+rb_audioscrobbler_user_class_finalize (RBAudioscrobblerUserClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_user_init (RBAudioscrobblerUser *user)
 {
 	user->priv = RB_AUDIOSCROBBLER_USER_GET_PRIVATE (user);
@@ -1789,3 +1792,9 @@ ban_track_response_cb (SoupSession *session,
 	 * might want a debug message indicating success or failure?
 	 */
 }
+
+void
+_rb_audioscrobbler_user_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_user_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-user.h b/plugins/audioscrobbler/rb-audioscrobbler-user.h
index 6b6d176..d8dcaac 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-user.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-user.h
@@ -88,6 +88,8 @@ typedef struct
 } RBAudioscrobblerUserClass;
 
 GType rb_audioscrobbler_user_get_type (void);
+void _rb_audioscrobbler_user_register_type (GTypeModule *module);
+
 RBAudioscrobblerUser *rb_audioscrobbler_user_new (RBAudioscrobblerService *service);
 
 void rb_audioscrobbler_user_set_authentication_details (RBAudioscrobblerUser *user,
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.c b/plugins/audioscrobbler/rb-audioscrobbler.c
index 2aaaf4e..7b78027 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler.c
@@ -53,7 +53,6 @@
 #include "rb-shell-player.h"
 #include "rb-source.h"
 #include "rb-cut-and-paste-code.h"
-#include "rb-plugin.h"
 #include "rb-util.h"
 #include "rb-podcast-entry-types.h"
 #include "rb-marshal.h"
@@ -137,8 +136,6 @@ static int	     rb_audioscrobbler_save_queue (RBAudioscrobbler *audioscrobbler);
 static void	     rb_audioscrobbler_print_queue (RBAudioscrobbler *audioscrobbler, gboolean submission);
 static void	     rb_audioscrobbler_free_queue_entries (RBAudioscrobbler *audioscrobbler, GQueue **queue);
 
-static void	     rb_audioscrobbler_class_init (RBAudioscrobblerClass *klass);
-static void	     rb_audioscrobbler_init (RBAudioscrobbler *audioscrobbler);
 static void	     rb_audioscrobbler_get_property (GObject *object,
 						    guint prop_id,
 						    GValue *value,
@@ -197,7 +194,7 @@ enum
 
 static guint rb_audioscrobbler_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (RBAudioscrobbler, rb_audioscrobbler, G_TYPE_OBJECT)
+G_DEFINE_DYNAMIC_TYPE (RBAudioscrobbler, rb_audioscrobbler, G_TYPE_OBJECT)
 
 
 static void
@@ -324,6 +321,11 @@ rb_audioscrobbler_class_init (RBAudioscrobblerClass *klass)
 }
 
 static void
+rb_audioscrobbler_class_finalize (RBAudioscrobblerClass *klass)
+{
+}
+
+static void
 rb_audioscrobbler_init (RBAudioscrobbler *audioscrobbler)
 {
 	rb_debug ("Initialising Audioscrobbler");
@@ -1279,3 +1281,9 @@ rb_audioscrobbler_nowplaying_cb (SoupSession *session, SoupMessage *msg, gpointe
 
 	g_idle_add ((GSourceFunc) idle_unref_cb, audioscrobbler);
 }
+
+void
+_rb_audioscrobbler_register_type (GTypeModule *module)
+{
+	rb_audioscrobbler_register_type (module);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.h b/plugins/audioscrobbler/rb-audioscrobbler.h
index e96fb7e..71ff7da 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler.h
@@ -34,7 +34,6 @@ G_BEGIN_DECLS
 #include <glib.h>
 
 #include "rb-shell-player.h"
-#include "rb-plugin.h"
 #include "rb-audioscrobbler-service.h"
 
 #define RB_TYPE_AUDIOSCROBBLER			(rb_audioscrobbler_get_type ())
@@ -69,6 +68,7 @@ typedef struct
 
 
 GType			rb_audioscrobbler_get_type (void);
+void			_rb_audioscrobbler_register_type (GTypeModule *module);
 
 RBAudioscrobbler *	rb_audioscrobbler_new (RBAudioscrobblerService *service,
                                                RBShellPlayer *shell_player,
diff --git a/plugins/brasero-disc-recorder/Makefile.am b/plugins/brasero-disc-recorder/Makefile.am
index 06909f5..88bd0dc 100644
--- a/plugins/brasero-disc-recorder/Makefile.am
+++ b/plugins/brasero-disc-recorder/Makefile.am
@@ -33,12 +33,12 @@ INCLUDES = 						\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE			\
 	$(NULL)
 
-plugin_in_files = cd-recorder.rb-plugin.in
+plugin_in_files = cd-recorder.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-BUILT_SOURCES =							\
-	$(plugin_in_files:.rb-plugin.in=.rb-plugin) 		\
+BUILT_SOURCES =						\
+	$(plugin_in_files:.plugin.in=.plugin) 		\
 	$(NULL)
 
 plugin_DATA = 			\
diff --git a/plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in b/plugins/brasero-disc-recorder/cd-recorder.plugin.in
similarity index 93%
rename from plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in
rename to plugins/brasero-disc-recorder/cd-recorder.plugin.in
index d830bb1..3c10182 100644
--- a/plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in
+++ b/plugins/brasero-disc-recorder/cd-recorder.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=cd-recorder
-IAge=1
+IAge=2
 _Name=Audio CD Recorder
 _Description=Record audio CDs from playlists and duplicate audio CDs
 Authors=William Jon McCann, Rouquier Philippe
diff --git a/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c b/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c
index 00f9da9..91980be 100644
--- a/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c
+++ b/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c
@@ -50,7 +50,7 @@
 #include <libxml/uri.h>
 #include <libxml/xmlsave.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-source.h"
@@ -67,9 +67,8 @@
 
 typedef struct
 {
-	RBPlugin        parent;
+	PeasExtensionBase parent;
 
-	RBShell        *shell;
 	GtkActionGroup *action_group;
 	guint           ui_merge_id;
 
@@ -79,16 +78,14 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBDiscRecorderPluginClass;
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_disc_recorder_plugin_get_type		(void) G_GNUC_CONST;
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
+
+RB_DEFINE_PLUGIN(RB_TYPE_DISC_RECORDER_PLUGIN, RBDiscRecorderPlugin, rb_disc_recorder_plugin,)
 
 static void rb_disc_recorder_plugin_init (RBDiscRecorderPlugin *plugin);
-static void rb_disc_recorder_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 static void cmd_burn_source (GtkAction          *action,
 			     RBDiscRecorderPlugin *pi);
 static void cmd_duplicate_cd (GtkAction          *action,
@@ -103,8 +100,6 @@ static GtkActionEntry rb_disc_recorder_plugin_actions [] = {
 	  G_CALLBACK (cmd_duplicate_cd) },
 };
 
-RB_PLUGIN_REGISTER(RBDiscRecorderPlugin, rb_disc_recorder_plugin)
-
 #define RB_RECORDER_ERROR rb_disc_recorder_error_quark ()
 
 GQuark rb_disc_recorder_error_quark (void);
@@ -127,31 +122,11 @@ typedef enum
 } RBRecorderError;
 
 static void
-rb_disc_recorder_plugin_class_init (RBDiscRecorderPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_disc_recorder_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-}
-
-static void
 rb_disc_recorder_plugin_init (RBDiscRecorderPlugin *pi)
 {
 	rb_debug ("RBDiscRecorderPlugin initialized");
 }
 
-static void
-rb_disc_recorder_plugin_finalize (GObject *object)
-{
-	rb_debug ("RBDiscRecorderPlugin finalized");
-
-	G_OBJECT_CLASS (rb_disc_recorder_plugin_parent_class)->finalize (object);
-}
-
 static gboolean
 rb_disc_recorder_plugin_start_burning (RBDiscRecorderPlugin *pi,
 					  const char *path,
@@ -163,6 +138,7 @@ rb_disc_recorder_plugin_start_burning (RBDiscRecorderPlugin *pi,
 	char **args, *xid_str;
 	GError *error = NULL;
 	gboolean ret;
+	RBShell *shell;
 	
 	array = g_ptr_array_new ();
 	g_ptr_array_add (array, "brasero");
@@ -172,7 +148,10 @@ rb_disc_recorder_plugin_start_burning (RBDiscRecorderPlugin *pi,
 		g_ptr_array_add (array, "-r");
 	g_ptr_array_add (array, (gpointer) path);
 
-	g_object_get (pi->shell, "window", &main_window, NULL);
+	g_object_get (pi, "object", &shell, NULL);
+	g_object_get (shell, "window", &main_window, NULL);
+	g_object_unref (shell);
+
 	window = gtk_widget_get_window (main_window);
 	if (window) {
 		int xid;
@@ -606,8 +585,12 @@ update_source (RBDiscRecorderPlugin *pi,
 	/* for now restrict to playlist sources */
 	playlist_active = RB_IS_PLAYLIST_SOURCE (selected_page);
 
-	page_type = G_OBJECT_TYPE_NAME (selected_page);
-	is_audiocd_active = g_str_equal (page_type, "RBAudioCdSource");
+	if (selected_page != NULL) {
+		page_type = G_OBJECT_TYPE_NAME (selected_page);
+		is_audiocd_active = g_str_equal (page_type, "RBAudioCdSource");
+	} else {
+		is_audiocd_active = FALSE;
+	}
 
 	burn_action = gtk_action_group_get_action (pi->action_group,
 						   "MusicPlaylistBurnToDiscPlaylist");
@@ -671,22 +654,22 @@ static struct ui_paths {
 };
 
 static void
-impl_activate (RBPlugin *plugin,
-	       RBShell  *shell)
+impl_activate (PeasActivatable *plugin)
 {
 	RBDiscRecorderPlugin *pi = RB_DISC_RECORDER_PLUGIN (plugin);
 	GtkUIManager         *uimanager = NULL;
 	GtkAction            *action;
+	RBShell              *shell;
 	int                   i;
 
+	g_object_get (pi, "object", &shell, NULL);
+
 	pi->enabled = TRUE;
 
 	rb_debug ("RBDiscRecorderPlugin activating");
 
 	brasero_media_library_start ();
 
-	pi->shell = shell;
-
 	g_object_get (shell,
 		      "ui-manager", &uimanager,
 		      NULL);
@@ -737,14 +720,18 @@ impl_activate (RBPlugin *plugin,
 	g_object_set (action, "short-label", _("Copy CD"), NULL);
 
 	update_source (pi, shell);
+
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *plugin,
-		 RBShell  *shell)
+impl_deactivate	(PeasActivatable *plugin)
 {
 	RBDiscRecorderPlugin *pi = RB_DISC_RECORDER_PLUGIN (plugin);
-	GtkUIManager       *uimanager = NULL;
+	GtkUIManager         *uimanager = NULL;
+	RBShell              *shell;
+
+	g_object_get (pi, "object", &shell, NULL);
 
 	pi->enabled = FALSE;
 
@@ -769,5 +756,15 @@ impl_deactivate	(RBPlugin *plugin,
 	g_object_unref (uimanager);
 
 	/* NOTE: don't deactivate libbrasero-media as it could be in use somewhere else */
+
+	g_object_unref (shell);
 }
 
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_disc_recorder_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_DISC_RECORDER_PLUGIN);
+}
diff --git a/plugins/context/context/AlbumTab.py b/plugins/context/AlbumTab.py
similarity index 97%
rename from plugins/context/context/AlbumTab.py
rename to plugins/context/AlbumTab.py
index 236ac30..9323ba1 100644
--- a/plugins/context/context/AlbumTab.py
+++ b/plugins/context/AlbumTab.py
@@ -48,8 +48,8 @@ class AlbumTab (gobject.GObject):
     def __init__ (self, shell, buttons, ds, view):
         gobject.GObject.__init__ (self)
         self.shell      = shell
-        self.sp         = shell.get_player ()
-        self.db         = shell.get_property ('db') 
+        self.sp         = shell.props.shell_player
+        self.db         = shell.props.db
         self.buttons    = buttons
 
         self.button     = Gtk.ToggleButton (label=_("Albums"))
@@ -99,7 +99,7 @@ class AlbumView (gobject.GObject):
         self.plugin  = plugin
         self.file    = ""
 
-        plugindir = os.path.split(plugin.find_file ('context.rb-plugin'))[0]
+        plugindir = plugin.plugin_info.get_data_dir()
         self.basepath = "file://" + urllib.pathname2url (plugindir)
 
         self.load_tmpl ()
@@ -121,8 +121,8 @@ class AlbumView (gobject.GObject):
         self.webview.load_string (self.loading_file, 'text/html', 'utf-8', self.basepath)
 
     def load_tmpl (self):
-        self.path = self.plugin.find_file ('tmpl/album-tmpl.html')
-        self.loading_path = self.plugin.find_file ('tmpl/loading.html')
+        self.path = rb.find_plugin_file (self.plugin, 'tmpl/album-tmpl.html')
+        self.loading_path = rb.find_plugin_file (self.plugin, 'tmpl/loading.html')
         self.album_template = Template (filename = self.path,
                                         module_directory = '/tmp/context')
         self.loading_template = Template (filename = self.loading_path, 
diff --git a/plugins/context/context/ArtistTab.py b/plugins/context/ArtistTab.py
similarity index 97%
rename from plugins/context/context/ArtistTab.py
rename to plugins/context/ArtistTab.py
index f944908..7453141 100644
--- a/plugins/context/context/ArtistTab.py
+++ b/plugins/context/ArtistTab.py
@@ -49,8 +49,8 @@ class ArtistTab (gobject.GObject):
     def __init__ (self, shell, buttons, ds, view):
         gobject.GObject.__init__ (self)
         self.shell      = shell
-        self.sp         = shell.get_player ()
-        self.db         = shell.get_property ('db') 
+        self.sp         = shell.props.shell_player
+        self.db         = shell.props.db
         self.buttons    = buttons
 
         self.button     = Gtk.ToggleButton (label=_("Artist"))
@@ -100,7 +100,8 @@ class ArtistView (gobject.GObject):
         self.shell    = shell
         self.plugin   = plugin
         self.file     = ""
-        plugindir = os.path.split(plugin.find_file ('context.rb-plugin'))[0]
+
+	plugindir = plugin.plugin_info.get_data_dir()
         self.basepath = "file://" + urllib.pathname2url (plugindir)
 
         self.load_tmpl ()
@@ -118,8 +119,8 @@ class ArtistView (gobject.GObject):
         self.webview.load_string (self.loading_file, 'text/html', 'utf-8', self.basepath)
 
     def load_tmpl (self):
-        self.path = self.plugin.find_file('tmpl/artist-tmpl.html')
-        self.loading_path = self.plugin.find_file ('tmpl/loading.html')
+        self.path = rb.find_plugin_file(self.plugin, 'tmpl/artist-tmpl.html')
+        self.loading_path = rb.find_plugin_file (self.plugin, 'tmpl/loading.html')
         self.template = Template (filename = self.path, module_directory = '/tmp/context/')
         self.loading_template = Template (filename = self.loading_path, module_directory = '/tmp/context')
         self.styles = self.basepath + '/tmpl/main.css'
diff --git a/plugins/context/context/ContextView.py b/plugins/context/ContextView.py
similarity index 87%
rename from plugins/context/context/ContextView.py
rename to plugins/context/ContextView.py
index f9e3a2f..f4004da 100644
--- a/plugins/context/context/ContextView.py
+++ b/plugins/context/ContextView.py
@@ -50,11 +50,10 @@ class ContextView (gobject.GObject):
     def __init__ (self, shell, plugin):
         gobject.GObject.__init__ (self)
         self.shell = shell
-        self.sp = shell.get_player ()
-        self.db = shell.get_property ('db')
+        self.sp = shell.props.shell_player
+        self.db = shell.props.db
         self.plugin = plugin
         
-        self.top_five = None
         self.current_artist = None
         self.current_album = None
         self.current_song = None
@@ -107,11 +106,18 @@ class ContextView (gobject.GObject):
         self.sp = None
         self.db = None
         self.plugin = None
-        self.top_five = None
         self.tab = None
+        self.ds = None
+        self.view = None
         if self.visible:
             shell.remove_widget (self.vbox, RB.ShellUILocation.RIGHT_SIDEBAR)
             self.visible = False
+	self.vbox = None
+	self.label = None
+	self.webview = None
+	self.websettings = None
+	self.buttons = None
+	self.top_five_list = None
         uim = shell.get_ui_manager ()
         uim.remove_ui (self.ui_id)
         uim.remove_action_group (self.action_group)
@@ -172,7 +178,6 @@ class ContextView (gobject.GObject):
         top_tracks = ds.get_top_tracks ()
         ## populate liststore
         if top_tracks is None:
-            self.top_five = ['','','','','']
             for i in range (0, 5):
                 self.top_five_list.append(["%d. " % (i+1), ""])
         else:
@@ -234,42 +239,42 @@ class ContextView (gobject.GObject):
 
     def init_gui(self):
         self.vbox = Gtk.VBox()
-        self.frame = Gtk.Frame()
+        frame = Gtk.Frame()
         self.label = Gtk.Label(_('Nothing Playing'))
-        self.frame.set_shadow_type(Gtk.ShadowType.IN)
-        self.frame.set_label_align(0.0,0.0)
-        self.frame.set_label_widget(self.label)
+        frame.set_shadow_type(Gtk.ShadowType.IN)
+        frame.set_label_align(0.0,0.0)
+        frame.set_label_widget(self.label)
         self.label.set_use_markup(True)
         self.label.set_padding(0,4)
 
         #----- set up top 5 tree view -----#
         self.top_five_list = Gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_STRING)
-        self.top_five_view = Gtk.TreeView.new_with_model(self.top_five_list)
+        top_five_view = Gtk.TreeView.new_with_model(self.top_five_list)
 
-        self.top_five_tvc1 = Gtk.TreeViewColumn()
-        self.top_five_tvc2 = Gtk.TreeViewColumn()
+        top_five_tvc1 = Gtk.TreeViewColumn()
+        top_five_tvc2 = Gtk.TreeViewColumn()
 
-        self.top_five_view.append_column(self.top_five_tvc1)
-        self.top_five_view.append_column(self.top_five_tvc2)
+        top_five_view.append_column(top_five_tvc1)
+        top_five_view.append_column(top_five_tvc2)
 
-        self.crt = Gtk.CellRendererText()
+        crt = Gtk.CellRendererText()
 
-        self.top_five_tvc1.pack_start(self.crt, True)
-        self.top_five_tvc2.pack_start(self.crt, True)
+        top_five_tvc1.pack_start(crt, True)
+        top_five_tvc2.pack_start(crt, True)
 
-        self.top_five_tvc1.add_attribute(self.crt, 'text', 0)
-        self.top_five_tvc2.add_attribute(self.crt, 'text', 1)
+        top_five_tvc1.add_attribute(crt, 'text', 0)
+        top_five_tvc2.add_attribute(crt, 'text', 1)
         
-        self.top_five_view.set_headers_visible( False )
-        self.frame.add (self.top_five_view)
+        top_five_view.set_headers_visible( False )
+        frame.add (top_five_view)
 
         #---- set up webkit pane -----#
         self.webview = WebKit.WebView()
         self.webview.connect("navigation-requested", self.navigation_request_cb)
-        self.scroll = Gtk.ScrolledWindow()
-        self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
-        self.scroll.set_shadow_type(Gtk.ShadowType.IN)
-        self.scroll.add (self.webview)
+        scroll = Gtk.ScrolledWindow()
+        scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
+        scroll.set_shadow_type(Gtk.ShadowType.IN)
+        scroll.add (self.webview)
 
         # set up webkit settings to match gtk font settings
         self.websettings = WebKit.WebSettings()
@@ -278,14 +283,14 @@ class ContextView (gobject.GObject):
         self.webview.connect("style-set", self.style_set_cb)
 
         #----- set up button group -----#
-        self.vbox2 = Gtk.VBox()
+        vbox2 = Gtk.VBox()
         self.buttons = Gtk.HBox()
 
         #---- pack everything into side pane ----#
-        self.vbox.pack_start  (self.frame, False, True, 0)
-        self.vbox2.pack_start (self.buttons, False, True, 0)
-        self.vbox2.pack_start (self.scroll, True, True, 0)
-        self.vbox.pack_start  (self.vbox2, True, True, 0)
+        self.vbox.pack_start  (frame, False, True, 0)
+        vbox2.pack_start (self.buttons, False, True, 0)
+        vbox2.pack_start (scroll, True, True, 0)
+        self.vbox.pack_start (vbox2, True, True, 0)
 
         self.vbox.show_all()
         self.vbox.set_size_request(200, -1)
diff --git a/plugins/context/context/LastFM.py b/plugins/context/LastFM.py
similarity index 98%
rename from plugins/context/context/LastFM.py
rename to plugins/context/LastFM.py
index 9aa0df0..dc4e685 100644
--- a/plugins/context/context/LastFM.py
+++ b/plugins/context/LastFM.py
@@ -24,8 +24,11 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
+import os
 import ConfigParser
 
+from gi.repository import RB
+
 # utility things for dealing with last.fm
 
 URL_PREFIX = 'http://ws.audioscrobbler.com/2.0/?method='
diff --git a/plugins/context/context/LinksTab.py b/plugins/context/LinksTab.py
similarity index 96%
rename from plugins/context/context/LinksTab.py
rename to plugins/context/LinksTab.py
index 96cfa05..0eac0b0 100644
--- a/plugins/context/context/LinksTab.py
+++ b/plugins/context/LinksTab.py
@@ -48,8 +48,8 @@ class LinksTab (gobject.GObject):
     def __init__ (self, shell, buttons, ds, view):
         gobject.GObject.__init__ (self)
         self.shell      = shell
-        self.sp         = shell.get_player ()
-        self.db         = shell.get_property ('db')
+        self.sp         = shell.props.shell_player
+        self.db         = shell.props.db
         self.buttons    = buttons
 
         self.button     = Gtk.ToggleButton (label=_("Links"))
@@ -98,12 +98,13 @@ class LinksView (gobject.GObject):
         self.plugin   = plugin
         self.webview  = webview
         self.file     = ""
-        plugindir = os.path.split(plugin.find_file ('context.rb-plugin'))[0]
+
+        plugindir = plugin.plugin_info.get_data_dir()
         self.basepath = "file://" + urllib.pathname2url (plugindir)
 
     def load_links (self, ds):
         print "Loading links into webview"
-        self.path = self.plugin.find_file('tmpl/links-tmpl.html')
+        self.path = rb.find_plugin_file(self.plugin, 'tmpl/links-tmpl.html')
         self.images = self.basepath + '/img/links/'
         self.styles = self.basepath + '/tmpl/main.css'
         self.template = Template (filename = self.path, 
diff --git a/plugins/context/context/LyricsTab.py b/plugins/context/LyricsTab.py
similarity index 94%
rename from plugins/context/context/LyricsTab.py
rename to plugins/context/LyricsTab.py
index 0774df5..d0cae85 100644
--- a/plugins/context/context/LyricsTab.py
+++ b/plugins/context/LyricsTab.py
@@ -44,8 +44,8 @@ class LyricsTab (gobject.GObject):
     def __init__ (self, shell, toolbar, ds, view):
         gobject.GObject.__init__ (self)
         self.shell      = shell
-        self.sp         = shell.get_player ()
-        self.db         = shell.get_property ('db') 
+        self.sp         = shell.props.shell_player
+        self.db         = shell.props.db
         self.toolbar    = toolbar
 
         self.button     = Gtk.ToggleButton (label=_("Lyrics"))
@@ -84,7 +84,7 @@ class LyricsView (gobject.GObject):
         self.shell   = shell
         self.plugin  = plugin
         self.file    = ""
-        plugindir = os.path.split(plugin.find_file ('context.rb-plugin'))[0]
+        plugindir = plugin.plugin_info.get_data_dir()
         self.basepath = "file://" + urllib.pathname2url (plugindir)
 
         self.load_tmpl ()
@@ -106,8 +106,8 @@ class LyricsView (gobject.GObject):
         print "loading screen loaded"
 
     def load_tmpl (self):
-        self.path = self.plugin.find_file('tmpl/lyrics-tmpl.html')
-        self.loading_path = self.plugin.find_file ('tmpl/loading.html')
+        self.path = rb.find_plugin_file(self.plugin, 'tmpl/lyrics-tmpl.html')
+        self.loading_path = rb.find_plugin_file (self.plugin, 'tmpl/loading.html')
         self.template = Template (filename = self.path, 
                                   module_directory = '/tmp/context/')
         self.loading_template = Template (filename = self.loading_path, 
diff --git a/plugins/context/Makefile.am b/plugins/context/Makefile.am
index 425fe71..88f0159 100644
--- a/plugins/context/Makefile.am
+++ b/plugins/context/Makefile.am
@@ -1,15 +1,22 @@
 # Context Pane Python Plugin
 
-SUBDIRS = context
-
 plugindir = $(PLUGINDIR)/context
-
-plugin_in_files = context.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
-
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
-
-tmpldir = $(plugindir)/tmpl
+plugindatadir = $(PLUGINDATADIR)/context
+plugin_PYTHON = 			\
+	AlbumTab.py			\
+	ArtistTab.py			\
+	ContextView.py			\
+	LastFM.py			\
+	LinksTab.py			\
+	LyricsTab.py			\
+	context.py
+
+plugin_in_files = context.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+
+tmpldir = $(plugindatadir)/tmpl
 tmpl_DATA = \
 	tmpl/album-tmpl.html		\
 	tmpl/artist-tmpl.html		\
@@ -18,7 +25,7 @@ tmpl_DATA = \
 	tmpl/lyrics-tmpl.html		\
 	tmpl/main.css
 
-imgdir = $(plugindir)/img
+imgdir = $(plugindatadir)/img
 img_DATA = \
 	img/lastfm.png			\
 	img/spinner.gif			\
diff --git a/plugins/context/context.rb-plugin.in b/plugins/context/context.plugin.in
similarity index 89%
rename from plugins/context/context.rb-plugin.in
rename to plugins/context/context.plugin.in
index df9e963..ee3e640 100644
--- a/plugins/context/context.rb-plugin.in
+++ b/plugins/context/context.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=context
-IAge=1
+IAge=2
+Depends=rb
 _Name=Context Pane
 _Description=Show information related to the currently playing artist and song.
 Authors=John Iacona <plate0salad gmail com>
diff --git a/plugins/context/context/__init__.py b/plugins/context/context.py
similarity index 78%
rename from plugins/context/context/__init__.py
rename to plugins/context/context.py
index ea275db..7fe2f2a 100644
--- a/plugins/context/context/__init__.py
+++ b/plugins/context/context.py
@@ -28,15 +28,19 @@
 
 import ContextView as cv
 
+from gi.repository import GObject, Peas
 from gi.repository import RB
 
-class ContextPlugin(RB.Plugin):
+class ContextPlugin(GObject.Object, Peas.Activatable):
+    __gtype_name__ = 'ContextPlugin'
+    object = GObject.property(type=GObject.Object)
+
     def __init__ (self):
-        RB.Plugin.__init__ (self)
+        GObject.Object.__init__ (self)
 
-    def activate (self, shell):
-        self.context_view = cv.ContextView (shell, self)
+    def do_activate (self):
+        self.context_view = cv.ContextView (self.object, self)
 
-    def deactivate(self, shell):
-        self.context_view.deactivate(shell)
+    def do_deactivate(self):
+        self.context_view.deactivate(self.object)
         del self.context_view
diff --git a/plugins/daap/Makefile.am b/plugins/daap/Makefile.am
index da8cd2d..2bd4704 100644
--- a/plugins/daap/Makefile.am
+++ b/plugins/daap/Makefile.am
@@ -1,6 +1,7 @@
 NULL =
 
 plugindir = $(PLUGINDIR)/daap
+plugindatadir = $(PLUGINDATADIR)/daap
 plugin_LTLIBRARIES = libdaap.la
 
 libdaap_la_SOURCES = \
@@ -69,28 +70,29 @@ libdaap_la_LIBADD += $(GNOME_KEYRING_LIBS)
 INCLUDES += $(GNOME_KEYRING_CFLAGS)
 endif
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA = daap-prefs.ui
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = daap-ui.xml
 
-plugin_in_files = daap.rb-plugin.in
+plugin_in_files = daap.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-BUILT_SOURCES =							\
-	$(plugin_in_files:.rb-plugin.in=.rb-plugin) 		\
-	$(NULL)
+plugin_files = $(plugin_in_files:.plugin.in=.plugin)
 
-plugin_DATA = 			\
-	$(BUILT_SOURCES)	\
-	$(top_srcdir)/plugins/daap/remote-icon.png		\
+BUILT_SOURCES = $(plugin_files)
+
+plugin_DATA = $(plugin_files)
+
+plugindata_DATA = 					\
+	$(top_srcdir)/plugins/daap/remote-icon.png	\
 	$(NULL)
 
-EXTRA_DIST = 			\
-	$(gtkbuilder_DATA)	\
-	$(top_srcdir)/plugins/daap/remote-icon.png		\
+EXTRA_DIST = 						\
+	$(gtkbuilder_DATA)				\
+	$(top_srcdir)/plugins/daap/remote-icon.png	\
 	$(uixml_DATA)		\
 	$(plugin_in_files)	\
 	$(NULL)
diff --git a/plugins/daap/daap.rb-plugin.in b/plugins/daap/daap.plugin.in
similarity index 93%
rename from plugins/daap/daap.rb-plugin.in
rename to plugins/daap/daap.plugin.in
index 60f63be..6b5b394 100644
--- a/plugins/daap/daap.rb-plugin.in
+++ b/plugins/daap/daap.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=daap
-IAge=1
+IAge=2
 _Name=DAAP Music Sharing
 _Description=Share music and play shared music on your local network
 Authors=Charles Schmidt  <cschmidt2 emich edu>, the Rhythmbox Developers
diff --git a/plugins/daap/rb-daap-container-record.c b/plugins/daap/rb-daap-container-record.c
index 621b038..7bb63ab 100644
--- a/plugins/daap/rb-daap-container-record.c
+++ b/plugins/daap/rb-daap-container-record.c
@@ -145,6 +145,11 @@ rb_daap_container_record_class_init (RBDAAPContainerRecordClass *klass)
 }
 
 static void
+rb_daap_container_record_class_finalize (RBDAAPContainerRecordClass *klass)
+{
+}
+
+static void
 rb_daap_container_record_daap_iface_init (gpointer iface, gpointer data)
 {
 	DMAPContainerRecordIface *dmap_container_record = iface;
@@ -157,10 +162,15 @@ rb_daap_container_record_daap_iface_init (gpointer iface, gpointer data)
 	dmap_container_record->get_entries = rb_daap_container_record_get_entries;
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBDAAPContainerRecord, rb_daap_container_record, G_TYPE_OBJECT, 
-			 G_IMPLEMENT_INTERFACE (DMAP_TYPE_CONTAINER_RECORD, rb_daap_container_record_daap_iface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBDAAPContainerRecord,
+				rb_daap_container_record,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_CONTAINER_RECORD,
+							       rb_daap_container_record_daap_iface_init))
 
-static void rb_daap_container_record_finalize (GObject *object)
+static void
+rb_daap_container_record_finalize (GObject *object)
 {
 	RBDAAPContainerRecord *record = RB_DAAP_CONTAINER_RECORD (object);
 
@@ -181,3 +191,9 @@ rb_daap_container_record_new (char *name, RBPlaylistSource *source)
 
 	return record;
 }
+
+void
+_rb_daap_container_record_register_type (GTypeModule *module)
+{
+	rb_daap_container_record_register_type (module);
+}
diff --git a/plugins/daap/rb-daap-container-record.h b/plugins/daap/rb-daap-container-record.h
index 08d5f3a..fc068b3 100644
--- a/plugins/daap/rb-daap-container-record.h
+++ b/plugins/daap/rb-daap-container-record.h
@@ -70,6 +70,8 @@ DMAPDb *rb_daap_container_record_get_entries     (DMAPContainerRecord *record);
 RBDAAPContainerRecord *rb_daap_container_record_new (char *name,
 						     RBPlaylistSource *model);
 
+void          _rb_daap_container_record_register_type   (GTypeModule *module);
+
 #endif /* __RB_DAAP_CONTAINER_RECORD */
 
 G_END_DECLS
diff --git a/plugins/daap/rb-daap-plugin.c b/plugins/daap/rb-daap-plugin.c
index c54f001..20cc539 100644
--- a/plugins/daap/rb-daap-plugin.c
+++ b/plugins/daap/rb-daap-plugin.c
@@ -40,18 +40,29 @@
 
 #include <libsoup/soup.h>
 
+#include <libpeas-gtk/peas-gtk.h>
+
+#include "rb-plugin-macros.h"
 #include "rb-daap-plugin.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-dialog.h"
 #include "rb-file-helpers.h"
 #include "rb-builder-helpers.h"
+#include "rb-uri-dialog.h"
+#include "rb-display-page-group.h"
+
+#include "rb-daap-container-record.h"
+#include "rb-daap-record-factory.h"
+#include "rb-daap-record.h"
 #include "rb-daap-source.h"
 #include "rb-daap-sharing.h"
 #include "rb-daap-src.h"
 #include "rb-dacp-pairing-page.h"
-#include "rb-uri-dialog.h"
-#include "rb-display-page-group.h"
+#include "rb-dacp-player.h"
+#include "rb-dmap-container-db-adapter.h"
+#include "rb-rhythmdb-dmap-db-adapter.h"
+#include "rb-rhythmdb-query-model-dmap-db-adapter.h"
 
 #include <libdmapsharing/dmap.h>
 
@@ -72,10 +83,9 @@ static const char *rb_daap_dbus_iface =
 "  </interface>"
 "</node>";
 
-
-struct RBDaapPluginPrivate
+struct _RBDaapPlugin
 {
-	RBShell *shell;
+	PeasExtensionBase parent;
 
 	GtkBuilder *builder;
 	GtkWidget *preferences;
@@ -101,26 +111,16 @@ struct RBDaapPluginPrivate
 	guint dbus_intf_id;
 };
 
-enum
+struct _RBDaapPluginClass
 {
-	PROP_0,
-	PROP_SHUTDOWN,
-	PROP_SHELL
+	PeasExtensionBaseClass parent;
 };
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
 
-static void rb_daap_plugin_get_property (GObject *object,
-					 guint prop_id,
-					 GValue *value,
-					 GParamSpec *pspec);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void rb_daap_plugin_init (RBDaapPlugin *plugin);
-static void rb_daap_plugin_dispose (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
-static GtkWidget* impl_create_configure_dialog (RBPlugin *plugin);
 static void rb_daap_plugin_cmd_disconnect (GtkAction *action, RBSource *source);
 static void rb_daap_plugin_cmd_connect (GtkAction *action, RBDaapPlugin *plugin);
 
@@ -141,7 +141,13 @@ static void libdmapsharing_debug (const char *domain,
 static void register_daap_dbus_iface (RBDaapPlugin *plugin);
 static void unregister_daap_dbus_iface (RBDaapPlugin *plugin);
 
-RB_PLUGIN_REGISTER(RBDaapPlugin, rb_daap_plugin)
+static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface);
+
+RB_DEFINE_PLUGIN(RB_TYPE_DAAP_PLUGIN,
+		 RBDaapPlugin,
+		 rb_daap_plugin,
+		 (G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE,
+						peas_gtk_configurable_iface_init)))
 
 static GtkActionEntry rb_daap_plugin_actions [] =
 {
@@ -158,146 +164,67 @@ static GtkActionEntry rb_daap_source_actions[] =
 };
 
 static void
-rb_daap_plugin_class_init (RBDaapPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->dispose = rb_daap_plugin_dispose;
-	object_class->get_property = rb_daap_plugin_get_property;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-	plugin_class->create_configure_dialog = impl_create_configure_dialog;
-
-	g_object_class_install_property (object_class,
-					 PROP_SHUTDOWN,
-					 g_param_spec_boolean ("shutdown",
-							       "shutdown",
-							       "Whether the DAAP plugin has been shut down",
-							       FALSE,
-							       G_PARAM_READABLE));
-
-	g_object_class_install_property (object_class,
-	                                 PROP_SHELL,
-	                                 g_param_spec_object ("shell",
-	                                                      "Shell",
-	                                                      "The Rhythmbox Shell",
-	                                                      RB_TYPE_SHELL,
-	                                                      G_PARAM_READABLE));
-
-	g_type_class_add_private (object_class, sizeof (RBDaapPluginPrivate));
-}
-
-static void
 rb_daap_plugin_init (RBDaapPlugin *plugin)
 {
-	rb_debug ("RBDaapPlugin initialising");
-	plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, RB_TYPE_DAAP_PLUGIN, RBDaapPluginPrivate);
-
-	rb_daap_src_set_plugin (RB_PLUGIN (plugin));
-}
-
-static void
-rb_daap_plugin_dispose (GObject *object)
-{
-	RBDaapPlugin *plugin = RB_DAAP_PLUGIN (object);
-
-	rb_debug ("RBDaapPlugin dispose");
-
-	if (plugin->priv->preferences) {
-		gtk_widget_destroy (plugin->priv->preferences);
-		plugin->priv->preferences = NULL;
-	}
-
-	if (plugin->priv->builder) {
-		g_object_unref (plugin->priv->builder);
-		plugin->priv->builder = NULL;
-	}
-
-	if (plugin->priv->bus) {
-		g_object_unref (plugin->priv->bus);
-		plugin->priv->bus = NULL;
-	}
+	GSettings *daap_settings;
 
-	G_OBJECT_CLASS (rb_daap_plugin_parent_class)->dispose (object);
-}
+	rb_debug ("RBDaapPlugin initialising");
+	rb_daap_src_set_plugin (G_OBJECT (plugin));
 
+	plugin->settings = g_settings_new ("org.gnome.rhythmbox.sharing");
 
-static void
-rb_daap_plugin_get_property (GObject *object,
-			     guint prop_id,
-			     GValue *value,
-			     GParamSpec *pspec)
-{
-	RBDaapPlugin *plugin = RB_DAAP_PLUGIN (object);
-
-	switch (prop_id) {
-	case PROP_SHUTDOWN:
-		g_value_set_boolean (value, plugin->priv->shutdown);
-		break;
-	case PROP_SHELL:
-		g_value_take_object (value, plugin->priv->shell);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
+	daap_settings = g_settings_new ("org.gnome.rhythmbox.plugins.daap");
+	plugin->dacp_settings = g_settings_get_child (daap_settings, "dacp");
+	g_object_unref (daap_settings);
 }
 
 static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBDaapPlugin *plugin = RB_DAAP_PLUGIN (bplugin);
 	gboolean no_registration;
 	GtkUIManager *uimanager = NULL;
 	char *uifile;
-	GSettings *daap_settings;
+	RBShell *shell;
 
-	plugin->priv->shutdown = FALSE;
-	plugin->priv->shell = g_object_ref (shell);
+	plugin->shutdown = FALSE;
 
 	g_log_set_handler ("libdmapsharing",
 			    G_LOG_LEVEL_MASK,
 			    libdmapsharing_debug,
 			    NULL);
 
-	plugin->priv->settings = g_settings_new ("org.gnome.rhythmbox.sharing");
-	g_signal_connect_object (plugin->priv->settings, "changed", G_CALLBACK (settings_changed_cb), plugin, 0);
+	g_object_get (plugin, "object", &shell, NULL);
 
-	daap_settings = g_settings_new ("org.gnome.rhythmbox.plugins.daap");
-	plugin->priv->dacp_settings = g_settings_get_child (daap_settings, "dacp");
-	g_object_unref (daap_settings);
-	g_signal_connect_object (plugin->priv->dacp_settings, "changed", G_CALLBACK (dacp_settings_changed_cb), plugin, 0);
+	g_signal_connect_object (plugin->settings, "changed", G_CALLBACK (settings_changed_cb), plugin, 0);
+
+	g_signal_connect_object (plugin->dacp_settings, "changed", G_CALLBACK (dacp_settings_changed_cb), plugin, 0);
 
-	if (g_settings_get_boolean (plugin->priv->settings, "enable-browsing")) {
+	if (g_settings_get_boolean (plugin->settings, "enable-browsing")) {
 		start_browsing (plugin);
 	}
 
 	create_pixbufs (plugin);
 
-	g_object_get (shell,
-		      "ui-manager", &uimanager,
-		      NULL);
+	g_object_get (shell, "ui-manager", &uimanager, NULL);
 
 	/* add actions */
-	plugin->priv->daap_action_group = gtk_action_group_new ("DaapActions");
-	gtk_action_group_set_translation_domain (plugin->priv->daap_action_group,
+	plugin->daap_action_group = gtk_action_group_new ("DaapActions");
+	gtk_action_group_set_translation_domain (plugin->daap_action_group,
 						 GETTEXT_PACKAGE);
-	gtk_action_group_add_actions (plugin->priv->daap_action_group,
+	gtk_action_group_add_actions (plugin->daap_action_group,
 				      rb_daap_plugin_actions, G_N_ELEMENTS (rb_daap_plugin_actions),
 				      plugin);
-	_rb_action_group_add_display_page_actions (plugin->priv->daap_action_group,
+	_rb_action_group_add_display_page_actions (plugin->daap_action_group,
 						   G_OBJECT (shell),
 						   rb_daap_source_actions,
 						   G_N_ELEMENTS (rb_daap_source_actions));
-	gtk_ui_manager_insert_action_group (uimanager, plugin->priv->daap_action_group, 0);
+	gtk_ui_manager_insert_action_group (uimanager, plugin->daap_action_group, 0);
 
 	/* add UI */
-	uifile = rb_plugin_find_file (bplugin, "daap-ui.xml");
+	uifile = rb_find_plugin_data_file (G_OBJECT (plugin), "daap-ui.xml");
 	if (uifile != NULL) {
-		plugin->priv->daap_ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager, uifile, NULL);
+		plugin->daap_ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager, uifile, NULL);
 		g_free (uifile);
 	}
 
@@ -308,70 +235,82 @@ impl_activate (RBPlugin *bplugin,
 	 * This flag is only used to run multiple instances at the same time, and
 	 * sharing from two instances would be silly
 	 */
-	g_object_get (G_OBJECT (shell),
-		      "no-registration", &no_registration,
-		      NULL);
-	plugin->priv->sharing = !no_registration;
-	if (plugin->priv->sharing)
+	g_object_get (shell, "no-registration", &no_registration, NULL);
+	plugin->sharing = !no_registration;
+	if (plugin->sharing)
 		rb_daap_sharing_init (shell);
 
-	plugin->priv->dacp_share = rb_daap_create_dacp_share (RB_PLUGIN (plugin));
-	if (g_settings_get_boolean (plugin->priv->dacp_settings, "enable-remote")) {
-		dacp_share_start_lookup (plugin->priv->dacp_share);
+	plugin->dacp_share = rb_daap_create_dacp_share (G_OBJECT (plugin));
+	if (g_settings_get_boolean (plugin->dacp_settings, "enable-remote")) {
+		dacp_share_start_lookup (plugin->dacp_share);
 	}
 
 	register_daap_dbus_iface (plugin);
+
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBDaapPlugin *plugin = RB_DAAP_PLUGIN (bplugin);
 	GtkUIManager *uimanager = NULL;
+	RBShell *shell;
 
 	rb_debug ("Shutting down DAAP plugin");
 
+	g_object_get (plugin, "object", &shell, NULL);
+
 	unregister_daap_dbus_iface (plugin);
-	plugin->priv->shutdown = TRUE;
+	plugin->shutdown = TRUE;
 
-	if (plugin->priv->sharing)
+	if (plugin->sharing)
 		rb_daap_sharing_shutdown (shell);
 
-	if (plugin->priv->mdns_browser) {
+	if (plugin->mdns_browser) {
 		stop_browsing (plugin);
 	}
 
-	if (plugin->priv->settings) {
-		g_object_unref (plugin->priv->settings);
-		plugin->priv->settings = NULL;
+	if (plugin->settings) {
+		g_object_unref (plugin->settings);
+		plugin->settings = NULL;
 	}
 
-	g_object_unref (plugin->priv->dacp_share);
+	g_object_unref (plugin->dacp_share);
 
-	g_object_get (shell,
-		      "ui-manager", &uimanager,
-		      NULL);
+	g_object_get (shell, "ui-manager", &uimanager, NULL);
 
-	gtk_ui_manager_remove_ui (uimanager, plugin->priv->daap_ui_merge_id);
-	gtk_ui_manager_remove_action_group (uimanager, plugin->priv->daap_action_group);
+	gtk_ui_manager_remove_ui (uimanager, plugin->daap_ui_merge_id);
+	gtk_ui_manager_remove_action_group (uimanager, plugin->daap_action_group);
 
 	g_object_unref (uimanager);
 
-	if (plugin->priv->daap_share_pixbuf != NULL) {
-		g_object_unref (plugin->priv->daap_share_pixbuf);
-		plugin->priv->daap_share_pixbuf = NULL;
+	if (plugin->daap_share_pixbuf != NULL) {
+		g_object_unref (plugin->daap_share_pixbuf);
+		plugin->daap_share_pixbuf = NULL;
 	}
 
-	if (plugin->priv->daap_share_locked_pixbuf != NULL) {
-		g_object_unref (plugin->priv->daap_share_locked_pixbuf);
-		plugin->priv->daap_share_locked_pixbuf = NULL;
+	if (plugin->daap_share_locked_pixbuf != NULL) {
+		g_object_unref (plugin->daap_share_locked_pixbuf);
+		plugin->daap_share_locked_pixbuf = NULL;
 	}
 
-	if (plugin->priv->shell) {
-		g_object_unref (plugin->priv->shell);
-		plugin->priv->shell = NULL;
+	if (plugin->preferences) {
+		gtk_widget_destroy (plugin->preferences);
+		plugin->preferences = NULL;
 	}
+
+	if (plugin->builder) {
+		g_object_unref (plugin->builder);
+		plugin->builder = NULL;
+	}
+
+	if (plugin->bus) {
+		g_object_unref (plugin->bus);
+		plugin->bus = NULL;
+	}
+
+	g_object_unref (shell);
 }
 
 /* DAAP share icons */
@@ -440,13 +379,13 @@ create_pixbufs (RBDaapPlugin *plugin)
 	theme = gtk_icon_theme_get_default ();
 
 	gtk_icon_size_lookup (RB_SOURCE_ICON_SIZE, &size, NULL);
-	plugin->priv->daap_share_pixbuf =
+	plugin->daap_share_pixbuf =
 		gtk_icon_theme_load_icon (theme, "gnome-fs-network", size, 0, NULL);
 
 	gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &size, NULL);
 	emblem = gtk_icon_theme_load_icon (theme, "stock_lock", size, 0, NULL);
 
-	plugin->priv->daap_share_locked_pixbuf = composite_icons (plugin->priv->daap_share_pixbuf, emblem);
+	plugin->daap_share_locked_pixbuf = composite_icons (plugin->daap_share_pixbuf, emblem);
 
 	if (emblem != NULL) {
 		g_object_unref (emblem);
@@ -460,15 +399,15 @@ rb_daap_plugin_get_icon (RBDaapPlugin *plugin,
 {
 	GdkPixbuf *icon;
 
-	g_return_val_if_fail (plugin->priv->daap_share_pixbuf != NULL, NULL);
-	g_return_val_if_fail (plugin->priv->daap_share_locked_pixbuf != NULL, NULL);
+	g_return_val_if_fail (plugin->daap_share_pixbuf != NULL, NULL);
+	g_return_val_if_fail (plugin->daap_share_locked_pixbuf != NULL, NULL);
 
 	if (password_protected == FALSE) {
-		icon = g_object_ref (plugin->priv->daap_share_pixbuf);
+		icon = g_object_ref (plugin->daap_share_pixbuf);
 	} else if (connected) {
-		icon = g_object_ref (plugin->priv->daap_share_pixbuf);
+		icon = g_object_ref (plugin->daap_share_pixbuf);
 	} else {
-		icon = g_object_ref (plugin->priv->daap_share_locked_pixbuf);
+		icon = g_object_ref (plugin->daap_share_locked_pixbuf);
 	}
 
 	return icon;
@@ -482,7 +421,7 @@ find_source_by_service_name (RBDaapPlugin *plugin,
 {
 	RBSource *source;
 
-	source = g_hash_table_lookup (plugin->priv->source_lookup, service_name);
+	source = g_hash_table_lookup (plugin->source_lookup, service_name);
 
 	return source;
 }
@@ -490,9 +429,10 @@ find_source_by_service_name (RBDaapPlugin *plugin,
 static void
 mdns_service_added (DMAPMdnsBrowser *browser,
 		    DMAPMdnsBrowserService *service,
-		    RBDaapPlugin	*plugin)
+		    RBDaapPlugin *plugin)
 {
 	RBSource *source;
+	RBShell *shell;
 
 	rb_debug ("New service: %s name=%s host=%s port=%u password=%d",
 		   service->service_name,
@@ -506,11 +446,23 @@ mdns_service_added (DMAPMdnsBrowser *browser,
 	source = find_source_by_service_name (plugin, service->service_name);
 
 	if (source == NULL) {
-		source = rb_daap_source_new (plugin->priv->shell, RB_PLUGIN (plugin), service->service_name, service->name, service->host, service->port, service->password_protected);
-		g_hash_table_insert (plugin->priv->source_lookup, g_strdup (service->service_name), source);
-		rb_shell_append_display_page (plugin->priv->shell, RB_DISPLAY_PAGE (source), RB_DISPLAY_PAGE_GROUP_SHARED);
+		g_object_get (plugin, "object", &shell, NULL);
+
+		source = rb_daap_source_new (shell,
+					     G_OBJECT (plugin),
+					     service->service_name,
+					     service->name,
+					     service->host,
+					     service->port,
+					     service->password_protected);
+		g_hash_table_insert (plugin->source_lookup, g_strdup (service->service_name), source);
+		rb_shell_append_display_page (shell,
+					      RB_DISPLAY_PAGE (source),
+					      RB_DISPLAY_PAGE_GROUP_SHARED);
+
+		g_object_unref (shell);
 	} else {
-		g_object_set (G_OBJECT (source),
+		g_object_set (source,
 			      "name", service->name,
 			      "host", service->host,
 			      "port", service->port,
@@ -534,7 +486,7 @@ mdns_service_removed (DMAPMdnsBrowser *browser,
 
 	rb_debug ("DAAP source '%s' went away", service_name);
 	if (source != NULL) {
-		g_hash_table_remove (plugin->priv->source_lookup, service_name);
+		g_hash_table_remove (plugin->source_lookup, service_name);
 	}
 
 	GDK_THREADS_LEAVE ();
@@ -559,35 +511,35 @@ start_browsing (RBDaapPlugin *plugin)
 {
 	GError *error;
 
-	if (plugin->priv->mdns_browser != NULL) {
+	if (plugin->mdns_browser != NULL) {
 		return;
 	}
 
-	plugin->priv->mdns_browser = dmap_mdns_browser_new (DMAP_MDNS_BROWSER_SERVICE_TYPE_DAAP);
-	if (plugin->priv->mdns_browser == NULL) {
+	plugin->mdns_browser = dmap_mdns_browser_new (DMAP_MDNS_BROWSER_SERVICE_TYPE_DAAP);
+	if (plugin->mdns_browser == NULL) {
 		g_warning ("Unable to start mDNS browsing");
 		return;
 	}
 
-	g_signal_connect_object (plugin->priv->mdns_browser,
+	g_signal_connect_object (plugin->mdns_browser,
 				 "service-added",
 				 G_CALLBACK (mdns_service_added),
 				 plugin,
 				 0);
-	g_signal_connect_object (plugin->priv->mdns_browser,
+	g_signal_connect_object (plugin->mdns_browser,
 				 "service-removed",
 				 G_CALLBACK (mdns_service_removed),
 				 plugin,
 				 0);
 
 	error = NULL;
-	dmap_mdns_browser_start (plugin->priv->mdns_browser, &error);
+	dmap_mdns_browser_start (plugin->mdns_browser, &error);
 	if (error != NULL) {
 		g_warning ("Unable to start mDNS browsing: %s", error->message);
 		g_error_free (error);
 	}
 
-	plugin->priv->source_lookup = g_hash_table_new_full ((GHashFunc)g_str_hash,
+	plugin->source_lookup = g_hash_table_new_full ((GHashFunc)g_str_hash,
 							     (GEqualFunc)g_str_equal,
 							     (GDestroyNotify)g_free,
 							     (GDestroyNotify)remove_source);
@@ -598,27 +550,27 @@ stop_browsing (RBDaapPlugin *plugin)
 {
 	GError *error;
 
-	if (plugin->priv->mdns_browser == NULL) {
+	if (plugin->mdns_browser == NULL) {
 		return;
 	}
 
 	rb_debug ("Destroying DAAP source lookup");
 
-	g_hash_table_destroy (plugin->priv->source_lookup);
-	plugin->priv->source_lookup = NULL;
+	g_hash_table_destroy (plugin->source_lookup);
+	plugin->source_lookup = NULL;
 
-	g_signal_handlers_disconnect_by_func (plugin->priv->mdns_browser, mdns_service_added, plugin);
-	g_signal_handlers_disconnect_by_func (plugin->priv->mdns_browser, mdns_service_removed, plugin);
+	g_signal_handlers_disconnect_by_func (plugin->mdns_browser, mdns_service_added, plugin);
+	g_signal_handlers_disconnect_by_func (plugin->mdns_browser, mdns_service_removed, plugin);
 
 	error = NULL;
-	dmap_mdns_browser_stop (plugin->priv->mdns_browser, &error);
+	dmap_mdns_browser_stop (plugin->mdns_browser, &error);
 	if (error != NULL) {
 		g_warning ("Unable to stop mDNS browsing: %s", error->message);
 		g_error_free (error);
 	}
 
-	g_object_unref (plugin->priv->mdns_browser);
-	plugin->priv->mdns_browser = NULL;
+	g_object_unref (plugin->mdns_browser);
+	plugin->mdns_browser = NULL;
 }
 
 static void
@@ -626,9 +578,9 @@ dacp_settings_changed_cb (GSettings *settings, const char *key, RBDaapPlugin *pl
 {
 	if (g_strcmp0 (key, "enable-remote") == 0) {
 		if (g_settings_get_boolean (settings, key)) {
-			dacp_share_start_lookup (plugin->priv->dacp_share);
+			dacp_share_start_lookup (plugin->dacp_share);
 		} else {
-			dacp_share_stop_lookup (plugin->priv->dacp_share);
+			dacp_share_stop_lookup (plugin->dacp_share);
 		}
 	}
 }
@@ -647,8 +599,8 @@ settings_changed_cb (GSettings *settings, const char *key, RBDaapPlugin *plugin)
 		GtkWidget *password_entry;
 		gboolean enabled = g_settings_get_boolean (settings, key);
 
-		password_check = GTK_TOGGLE_BUTTON (gtk_builder_get_object (plugin->priv->builder, "daap_password_check"));
-		password_entry = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "daap_password_entry"));
+		password_check = GTK_TOGGLE_BUTTON (gtk_builder_get_object (plugin->builder, "daap_password_check"));
+		password_entry = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "daap_password_entry"));
 
 		gtk_widget_set_sensitive (password_entry, enabled && gtk_toggle_button_get_active (password_check));
 		gtk_widget_set_sensitive (GTK_WIDGET (password_check), enabled);
@@ -764,26 +716,28 @@ rb_daap_plugin_find_source_for_uri (RBDaapPlugin *plugin, const char *uri)
 	s = strchr (ip, ':');
 	*s = '\0';
 
-	source = (RBDAAPSource *)g_hash_table_find (plugin->priv->source_lookup, (GHRFunc)source_host_find, ip);
+	source = (RBDAAPSource *)g_hash_table_find (plugin->source_lookup, (GHRFunc)source_host_find, ip);
 
 	g_free (ip);
 
 	return source;
 }
 
-/* preferences dialog */
-
-static void
-preferences_response_cb (GtkWidget *dialog, gint response, RBPlugin *plugin)
+gboolean
+rb_daap_plugin_shutdown (RBDaapPlugin *plugin)
 {
-	gtk_widget_hide (dialog);
+	return plugin->shutdown;
 }
 
+/* preferences dialog */
+
+/* should move this to a separate class really */
+
 static void
 forget_remotes_button_toggled_cb (GtkToggleButton *button,
 				  RBDaapPlugin *plugin)
 {
-	g_settings_reset (plugin->priv->dacp_settings, "known-remotes");
+	g_settings_reset (plugin->dacp_settings, "known-remotes");
 }
 
 static gboolean
@@ -796,7 +750,7 @@ share_name_entry_focus_out_event_cb (GtkEntry *entry,
 	char       *old_name;
 
 	name = gtk_entry_get_text (entry);
-	old_name = g_settings_get_string (plugin->priv->settings, "share-name");
+	old_name = g_settings_get_string (plugin->settings, "share-name");
 
 	if (name == NULL && old_name == NULL) {
 		changed = FALSE;
@@ -809,7 +763,7 @@ share_name_entry_focus_out_event_cb (GtkEntry *entry,
 	}
 
 	if (changed) {
-		g_settings_set_string (plugin->priv->settings, "share-name", name);
+		g_settings_set_string (plugin->settings, "share-name", name);
 	}
 
 	g_free (old_name);
@@ -827,7 +781,7 @@ share_password_entry_focus_out_event_cb (GtkEntry *entry,
 	char       *old_pw;
 
 	pw = gtk_entry_get_text (entry);
-	old_pw = g_settings_get_string (plugin->priv->settings, "share-password");
+	old_pw = g_settings_get_string (plugin->settings, "share-password");
 
 	if (pw == NULL && old_pw == NULL) {
 		changed = FALSE;
@@ -840,7 +794,7 @@ share_password_entry_focus_out_event_cb (GtkEntry *entry,
 	}
 
 	if (changed) {
-		g_settings_set_string (plugin->priv->settings, "share-password", pw);
+		g_settings_set_string (plugin->settings, "share-password", pw);
 	}
 
 	g_free (old_pw);
@@ -860,25 +814,25 @@ update_config_widget (RBDaapPlugin *plugin)
 	char *name;
 	char *password;
 
-	check = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "daap_enable_check"));
-	remote_check = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "dacp_enable_check"));
-	password_check = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "daap_password_check"));
-	name_entry = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "daap_name_entry"));
-	password_entry = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "daap_password_entry"));
-	forget_remotes_button = GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "forget_remotes_button"));
+	check = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "daap_enable_check"));
+	remote_check = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "dacp_enable_check"));
+	password_check = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "daap_password_check"));
+	name_entry = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "daap_name_entry"));
+	password_entry = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "daap_password_entry"));
+	forget_remotes_button = GTK_WIDGET (gtk_builder_get_object (plugin->builder, "forget_remotes_button"));
 
-	g_settings_bind (plugin->priv->settings, "enable-sharing", check, "active", G_SETTINGS_BIND_DEFAULT);
-	g_settings_bind (plugin->priv->dacp_settings, "enable-remote", remote_check, "active", G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind (plugin->settings, "enable-sharing", check, "active", G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind (plugin->dacp_settings, "enable-remote", remote_check, "active", G_SETTINGS_BIND_DEFAULT);
 
-	/*g_signal_connect (check, "toggled", G_CALLBACK (share_check_button_toggled_cb), plugin->priv->builder);*/
+	/*g_signal_connect (check, "toggled", G_CALLBACK (share_check_button_toggled_cb), plugin->builder);*/
 
 	/* probably needs rethinking to deal with remotes.. */
-	g_settings_bind (plugin->priv->settings, "require-password", password_check, "active", G_SETTINGS_BIND_DEFAULT);
-	g_settings_bind (plugin->priv->settings, "require-password", password_entry, "sensitive", G_SETTINGS_BIND_NO_SENSITIVITY);
+	g_settings_bind (plugin->settings, "require-password", password_check, "active", G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind (plugin->settings, "require-password", password_entry, "sensitive", G_SETTINGS_BIND_NO_SENSITIVITY);
 
 	g_signal_connect_object (forget_remotes_button, "clicked", G_CALLBACK (forget_remotes_button_toggled_cb), plugin, 0);
 
-	name = g_settings_get_string (plugin->priv->settings, "share-name");
+	name = g_settings_get_string (plugin->settings, "share-name");
 	if (name == NULL || name[0] == '\0') {
 		g_free (name);
 		name = rb_daap_sharing_default_share_name ();
@@ -893,7 +847,7 @@ update_config_widget (RBDaapPlugin *plugin)
 				 plugin,
 				 0);
 
-	password = g_settings_get_string (plugin->priv->settings, "share-password");
+	password = g_settings_get_string (plugin->settings, "share-password");
 	if (password != NULL) {
 		gtk_entry_set_text (GTK_ENTRY (password_entry), password);
 		g_free (password);
@@ -908,52 +862,27 @@ update_config_widget (RBDaapPlugin *plugin)
 }
 
 static GtkWidget *
-make_config_widget (RBDaapPlugin *plugin)
+impl_create_configure_widget (PeasGtkConfigurable *bplugin)
 {
 	char *builder_file;
+	RBDaapPlugin *plugin = RB_DAAP_PLUGIN (bplugin);
 
-	builder_file = rb_plugin_find_file (RB_PLUGIN (plugin), "daap-prefs.ui");
+	builder_file = rb_find_plugin_data_file (G_OBJECT (plugin), "daap-prefs.ui");
 	if (builder_file == NULL) {
 		return NULL;
 	}
 
-	plugin->priv->builder = rb_builder_load (builder_file, NULL);
+	plugin->builder = rb_builder_load (builder_file, NULL);
 	g_free (builder_file);
 
 	update_config_widget (plugin);
-	return GTK_WIDGET (gtk_builder_get_object (plugin->priv->builder, "daap_vbox"));
+	return GTK_WIDGET (gtk_builder_get_object (plugin->builder, "daap_vbox"));
 }
 
-
-static GtkWidget*
-impl_create_configure_dialog (RBPlugin *bplugin)
+static void
+peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface)
 {
-	RBDaapPlugin *plugin = RB_DAAP_PLUGIN (bplugin);
-
-	if (plugin->priv->preferences == NULL) {
-		GtkWidget *widget;
-
-		widget = make_config_widget (plugin);
-
-		plugin->priv->preferences = gtk_dialog_new_with_buttons (_("DAAP Music Sharing Preferences"),
-								   NULL,
-								   GTK_DIALOG_DESTROY_WITH_PARENT,
-								   GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-								   NULL);
-		g_signal_connect (G_OBJECT (plugin->priv->preferences),
-				  "response",
-				  G_CALLBACK (preferences_response_cb),
-				  plugin);
-		gtk_widget_hide_on_delete (plugin->priv->preferences);
-
-		gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (plugin->priv->preferences))),
-				   widget);
-	} else {
-		update_config_widget (plugin);
-	}
-
-	gtk_widget_show_all (plugin->priv->preferences);
-	return plugin->priv->preferences;
+	iface->create_configure_widget = impl_create_configure_widget;
 }
 
 /* DAAP DBus interface */
@@ -968,7 +897,7 @@ daap_dbus_method_call (GDBusConnection *connection,
 		       GDBusMethodInvocation *invocation,
 		       RBDaapPlugin *plugin)
 {
-	if (plugin->priv->shutdown) {
+	if (plugin->shutdown) {
 		rb_debug ("ignoring %s call", method_name);
 		return;
 	}
@@ -989,7 +918,7 @@ daap_dbus_method_call (GDBusConnection *connection,
 
 		g_variant_get (parameters, "(&s)", &service_name);
 		rb_debug ("removing DAAP source %s", service_name);
-		mdns_service_removed (plugin->priv->mdns_browser, service_name, plugin);
+		mdns_service_removed (plugin->mdns_browser, service_name, plugin);
 
 		g_dbus_method_invocation_return_value (invocation, NULL);
 	}
@@ -1008,14 +937,14 @@ register_daap_dbus_iface (RBDaapPlugin *plugin)
 	GDBusNodeInfo *node_info;
 	GDBusInterfaceInfo *iface_info;
 
-	if (plugin->priv->dbus_intf_id != 0) {
+	if (plugin->dbus_intf_id != 0) {
 		rb_debug ("DAAP DBus interface already registered");
 		return;
 	}
 
-	if (plugin->priv->bus == NULL) {
-		plugin->priv->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
-		if (plugin->priv->bus == NULL) {
+	if (plugin->bus == NULL) {
+		plugin->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+		if (plugin->bus == NULL) {
 			rb_debug ("Unable to register DAAP DBus interface: %s", error->message);
 			g_clear_error (&error);
 			return;
@@ -1030,8 +959,8 @@ register_daap_dbus_iface (RBDaapPlugin *plugin)
 	}
 
 	iface_info = g_dbus_node_info_lookup_interface (node_info, DAAP_DBUS_IFACE);
-	plugin->priv->dbus_intf_id =
-		g_dbus_connection_register_object (plugin->priv->bus,
+	plugin->dbus_intf_id =
+		g_dbus_connection_register_object (plugin->bus,
 						   DAAP_DBUS_PATH,
 						   iface_info,
 						   &daap_dbus_vtable,
@@ -1049,17 +978,38 @@ register_daap_dbus_iface (RBDaapPlugin *plugin)
 static void
 unregister_daap_dbus_iface (RBDaapPlugin *plugin)
 {
-	if (plugin->priv->dbus_intf_id == 0) {
+	if (plugin->dbus_intf_id == 0) {
 		rb_debug ("DAAP DBus interface not registered");
 		return;
 	}
 
-	if (plugin->priv->bus == NULL) {
+	if (plugin->bus == NULL) {
 		rb_debug ("no bus connection");
 		return;
 	}
 
-	g_dbus_connection_unregister_object (plugin->priv->bus, plugin->priv->dbus_intf_id);
-	plugin->priv->dbus_intf_id = 0;
+	g_dbus_connection_unregister_object (plugin->bus, plugin->dbus_intf_id);
+	plugin->dbus_intf_id = 0;
 }
 
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_daap_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_daap_container_record_register_type (G_TYPE_MODULE (module));
+	_rb_daap_record_factory_register_type (G_TYPE_MODULE (module));
+	_rb_daap_record_register_type (G_TYPE_MODULE (module));
+	_rb_daap_source_register_type (G_TYPE_MODULE (module));
+	_rb_dacp_pairing_page_register_type (G_TYPE_MODULE (module));
+	_rb_dacp_player_register_type (G_TYPE_MODULE (module));
+	_rb_dmap_container_db_adapter_register_type (G_TYPE_MODULE (module));
+	_rb_rhythmdb_dmap_db_adapter_register_type (G_TYPE_MODULE (module));
+	_rb_rhythmdb_query_model_dmap_db_adapter_register_type (G_TYPE_MODULE (module));
+
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_DAAP_PLUGIN);
+	peas_object_module_register_extension_type (module,
+						    PEAS_GTK_TYPE_CONFIGURABLE,
+						    RB_TYPE_DAAP_PLUGIN);
+}
diff --git a/plugins/daap/rb-daap-plugin.h b/plugins/daap/rb-daap-plugin.h
index 4f7686f..a355ebc 100644
--- a/plugins/daap/rb-daap-plugin.h
+++ b/plugins/daap/rb-daap-plugin.h
@@ -28,7 +28,8 @@
 #ifndef __RB_DAAP_PLUGIN_H
 #define __RB_DAAP_PLUGIN_H
 
-#include "rb-plugin.h"
+#include <libpeas/peas.h>
+
 #include "rb-daap-source.h"
 
 G_BEGIN_DECLS
@@ -40,19 +41,8 @@ G_BEGIN_DECLS
 #define RB_IS_DAAP_PLUGIN_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_PLUGIN))
 #define RB_DAAP_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_PLUGIN, RBDaapPluginClass))
 
-typedef struct RBDaapPluginPrivate RBDaapPluginPrivate;
-
-typedef struct
-{
-	RBPlugin parent;
-
-	RBDaapPluginPrivate *priv;
-} RBDaapPlugin;
-
-typedef struct
-{
-	RBPluginClass parent;
-} RBDaapPluginClass;
+typedef struct _RBDaapPlugin RBDaapPlugin;
+typedef struct _RBDaapPluginClass RBDaapPluginClass;
 
 GType		rb_daap_plugin_get_type		(void);
 
@@ -62,8 +52,8 @@ GdkPixbuf *	rb_daap_plugin_get_icon 	(RBDaapPlugin *plugin,
 
 RBDAAPSource *	rb_daap_plugin_find_source_for_uri (RBDaapPlugin *plugin,
 						 const char *uri);
+gboolean	rb_daap_plugin_shutdown		(RBDaapPlugin *plugin);
 
 G_END_DECLS
 
 #endif /* __RB_DAAP_PLUGIN_H */
-
diff --git a/plugins/daap/rb-daap-record-factory.c b/plugins/daap/rb-daap-record-factory.c
index 393cf31..35d920e 100644
--- a/plugins/daap/rb-daap-record-factory.c
+++ b/plugins/daap/rb-daap-record-factory.c
@@ -53,6 +53,11 @@ rb_daap_record_factory_class_init (RBDAAPRecordFactoryClass *klass)
 }
 
 static void
+rb_daap_record_factory_class_finalize (RBDAAPRecordFactoryClass *klass)
+{
+}
+
+static void
 rb_daap_record_factory_interface_init (gpointer iface, gpointer data)
 {
 	DMAPRecordFactoryIface *factory = iface;
@@ -62,9 +67,12 @@ rb_daap_record_factory_interface_init (gpointer iface, gpointer data)
 	factory->create = rb_daap_record_factory_create;
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBDAAPRecordFactory, rb_daap_record_factory, G_TYPE_OBJECT, 
-			 G_IMPLEMENT_INTERFACE (DMAP_TYPE_RECORD_FACTORY,
-					        rb_daap_record_factory_interface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBDAAPRecordFactory,
+				rb_daap_record_factory,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_RECORD_FACTORY,
+							       rb_daap_record_factory_interface_init))
 
 RBDAAPRecordFactory *
 rb_daap_record_factory_new (void)
@@ -75,3 +83,9 @@ rb_daap_record_factory_new (void)
 
 	return factory;
 }
+
+void
+_rb_daap_record_factory_register_type (GTypeModule *module)
+{
+	rb_daap_record_factory_register_type (module);
+}
diff --git a/plugins/daap/rb-daap-record-factory.h b/plugins/daap/rb-daap-record-factory.h
index 3bb9961..f0b6bf0 100644
--- a/plugins/daap/rb-daap-record-factory.h
+++ b/plugins/daap/rb-daap-record-factory.h
@@ -62,6 +62,8 @@ RBDAAPRecordFactory *rb_daap_record_factory_new      (void);
 
 DMAPRecord            *rb_daap_record_factory_create   (DMAPRecordFactory *factory, gpointer user_data);
 
+void                   _rb_daap_record_factory_register_type (GTypeModule *module);
+
 #endif /* __RB_DAAP_RECORD_FACTORY */
 
 G_END_DECLS
diff --git a/plugins/daap/rb-daap-record.c b/plugins/daap/rb-daap-record.c
index ff5c127..08e28b5 100644
--- a/plugins/daap/rb-daap-record.c
+++ b/plugins/daap/rb-daap-record.c
@@ -344,6 +344,11 @@ rb_daap_record_class_init (RBDAAPRecordClass *klass)
 }
 
 static void
+rb_daap_record_class_finalize (RBDAAPRecordClass *klass)
+{
+}
+
+static void
 rb_daap_record_daap_iface_init (gpointer iface, gpointer data)
 {
 	DAAPRecordIface *daap_record = iface;
@@ -362,11 +367,15 @@ rb_daap_record_dmap_iface_init (gpointer iface, gpointer data)
 	g_assert (G_TYPE_FROM_INTERFACE (dmap_record) == DMAP_TYPE_RECORD);
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBDAAPRecord, rb_daap_record, G_TYPE_OBJECT,
-			 G_IMPLEMENT_INTERFACE (DAAP_TYPE_RECORD, rb_daap_record_daap_iface_init)
-			 G_IMPLEMENT_INTERFACE (DMAP_TYPE_RECORD, rb_daap_record_dmap_iface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBDAAPRecord,
+				rb_daap_record,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DAAP_TYPE_RECORD, rb_daap_record_daap_iface_init)
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_RECORD, rb_daap_record_dmap_iface_init))
 
-static void rb_daap_record_finalize (GObject *object)
+static void
+rb_daap_record_finalize (GObject *object)
 {
 	RBDAAPRecord *record = RB_DAAP_RECORD (object);
 
@@ -381,7 +390,8 @@ static void rb_daap_record_finalize (GObject *object)
 	G_OBJECT_CLASS (rb_daap_record_parent_class)->finalize (object);
 }
 
-RBDAAPRecord *rb_daap_record_new (RhythmDBEntry *entry)
+RBDAAPRecord *
+rb_daap_record_new (RhythmDBEntry *entry)
 {
 	RBDAAPRecord *record = NULL;
 	record = RB_DAAP_RECORD (g_object_new (RB_TYPE_DAAP_RECORD, NULL));
@@ -457,3 +467,9 @@ RBDAAPRecord *rb_daap_record_new (RhythmDBEntry *entry)
 
 	return record;
 }
+
+void
+_rb_daap_record_register_type (GTypeModule *module)
+{
+	rb_daap_record_register_type (module);
+}
diff --git a/plugins/daap/rb-daap-record.h b/plugins/daap/rb-daap-record.h
index 0a1edd0..1f128a3 100644
--- a/plugins/daap/rb-daap-record.h
+++ b/plugins/daap/rb-daap-record.h
@@ -67,6 +67,8 @@ void          rb_daap_record_set_transcode_format (DAAPRecord *record,
 GInputStream *rb_daap_record_read            (DAAPRecord *record,
 						 GError **err);
 
+void          _rb_daap_record_register_type  (GTypeModule *module);
+
 #endif /* __RB_DAAP_RECORD */
 
 G_END_DECLS
diff --git a/plugins/daap/rb-daap-source.c b/plugins/daap/rb-daap-source.c
index 2ab2f46..4e12aee 100644
--- a/plugins/daap/rb-daap-source.c
+++ b/plugins/daap/rb-daap-source.c
@@ -110,9 +110,9 @@ enum {
 	PROP_PASSWORD_PROTECTED
 };
 
-G_DEFINE_TYPE (RBDAAPSource, rb_daap_source, RB_TYPE_BROWSER_SOURCE);
+G_DEFINE_DYNAMIC_TYPE (RBDAAPSource, rb_daap_source, RB_TYPE_BROWSER_SOURCE);
 
-G_DEFINE_TYPE (RBDAAPEntryType, rb_daap_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
+G_DEFINE_DYNAMIC_TYPE (RBDAAPEntryType, rb_daap_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
 
 static char *
 rb_daap_entry_type_get_playback_uri (RhythmDBEntryType *etype, RhythmDBEntry *entry)
@@ -135,6 +135,11 @@ rb_daap_entry_type_class_init (RBDAAPEntryTypeClass *klass)
 }
 
 static void
+rb_daap_entry_type_class_finalize (RBDAAPEntryTypeClass *klass)
+{
+}
+
+static void
 rb_daap_entry_type_init (RBDAAPEntryType *etype)
 {
 }
@@ -221,6 +226,11 @@ rb_daap_source_class_init (RBDAAPSourceClass *klass)
 }
 
 static void
+rb_daap_source_class_finalize (RBDAAPSourceClass *klass)
+{
+}
+
+static void
 rb_daap_source_init (RBDAAPSource *source)
 {
 	source->priv = G_TYPE_INSTANCE_GET_PRIVATE (source,
@@ -290,7 +300,7 @@ rb_daap_source_get_property (GObject *object,
 
 RBSource *
 rb_daap_source_new (RBShell *shell,
-		    RBPlugin *plugin,
+		    GObject *plugin,
 		    const char *service_name,
 		    const char *name,
 		    const char *host,
@@ -330,7 +340,7 @@ rb_daap_source_new (RBShell *shell,
 					  "shell", shell,
 					  "visibility", TRUE,
 					  "password-protected", password_protected,
-					  "plugin", RB_PLUGIN (plugin),
+					  "plugin", G_OBJECT (plugin),
 					  "settings", g_settings_get_child (settings, "source"),
 					  NULL));
 	g_object_unref (settings);
@@ -478,7 +488,7 @@ connection_connecting_cb (DMAPConnection       *connection,
 {
 	GdkPixbuf *icon;
 	gboolean   is_connected;
-	RBPlugin  *plugin;
+	GObject *plugin;
 
 	rb_debug ("DAAP connection status: %d/%f", state, progress);
 
@@ -526,16 +536,14 @@ connection_disconnected_cb (DMAPConnection   *connection,
 			    RBDAAPSource     *source)
 {
 	GdkPixbuf *icon;
-	RBPlugin  *plugin;
-	gboolean   daap_shutdown;
+	GObject   *plugin;
 
 	rb_debug ("DAAP connection disconnected");
 
 	g_object_get (source, "plugin", &plugin, NULL);
 	g_assert (plugin != NULL);
 
-	g_object_get (plugin, "shutdown", &daap_shutdown, NULL);
-	if (daap_shutdown == FALSE) {
+	if (rb_daap_plugin_shutdown (RB_DAAP_PLUGIN (plugin)) == FALSE) {
 
 		icon = rb_daap_plugin_get_icon (RB_DAAP_PLUGIN (plugin),
 						source->priv->password_protected,
@@ -799,3 +807,10 @@ rb_daap_source_get_status (RBDisplayPage *page,
 
 	RB_DISPLAY_PAGE_CLASS (rb_daap_source_parent_class)->get_status (page, text, progress_text, progress);
 }
+
+void
+_rb_daap_source_register_type (GTypeModule *module)
+{
+	rb_daap_source_register_type (module);
+	rb_daap_entry_type_register_type (module);
+}
diff --git a/plugins/daap/rb-daap-source.h b/plugins/daap/rb-daap-source.h
index 667d984..b3c22b7 100644
--- a/plugins/daap/rb-daap-source.h
+++ b/plugins/daap/rb-daap-source.h
@@ -32,7 +32,6 @@
 
 #include "rb-shell.h"
 #include "rb-browser-source.h"
-#include "rb-plugin.h"
 
 #include <gst/gst.h>
 #include <libsoup/soup.h>
@@ -61,7 +60,7 @@ typedef struct {
 GType			rb_daap_source_get_type		(void);
 
 RBSource *		rb_daap_source_new 		(RBShell *shell,
-							 RBPlugin *plugin,
+							 GObject *plugin,
 							 const char *service_name,
 							 const char *name,
 							 const char *host,
@@ -73,6 +72,8 @@ void			rb_daap_source_disconnect 	(RBDAAPSource *daap_source);
 SoupMessageHeaders *	rb_daap_source_get_headers	(RBDAAPSource *source,
 							 const gchar *uri);
 
+void			_rb_daap_source_register_type	(GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* __RB_DAAP_SOURCE_H */
diff --git a/plugins/daap/rb-daap-src.c b/plugins/daap/rb-daap-src.c
index a23d634..d080a0a 100644
--- a/plugins/daap/rb-daap-src.c
+++ b/plugins/daap/rb-daap-src.c
@@ -110,7 +110,7 @@ static void rb_daap_src_get_property (GObject *object,
 static GstStateChangeReturn rb_daap_src_change_state (GstElement *element, GstStateChange transition);
 
 void
-rb_daap_src_set_plugin (RBPlugin *plugin)
+rb_daap_src_set_plugin (GObject *plugin)
 {
 	g_assert (RB_IS_DAAP_PLUGIN (plugin));
 	daap_plugin = RB_DAAP_PLUGIN (plugin);
diff --git a/plugins/daap/rb-daap-src.h b/plugins/daap/rb-daap-src.h
index ffc91c3..e63795f 100644
--- a/plugins/daap/rb-daap-src.h
+++ b/plugins/daap/rb-daap-src.h
@@ -36,7 +36,7 @@
 G_BEGIN_DECLS
 
 GType rb_daap_src_get_type (void);
-void rb_daap_src_set_plugin (RBPlugin *plugin);
+void rb_daap_src_set_plugin (GObject *plugin);
 
 G_END_DECLS
 
diff --git a/plugins/daap/rb-dacp-pairing-page.c b/plugins/daap/rb-dacp-pairing-page.c
index 77fa41d..c309fc1 100644
--- a/plugins/daap/rb-dacp-pairing-page.c
+++ b/plugins/daap/rb-dacp-pairing-page.c
@@ -105,7 +105,7 @@ enum {
 	PROP_SERVICE_NAME
 };
 
-G_DEFINE_TYPE (RBDACPPairingPage, rb_dacp_pairing_page, RB_TYPE_DISPLAY_PAGE)
+G_DEFINE_DYNAMIC_TYPE (RBDACPPairingPage, rb_dacp_pairing_page, RB_TYPE_DISPLAY_PAGE)
 
 static gboolean
 entry_insert_text_cb (GtkWidget *entry, gchar *text, gint len, gint *position, RBDACPPairingPage *page)
@@ -227,6 +227,11 @@ rb_dacp_pairing_page_class_init (RBDACPPairingPageClass *klass)
 }
 
 static void
+rb_dacp_pairing_page_class_finalize (RBDACPPairingPageClass *klass)
+{
+}
+
+static void
 rb_dacp_pairing_page_init (RBDACPPairingPage *page)
 {
 	page->priv = G_TYPE_INSTANCE_GET_PRIVATE (page,
@@ -242,12 +247,12 @@ impl_constructed (GObject *object)
 	GtkWidget *passcode_widget;
 	GtkWidget *close_pairing_button;
 	PangoFontDescription *font;
-	RBPlugin *plugin;
+	GObject *plugin;
 	int i;
 
 	g_object_get (page, "plugin", &plugin, NULL);
 
-	builder_filename = rb_plugin_find_file (RB_PLUGIN (plugin), "daap-prefs.ui");
+	builder_filename = rb_find_plugin_data_file (G_OBJECT (plugin), "daap-prefs.ui");
 	g_assert (builder_filename != NULL);
 
 	page->priv->builder = rb_builder_load (builder_filename, NULL);
@@ -328,7 +333,7 @@ impl_get_property (GObject *object,
 }
 
 RBDACPPairingPage *
-rb_dacp_pairing_page_new (RBPlugin *plugin,
+rb_dacp_pairing_page_new (GObject *plugin,
 			  RBShell *shell,
 			  DACPShare *dacp_share,
 			  const char *display_name,
@@ -339,7 +344,7 @@ rb_dacp_pairing_page_new (RBPlugin *plugin,
 	int icon_size;
 	GdkPixbuf *icon_pixbuf;
 
-	icon_filename = rb_plugin_find_file (plugin, "remote-icon.png");
+	icon_filename = rb_find_plugin_data_file (plugin, "remote-icon.png");
 	gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR, &icon_size, NULL);
 	icon_pixbuf = gdk_pixbuf_new_from_file_at_size (icon_filename, icon_size, icon_size, NULL);
 
@@ -429,7 +434,7 @@ remote_paired_cb (DACPShare *share, gchar *service_name, gboolean connected, RBD
 }
 
 DACPShare *
-rb_daap_create_dacp_share (RBPlugin *plugin)
+rb_daap_create_dacp_share (GObject *plugin)
 {
 	DACPShare *share;
 	DACPPlayer *player;
@@ -443,7 +448,7 @@ rb_daap_create_dacp_share (RBPlugin *plugin)
 	GSettings *settings;
 	gchar *name;
 
-	g_object_get (plugin, "shell", &shell, NULL);
+	g_object_get (plugin, "object", &shell, NULL);
 
 	g_object_get (shell,
 	              "db", &rdb,
@@ -501,6 +506,7 @@ rb_daap_create_dacp_share (RBPlugin *plugin)
 	g_object_unref (rdb);
 	g_object_unref (playlist_manager);
 	g_object_unref (player);
+	g_object_unref (shell);
 
 	return share;
 }
@@ -609,7 +615,7 @@ dacp_remote_added (DACPShare    *share,
 
 	rb_debug ("Remote %s (%s) found", service_name, display_name);
 
-	g_object_get (plugin, "shell", &shell, NULL);
+	g_object_get (plugin, "object", &shell, NULL);
 
 	GDK_THREADS_ENTER ();
 
@@ -626,7 +632,7 @@ dacp_remote_added (DACPShare    *share,
 			rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (page_group), NULL);
 		}
 
-		page = rb_dacp_pairing_page_new (RB_PLUGIN (plugin), shell, share, display_name, service_name);
+		page = rb_dacp_pairing_page_new (G_OBJECT (plugin), shell, share, display_name, service_name);
 
 		rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (page), RB_DISPLAY_PAGE (page_group));
 	} else {
@@ -634,6 +640,8 @@ dacp_remote_added (DACPShare    *share,
 	}
 
 	GDK_THREADS_LEAVE ();
+
+	g_object_unref (shell);
 }
 
 static void
@@ -646,7 +654,7 @@ dacp_remote_removed (DACPShare       *share,
 
 	rb_debug ("Remote '%s' went away", service_name);
 
-	g_object_get (plugin, "shell", &shell, NULL);
+	g_object_get (plugin, "object", &shell, NULL);
 
 	GDK_THREADS_ENTER ();
 
@@ -656,4 +664,12 @@ dacp_remote_removed (DACPShare       *share,
 	}
 
 	GDK_THREADS_LEAVE ();
+
+	g_object_unref (shell);
+}
+
+void
+_rb_dacp_pairing_page_register_type (GTypeModule *module)
+{
+	rb_dacp_pairing_page_register_type (module);
 }
diff --git a/plugins/daap/rb-dacp-pairing-page.h b/plugins/daap/rb-dacp-pairing-page.h
index e1db334..fc8e06d 100644
--- a/plugins/daap/rb-dacp-pairing-page.h
+++ b/plugins/daap/rb-dacp-pairing-page.h
@@ -32,7 +32,6 @@
 
 #include "rb-shell.h"
 #include "rb-display-page.h"
-#include "rb-plugin.h"
 
 #include <libdmapsharing/dmap.h>
 
@@ -59,7 +58,7 @@ typedef struct {
 
 GType 		rb_dacp_pairing_page_get_type 	(void);
 
-RBDACPPairingPage *rb_dacp_pairing_page_new 	(RBPlugin *plugin,
+RBDACPPairingPage *rb_dacp_pairing_page_new 	(GObject *plugin,
 						 RBShell *shell,
 						 DACPShare *dacp_share,
 						 const char *display_name,
@@ -68,7 +67,9 @@ RBDACPPairingPage *rb_dacp_pairing_page_new 	(RBPlugin *plugin,
 void           rb_dacp_pairing_page_remote_found (RBDACPPairingPage *page);
 void           rb_dacp_pairing_page_remote_lost (RBDACPPairingPage *page);
 
-DACPShare     *rb_daap_create_dacp_share       (RBPlugin *plugin);
+DACPShare     *rb_daap_create_dacp_share       (GObject *plugin);
+
+void           _rb_dacp_pairing_page_register_type (GTypeModule *module);
 
 G_END_DECLS
 
diff --git a/plugins/daap/rb-dacp-player.c b/plugins/daap/rb-dacp-player.c
index 19048a0..9b92aac 100644
--- a/plugins/daap/rb-dacp-player.c
+++ b/plugins/daap/rb-dacp-player.c
@@ -102,8 +102,12 @@ rb_dacp_player_iface_init (gpointer iface, gpointer data)
 	dacp_player->cue_play            = rb_dacp_player_cue_play;
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBDACPPlayer, rb_dacp_player, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (DACP_TYPE_PLAYER, rb_dacp_player_iface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBDACPPlayer,
+				rb_dacp_player,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DACP_TYPE_PLAYER,
+							       rb_dacp_player_iface_init))
 
 static void
 rb_dacp_player_init (RBDACPPlayer *object)
@@ -154,6 +158,11 @@ rb_dacp_player_class_init (RBDACPPlayerClass *klass)
 }
 
 static void
+rb_dacp_player_class_finalize (RBDACPPlayerClass *klass)
+{
+}
+
+static void
 rb_dacp_player_get_property (GObject *object,
                              guint prop_id,
                              GValue *value,
@@ -369,3 +378,9 @@ rb_dacp_player_cue_play (DACPPlayer *player, GList *records, guint index)
 		current++;
 	}
 }
+
+void
+_rb_dacp_player_register_type (GTypeModule *module)
+{
+	rb_dacp_player_register_type (module);
+}
diff --git a/plugins/daap/rb-dacp-player.h b/plugins/daap/rb-dacp-player.h
index 3063dce..ff2aa18 100644
--- a/plugins/daap/rb-dacp-player.h
+++ b/plugins/daap/rb-dacp-player.h
@@ -66,6 +66,8 @@ GType rb_dacp_player_get_type (void) G_GNUC_CONST;
 
 RBDACPPlayer *rb_dacp_player_new (RBShell *shell);
 
+void _rb_dacp_player_register_type (GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* _RB_DACP_PLAYER_H_ */
diff --git a/plugins/daap/rb-dmap-container-db-adapter.c b/plugins/daap/rb-dmap-container-db-adapter.c
index fce821c..1340d3a 100644
--- a/plugins/daap/rb-dmap-container-db-adapter.c
+++ b/plugins/daap/rb-dmap-container-db-adapter.c
@@ -48,7 +48,6 @@ typedef struct ForeachAdapterData {
 static guint find_by_id (gconstpointer a, gconstpointer b)
 {
 	return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "daap_id")) != GPOINTER_TO_UINT (b);
-
 }
 
 static DMAPContainerRecord *
@@ -137,6 +136,11 @@ rb_dmap_container_db_adapter_class_init (RBDMAPContainerDbAdapterClass *klass)
 }
 
 static void
+rb_dmap_container_db_adapter_class_finalize (RBDMAPContainerDbAdapterClass *klass)
+{
+}
+
+static void
 rb_dmap_container_db_adapter_interface_init (gpointer iface, gpointer data)
 {
 	DMAPContainerDbIface *dmap_db = iface;
@@ -148,8 +152,12 @@ rb_dmap_container_db_adapter_interface_init (gpointer iface, gpointer data)
 	dmap_db->count = rb_dmap_container_db_adapter_count;
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBDMAPContainerDbAdapter, rb_dmap_container_db_adapter, G_TYPE_OBJECT, 
-			 G_IMPLEMENT_INTERFACE (DMAP_TYPE_CONTAINER_DB, rb_dmap_container_db_adapter_interface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBDMAPContainerDbAdapter,
+				rb_dmap_container_db_adapter,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_CONTAINER_DB,
+							       rb_dmap_container_db_adapter_interface_init))
 
 static void
 assign_id (RBPlaylistManager *mgr,
@@ -194,3 +202,9 @@ rb_dmap_container_db_adapter_new (RBPlaylistManager *playlist_manager)
 
 	return db;
 }
+
+void
+_rb_dmap_container_db_adapter_register_type (GTypeModule *module)
+{
+	rb_dmap_container_db_adapter_register_type (module);
+}
diff --git a/plugins/daap/rb-dmap-container-db-adapter.h b/plugins/daap/rb-dmap-container-db-adapter.h
index 160c80c..2587a8e 100644
--- a/plugins/daap/rb-dmap-container-db-adapter.h
+++ b/plugins/daap/rb-dmap-container-db-adapter.h
@@ -59,6 +59,8 @@ RBDMAPContainerDbAdapter *rb_dmap_container_db_adapter_new (
 				RBPlaylistManager *playlist_manager);
 GType rb_dmap_container_db_adapter_get_type (void);
 
+void _rb_dmap_container_db_adapter_register_type (GTypeModule *module);
+
 #endif /* _RB_DMAP_CONTAINER_DB_ADAPTER */
 
 G_END_DECLS
diff --git a/plugins/daap/rb-rhythmdb-dmap-db-adapter.c b/plugins/daap/rb-rhythmdb-dmap-db-adapter.c
index f83117e..415f9f4 100644
--- a/plugins/daap/rb-rhythmdb-dmap-db-adapter.c
+++ b/plugins/daap/rb-rhythmdb-dmap-db-adapter.c
@@ -249,6 +249,11 @@ rb_rhythmdb_dmap_db_adapter_class_init (RBRhythmDBDMAPDbAdapterClass *klass)
 }
 
 static void
+rb_rhythmdb_dmap_db_adapter_class_finalize (RBRhythmDBDMAPDbAdapterClass *klass)
+{
+}
+
+static void
 rb_rhythmdb_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
 {
 	DMAPDbIface *dmap_db = iface;
@@ -261,8 +266,12 @@ rb_rhythmdb_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
 	dmap_db->count = rb_rhythmdb_dmap_db_adapter_count;
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBRhythmDBDMAPDbAdapter, rb_rhythmdb_dmap_db_adapter, G_TYPE_OBJECT, 
-			 G_IMPLEMENT_INTERFACE (DMAP_TYPE_DB, rb_rhythmdb_dmap_db_adapter_interface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBRhythmDBDMAPDbAdapter,
+				rb_rhythmdb_dmap_db_adapter,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_DB,
+							       rb_rhythmdb_dmap_db_adapter_interface_init))
 
 RBRhythmDBDMAPDbAdapter *
 rb_rhythmdb_dmap_db_adapter_new (RhythmDB *rdb, RhythmDBEntryType *entry_type)
@@ -277,3 +286,9 @@ rb_rhythmdb_dmap_db_adapter_new (RhythmDB *rdb, RhythmDBEntryType *entry_type)
 
 	return db;
 }
+
+void
+_rb_rhythmdb_dmap_db_adapter_register_type (GTypeModule *module)
+{
+	rb_rhythmdb_dmap_db_adapter_register_type (module);
+}
diff --git a/plugins/daap/rb-rhythmdb-dmap-db-adapter.h b/plugins/daap/rb-rhythmdb-dmap-db-adapter.h
index 32782ef..ea0d20f 100644
--- a/plugins/daap/rb-rhythmdb-dmap-db-adapter.h
+++ b/plugins/daap/rb-rhythmdb-dmap-db-adapter.h
@@ -56,6 +56,8 @@ typedef struct {
 RBRhythmDBDMAPDbAdapter *rb_rhythmdb_dmap_db_adapter_new (RhythmDB *db, RhythmDBEntryType *entry_type);
 GType rb_rhythmdb_dmap_db_adapter_get_type (void);
 
+void _rb_rhythmdb_dmap_db_adapter_register_type (GTypeModule *module);
+
 #endif /* _RB_RHYTHMDB_DMAP_DB_ADAPTER */
 
 G_END_DECLS
diff --git a/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c
index 0a341e1..161b92a 100644
--- a/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c
+++ b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c
@@ -127,6 +127,11 @@ rb_rhythmdb_query_model_dmap_db_adapter_class_init (RBRhythmDBQueryModelDMAPDbAd
 }
 
 static void
+rb_rhythmdb_query_model_dmap_db_adapter_class_finalize (RBRhythmDBQueryModelDMAPDbAdapterClass *klass)
+{
+}
+
+static void
 rb_rhythmdb_query_model_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
 {
 	DMAPDbIface *dmap_db = iface;
@@ -139,18 +144,28 @@ rb_rhythmdb_query_model_dmap_db_adapter_interface_init (gpointer iface, gpointer
 	dmap_db->count = rb_rhythmdb_query_model_dmap_db_adapter_count;
 }
 
-G_DEFINE_TYPE_WITH_CODE (RBRhythmDBQueryModelDMAPDbAdapter, rb_rhythmdb_query_model_dmap_db_adapter, G_TYPE_OBJECT, 
-			 G_IMPLEMENT_INTERFACE (DMAP_TYPE_DB, rb_rhythmdb_query_model_dmap_db_adapter_interface_init))
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBRhythmDBQueryModelDMAPDbAdapter,
+				rb_rhythmdb_query_model_dmap_db_adapter,
+				G_TYPE_OBJECT,
+				0,
+				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_DB,
+							       rb_rhythmdb_query_model_dmap_db_adapter_interface_init))
 
 RBRhythmDBQueryModelDMAPDbAdapter *
 rb_rhythmdb_query_model_dmap_db_adapter_new (RhythmDBQueryModel *model)
 {
 	RBRhythmDBQueryModelDMAPDbAdapter *db;
 
-	db = RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (g_object_new (RB_TYPE_DMAP_DB_ADAPTER,
+	db = RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (g_object_new (RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER,
 					       NULL));
 
 	db->priv->model = model;
 
 	return db;
 }
+
+void
+_rb_rhythmdb_query_model_dmap_db_adapter_register_type (GTypeModule *module)
+{
+	rb_rhythmdb_query_model_dmap_db_adapter_register_type (module);
+}
diff --git a/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h
index d35147a..b18d499 100644
--- a/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h
+++ b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h
@@ -34,13 +34,13 @@
 
 G_BEGIN_DECLS
 
-#define RB_TYPE_DMAP_DB_ADAPTER         (rb_rhythmdb_query_model_dmap_db_adapter_get_type ())
-#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapter))
-#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterClass))
-#define RB_IS_DMAP_DB_ADAPTER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DMAP_DB_ADAPTER))
-#define RB_IS_DMAP_DB_ADAPTER_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DMAP_DB_ADAPTER_CLASS))
-#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterClass))
-#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterPrivate))
+#define RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER         (rb_rhythmdb_query_model_dmap_db_adapter_get_type ())
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapter))
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterClass))
+#define RB_IS_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER))
+#define RB_IS_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_CLASS))
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterClass))
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterPrivate))
 
 typedef struct RBRhythmDBQueryModelDMAPDbAdapterPrivate RBRhythmDBQueryModelDMAPDbAdapterPrivate;
 
@@ -56,6 +56,8 @@ typedef struct {
 RBRhythmDBQueryModelDMAPDbAdapter *rb_rhythmdb_query_model_dmap_db_adapter_new (RhythmDBQueryModel *db);
 GType rb_rhythmdb_query_model_dmap_db_adapter_get_type (void);
 
+void _rb_rhythmdb_query_model_dmap_db_adapter_register_type (GTypeModule *module);
+
 #endif /* _RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER */
 
 G_END_DECLS
diff --git a/plugins/dbus-media-server/Makefile.am b/plugins/dbus-media-server/Makefile.am
index bd2ca41..488ee0e 100644
--- a/plugins/dbus-media-server/Makefile.am
+++ b/plugins/dbus-media-server/Makefile.am
@@ -27,11 +27,11 @@ INCLUDES = 						\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE			\
 	$(NULL)
 
-plugin_in_files = dbus-media-server.rb-plugin.in
+plugin_in_files = dbus-media-server.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/dbus-media-server/dbus-media-server.rb-plugin.in b/plugins/dbus-media-server/dbus-media-server.plugin.in
similarity index 93%
rename from plugins/dbus-media-server/dbus-media-server.rb-plugin.in
rename to plugins/dbus-media-server/dbus-media-server.plugin.in
index 7297188..b0ca90d 100644
--- a/plugins/dbus-media-server/dbus-media-server.rb-plugin.in
+++ b/plugins/dbus-media-server/dbus-media-server.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=dbus-media-server
-IAge=1
+IAge=2
 _Name=MediaServer2 D-Bus interface
 _Description=Provides an implementation of the MediaServer2 D-Bus interface specification
 Authors=Jonathan Matthew
diff --git a/plugins/dbus-media-server/rb-dbus-media-server-plugin.c b/plugins/dbus-media-server/rb-dbus-media-server-plugin.c
index 69de16a..85ed16b 100644
--- a/plugins/dbus-media-server/rb-dbus-media-server-plugin.c
+++ b/plugins/dbus-media-server/rb-dbus-media-server-plugin.c
@@ -38,7 +38,7 @@
 
 #include <lib/rb-util.h>
 #include <lib/rb-debug.h>
-#include <shell/rb-plugin.h>
+#include <plugins/rb-plugin-macros.h>
 #include <shell/rb-shell.h>
 #include <shell/rb-shell-player.h>
 #include <sources/rb-display-page-model.h>
@@ -66,7 +66,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
 	GDBusNodeInfo *node_info;
 	guint name_own_id;
@@ -85,14 +85,13 @@ typedef struct
 	GList *categories;
 
 	GSettings *settings;
-	RBShell *shell;
 	RhythmDB *db;
 	RBDisplayPageModel *display_page_model;
 } RBMediaServer2Plugin;
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBMediaServer2PluginClass;
 
 typedef struct
@@ -120,18 +119,15 @@ typedef struct
 	RBMediaServer2Plugin *plugin;
 } SourceRegistrationData;
 
+RB_DEFINE_PLUGIN(RB_TYPE_DBUS_MEDIA_SERVER_PLUGIN, RBMediaServer2Plugin, rb_dbus_media_server_plugin,)
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_dbus_media_server_plugin_get_type		(void) G_GNUC_CONST;
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void unregister_source_container (RBMediaServer2Plugin *plugin, SourceRegistrationData *source_data, gboolean deactivating);
 static void emit_source_property_updates (RBMediaServer2Plugin *plugin, SourceRegistrationData *source_data);
 static void emit_category_container_property_updates (RBMediaServer2Plugin *plugin, CategoryRegistrationData *category_data);
 static void emit_root_property_updates (RBMediaServer2Plugin *plugin);
 
-RB_PLUGIN_REGISTER(RBMediaServer2Plugin, rb_dbus_media_server_plugin)
-
-
 static void
 rb_dbus_media_server_plugin_init (RBMediaServer2Plugin *plugin)
 {
@@ -1411,22 +1407,22 @@ name_lost_cb (GDBusConnection *connection, const char *name, RBMediaServer2Plugi
 }
 
 static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBMediaServer2Plugin *plugin;
 	GDBusInterfaceInfo *container_iface;
 	RBSource *source;
 	GError *error = NULL;
+	RBShell *shell;
 
 	rb_debug ("activating DBus MediaServer2 plugin");
 
 	plugin = RB_DBUS_MEDIA_SERVER_PLUGIN (bplugin);
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell,
 		      "db", &plugin->db,
 		      "display-page-model", &plugin->display_page_model,
 		      NULL);
-	plugin->shell = g_object_ref (shell);
 
 	plugin->settings = g_settings_new ("org.gnome.rhythmbox.sharing");
 
@@ -1434,6 +1430,7 @@ impl_activate (RBPlugin *bplugin,
 	if (error != NULL) {
 		g_warning ("Unable to parse MediaServer2 spec: %s", error->message);
 		g_clear_error (&error);
+		g_object_unref (shell);
 		return;
 	}
 
@@ -1441,6 +1438,7 @@ impl_activate (RBPlugin *bplugin,
 	if (error != NULL) {
 		g_warning ("Unable to connect to D-Bus: %s", error->message);
 		g_clear_error (&error);
+		g_object_unref (shell);
 		return;
 	}
 
@@ -1474,6 +1472,7 @@ impl_activate (RBPlugin *bplugin,
 	if (error != NULL) {
 		g_warning ("Unable to register MediaServer2 entry subtree: %s", error->message);
 		g_clear_error (&error);
+		g_object_unref (shell);
 		return;
 	}
 
@@ -1485,11 +1484,11 @@ impl_activate (RBPlugin *bplugin,
 					      (GBusNameLostCallback) name_lost_cb,
 					      g_object_ref (plugin),
 					      g_object_unref);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBMediaServer2Plugin *plugin;
 	GList *l;
@@ -1534,10 +1533,6 @@ impl_deactivate	(RBPlugin *bplugin,
 		plugin->display_page_model = NULL;
 	}
 
-	if (plugin->shell != NULL) {
-		g_object_unref (plugin->shell);
-		plugin->shell = NULL;
-	}
 	if (plugin->db != NULL) {
 		g_object_unref (plugin->db);
 		plugin->db = NULL;
@@ -1555,11 +1550,11 @@ impl_deactivate	(RBPlugin *bplugin,
 }
 
 
-static void
-rb_dbus_media_server_plugin_class_init (RBMediaServer2PluginClass *klass)
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
+	rb_dbus_media_server_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_DBUS_MEDIA_SERVER_PLUGIN);
 }
diff --git a/plugins/fmradio/Makefile.am b/plugins/fmradio/Makefile.am
index 7db5832..2e7d637 100644
--- a/plugins/fmradio/Makefile.am
+++ b/plugins/fmradio/Makefile.am
@@ -1,5 +1,6 @@
 
 plugindir = $(PLUGINDIR)/fmradio
+plugindatadir = $(PLUGINDATADIR)/fmradio
 plugin_LTLIBRARIES = libfmradio.la
 
 libfmradio_la_SOURCES = \
@@ -34,16 +35,15 @@ INCLUDES = \
   $(WARN_CFLAGS) \
   -D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = fmradio.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = fmradio.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = fmradio-ui.xml
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(uixml_DATA) $(plugin_in_files)
 
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
-
diff --git a/plugins/fmradio/fmradio.rb-plugin.in b/plugins/fmradio/fmradio.plugin.in
similarity index 90%
rename from plugins/fmradio/fmradio.rb-plugin.in
rename to plugins/fmradio/fmradio.plugin.in
index 3238e4e..b0a70ab 100644
--- a/plugins/fmradio/fmradio.rb-plugin.in
+++ b/plugins/fmradio/fmradio.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=fmradio
-IAge=1
+IAge=2
 _Name=FM Radio
 _Description=Support for FM radio broadcasting services
 Authors=James Henstridge
diff --git a/plugins/fmradio/rb-fm-radio-plugin.c b/plugins/fmradio/rb-fm-radio-plugin.c
index 3f6b928..5407296 100644
--- a/plugins/fmradio/rb-fm-radio-plugin.c
+++ b/plugins/fmradio/rb-fm-radio-plugin.c
@@ -32,11 +32,12 @@
 #include <glib/gi18n-lib.h>
 
 #include "rb-debug.h"
-#include "rb-plugin.h"
 
+#include "rb-plugin-macros.h"
 #include "rb-fm-radio-source.h"
 #include "rb-radio-tuner.h"
 #include "rb-display-page-group.h"
+#include "rb-file-helpers.h"
 
 #define RB_TYPE_FM_RADIO_PLUGIN         (rb_fm_radio_plugin_get_type ())
 #define RB_FM_RADIO_PLUGIN(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_FM_RADIO_PLUGIN, RBFMRadioPlugin))
@@ -49,22 +50,19 @@ typedef struct _RBFMRadioPlugin RBFMRadioPlugin;
 typedef struct _RBFMRadioPluginClass RBFMRadioPluginClass;
 
 struct _RBFMRadioPlugin {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 	RBSource *source;
 	guint ui_merge_id;
 };
 
 struct _RBFMRadioPluginClass {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 };
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 GType rb_fm_radio_plugin_get_type (void) G_GNUC_CONST;
 
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
-
-RB_PLUGIN_REGISTER (RBFMRadioPlugin, rb_fm_radio_plugin);
+RB_DEFINE_PLUGIN (RB_TYPE_FM_RADIO_PLUGIN, RBFMRadioPlugin, rb_fm_radio_plugin,)
 
 static void
 rb_fm_radio_plugin_init (RBFMRadioPlugin *plugin)
@@ -73,19 +71,12 @@ rb_fm_radio_plugin_init (RBFMRadioPlugin *plugin)
 }
 
 static void
-rb_fm_radio_plugin_finalize (GObject *object)
-{
-	rb_debug ("RBIRadioPlugin finalising");
-
-	G_OBJECT_CLASS (rb_fm_radio_plugin_parent_class)->finalize (object);
-}
-
-static void
-impl_activate (RBPlugin *plugin, RBShell *shell)
+impl_activate (PeasActivatable *plugin)
 {
 	RBFMRadioPlugin *pi = RB_FM_RADIO_PLUGIN (plugin);
 	RBRadioTuner *tuner;
 	GtkUIManager *uimanager;
+	RBShell *shell;
 	char *filename;
 
 	tuner = rb_radio_tuner_new (NULL, NULL);
@@ -94,11 +85,14 @@ impl_activate (RBPlugin *plugin, RBShell *shell)
 
 	rb_radio_tuner_set_mute (tuner, TRUE);
 	rb_radio_tuner_update (tuner);
+
+	g_object_get (plugin, "object", &shell, NULL);
 	pi->source = rb_fm_radio_source_new (shell, tuner);
 	rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (pi->source), RB_DISPLAY_PAGE_GROUP_LIBRARY);	/* devices? */
+
 	g_object_unref (tuner);
 
-	filename = rb_plugin_find_file (plugin, "fmradio-ui.xml");
+	filename = rb_find_plugin_data_file (G_OBJECT (plugin), "fmradio-ui.xml");
 	if (filename != NULL) {
 		g_object_get (shell, "ui-manager", &uimanager, NULL);
 		pi->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager,
@@ -109,14 +103,16 @@ impl_activate (RBPlugin *plugin, RBShell *shell)
 	} else {
 		g_warning ("Unable to find file: fmradio-ui.xml");
 	}
-	
+
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate (RBPlugin *plugin, RBShell *shell)
+impl_deactivate (PeasActivatable *plugin)
 {
 	RBFMRadioPlugin *pi = RB_FM_RADIO_PLUGIN (plugin);
 	GtkUIManager *uimanager;
+	RBShell *shell;
 
 	if (pi->source) {
 		rb_display_page_delete_thyself (RB_DISPLAY_PAGE (pi->source));
@@ -124,24 +120,24 @@ impl_deactivate (RBPlugin *plugin, RBShell *shell)
 	}
 
 	if (pi->ui_merge_id) {
+		g_object_get (plugin, "object", &shell, NULL);
 		g_object_get (shell, "ui-manager", &uimanager, NULL);
+		g_object_unref (shell);
+
 		gtk_ui_manager_remove_ui (uimanager, pi->ui_merge_id);
 		g_object_unref (uimanager);
 		pi->ui_merge_id = 0;
 	}
 }
 
-static void
-rb_fm_radio_plugin_class_init (RBFMRadioPluginClass *klass)
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-        GObjectClass *object_class = G_OBJECT_CLASS (klass);
-        RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-        object_class->finalize = rb_fm_radio_plugin_finalize;
-
-        plugin_class->activate = impl_activate;
-        plugin_class->deactivate = impl_deactivate;
+	rb_fm_radio_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_fm_radio_source_register_type (G_TYPE_MODULE (module));
+	_rb_radio_tuner_register_type (G_TYPE_MODULE (module));
 
-	RB_PLUGIN_REGISTER_TYPE (rb_radio_tuner);
-	RB_PLUGIN_REGISTER_TYPE (rb_fm_radio_source);
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_FM_RADIO_PLUGIN);
 }
diff --git a/plugins/fmradio/rb-fm-radio-source.c b/plugins/fmradio/rb-fm-radio-source.c
index 61f9de5..ce0f82e 100644
--- a/plugins/fmradio/rb-fm-radio-source.c
+++ b/plugins/fmradio/rb-fm-radio-source.c
@@ -93,9 +93,9 @@ static GtkActionEntry rb_fm_radio_source_actions[] = {
 	  G_CALLBACK (rb_fm_radio_source_cmd_new_station) },
 };
 
-RB_PLUGIN_DEFINE_TYPE (RBFMRadioSource, rb_fm_radio_source, RB_TYPE_SOURCE);
+G_DEFINE_DYNAMIC_TYPE (RBFMRadioSource, rb_fm_radio_source, RB_TYPE_SOURCE);
 
-G_DEFINE_TYPE (RBFMRadioEntryType, rb_fm_radio_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
+G_DEFINE_DYNAMIC_TYPE (RBFMRadioEntryType, rb_fm_radio_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
 
 static char *
 rb_fm_radio_source_get_playback_uri (RhythmDBEntryType *etype, RhythmDBEntry *entry)
@@ -113,6 +113,11 @@ rb_fm_radio_entry_type_class_init (RBFMRadioEntryTypeClass *klass)
 }
 
 static void
+rb_fm_radio_entry_type_class_finalize (RBFMRadioEntryTypeClass *klass)
+{
+}
+
+static void
 rb_fm_radio_entry_type_init (RBFMRadioEntryType *etype)
 {
 }
@@ -140,6 +145,11 @@ rb_fm_radio_source_class_init (RBFMRadioSourceClass *class)
 }
 
 static void
+rb_fm_radio_source_class_finalize (RBFMRadioSourceClass *class)
+{
+}
+
+static void
 rb_fm_radio_source_init (RBFMRadioSource *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (
@@ -448,3 +458,10 @@ impl_get_entry_view (RBSource *source)
 
 	return self->priv->stations;
 }
+
+void
+_rb_fm_radio_source_register_type (GTypeModule *module)
+{
+	rb_fm_radio_source_register_type (module);
+	rb_fm_radio_entry_type_register_type (module);
+}
diff --git a/plugins/fmradio/rb-fm-radio-source.h b/plugins/fmradio/rb-fm-radio-source.h
index ef5a303..0304607 100644
--- a/plugins/fmradio/rb-fm-radio-source.h
+++ b/plugins/fmradio/rb-fm-radio-source.h
@@ -29,7 +29,6 @@
 #define RB_FM_RADIO_SOURCE_H
 
 #include "rb-shell.h"
-#include "rb-plugin.h"
 #include "rb-source.h"
 #include "rb-radio-tuner.h"
 
@@ -57,7 +56,6 @@ struct _RBFMRadioSourceClass {
 };
 
 GType     rb_fm_radio_source_get_type	       (void);
-GType     rb_fm_radio_source_register_type     (GTypeModule *plugin);
 
 RBSource *rb_fm_radio_source_new               (RBShell *shell,
 						RBRadioTuner *tuner);
@@ -66,6 +64,7 @@ void	  rb_fm_radio_source_add_station       (RBFMRadioSource *source,
 						const char *frequency,
 						const char *title);
 
+void      _rb_fm_radio_source_register_type    (GTypeModule *module);
 G_END_DECLS
 
 #endif /* RB_FM_RADIO_SOURCE_H */
diff --git a/plugins/fmradio/rb-radio-tuner-v4l2.c b/plugins/fmradio/rb-radio-tuner-v4l2.c
index 21007fb..9864b81 100644
--- a/plugins/fmradio/rb-radio-tuner-v4l2.c
+++ b/plugins/fmradio/rb-radio-tuner-v4l2.c
@@ -40,7 +40,6 @@
 #include <glib.h>
 
 #include "rb-debug.h"
-#include "rb-plugin.h"
 #include "rb-radio-tuner.h"
 
 struct _RBRadioTunerPrivate {
@@ -51,7 +50,7 @@ struct _RBRadioTunerPrivate {
 	guint32 freq_mul;
 };
 
-RB_PLUGIN_DEFINE_TYPE (RBRadioTuner, rb_radio_tuner, G_TYPE_OBJECT);
+G_DEFINE_DYNAMIC_TYPE (RBRadioTuner, rb_radio_tuner, G_TYPE_OBJECT);
 
 static void rb_radio_tuner_finalize (GObject *object);
 
@@ -66,6 +65,11 @@ rb_radio_tuner_class_init (RBRadioTunerClass *class)
 }
 
 static void
+rb_radio_tuner_class_finalize (RBRadioTunerClass *class)
+{
+}
+
+static void
 rb_radio_tuner_init (RBRadioTuner *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, RB_TYPE_RADIO_TUNER,
@@ -227,3 +231,9 @@ rb_radio_tuner_set_mute (RBRadioTuner *self, gboolean mute)
 	control.value = !!mute;
 	return ioctl (self->priv->fd, VIDIOC_S_CTRL, &control) >= 0;
 }
+
+void
+_rb_radio_tuner_register_type (GTypeModule *module)
+{
+	rb_radio_tuner_register_type (module);
+}
diff --git a/plugins/fmradio/rb-radio-tuner.h b/plugins/fmradio/rb-radio-tuner.h
index 5a60029..11754f0 100644
--- a/plugins/fmradio/rb-radio-tuner.h
+++ b/plugins/fmradio/rb-radio-tuner.h
@@ -67,7 +67,6 @@ struct _RBRadioTunerClass {
 };
 
 GType         rb_radio_tuner_get_type      (void);
-GType         rb_radio_tuner_register_type (GTypeModule *module);
 
 RBRadioTuner *rb_radio_tuner_new           (const gchar *devname,
 					    GError **err);
@@ -77,6 +76,7 @@ gboolean      rb_radio_tuner_set_frequency (RBRadioTuner *self,
 gboolean      rb_radio_tuner_set_mute      (RBRadioTuner *self,
 					    gboolean mute);
 
+void          _rb_radio_tuner_register_type (GTypeModule *module);
 G_END_DECLS
 
 #endif /* RB_RADIO_TUNER_H */
diff --git a/plugins/generic-player/Makefile.am b/plugins/generic-player/Makefile.am
index 1098e24..6426902 100644
--- a/plugins/generic-player/Makefile.am
+++ b/plugins/generic-player/Makefile.am
@@ -1,4 +1,5 @@
 plugindir = $(PLUGINDIR)/generic-player
+plugindatadir = $(PLUGINDATADIR)/generic-player
 plugin_LTLIBRARIES = libgeneric-player.la
 
 libgeneric_player_la_SOURCES =				\
@@ -25,15 +26,11 @@ INCLUDES = 						\
 	-I$(top_srcdir)/lib                        	\
 	-I$(top_srcdir)/lib/libmediaplayerid            \
 	-I$(top_srcdir)/metadata                       	\
-	-I$(top_srcdir)/player                       	\
 	-I$(top_srcdir)/rhythmdb                       	\
 	-I$(top_srcdir)/widgets                    	\
 	-I$(top_srcdir)/sources                    	\
 	-I$(top_srcdir)/sources/sync                   	\
-	-I$(top_srcdir)/iradio                    	\
 	-I$(top_srcdir)/podcast                    	\
-	-I$(top_srcdir)/remote				\
-	-I$(top_builddir)/remote			\
 	-I$(top_srcdir)/plugins				\
 	-I$(top_srcdir)/shell				\
 	-DPIXMAP_DIR=\""$(datadir)/pixmaps"\"		\
@@ -43,17 +40,17 @@ INCLUDES = 						\
 	$(RHYTHMBOX_CFLAGS)				\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = generic-player-ui.xml
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA = generic-player-info.ui
 
-plugin_in_files = generic-player.rb-plugin.in
+plugin_in_files = generic-player.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(uixml_DATA) $(gtkbuilder_DATA) $(plugin_in_files)
 
diff --git a/plugins/generic-player/generic-player.rb-plugin.in b/plugins/generic-player/generic-player.plugin.in
similarity index 90%
rename from plugins/generic-player/generic-player.rb-plugin.in
rename to plugins/generic-player/generic-player.plugin.in
index 66ca929..2523045 100644
--- a/plugins/generic-player/generic-player.rb-plugin.in
+++ b/plugins/generic-player/generic-player.plugin.in
@@ -1,6 +1,7 @@
-[RB Plugin]
+[Plugin]
 Module=generic-player
-IAge=1
+IAge=2
+Builtin=true
 _Name=Portable Players
 _Description=Support for generic audio player devices (plus PSP and Nokia 770)
 Authors=James Livingston, Jonathan Matthew
diff --git a/plugins/generic-player/rb-generic-player-playlist-source.c b/plugins/generic-player/rb-generic-player-playlist-source.c
index 92a330e..9ad6cdb 100644
--- a/plugins/generic-player/rb-generic-player-playlist-source.c
+++ b/plugins/generic-player/rb-generic-player-playlist-source.c
@@ -35,7 +35,6 @@
 #include "rb-generic-player-playlist-source.h"
 #include "rb-generic-player-source.h"
 #include "rb-debug.h"
-#include "rb-plugin.h"
 #include "rb-file-helpers.h"
 #include "rb-util.h"
 
@@ -50,7 +49,7 @@ typedef struct
 	gboolean loading;
 } RBGenericPlayerPlaylistSourcePrivate;
 
-RB_PLUGIN_DEFINE_TYPE(RBGenericPlayerPlaylistSource,
+G_DEFINE_DYNAMIC_TYPE(RBGenericPlayerPlaylistSource,
 		      rb_generic_player_playlist_source,
 		      RB_TYPE_STATIC_PLAYLIST_SOURCE)
 
@@ -78,8 +77,6 @@ impl_save_to_xml (RBPlaylistSource *source, xmlNodePtr node)
 	/* do nothing; just to prevent weirdness */
 }
 
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,29,1)
-
 static void
 set_field_from_property (TotemPlPlaylist *playlist,
 			 TotemPlPlaylistIter *iter,
@@ -127,33 +124,6 @@ save_playlist_foreach (GtkTreeModel *model,
 	return FALSE;
 }
 
-#else
-
-static void
-save_playlist_entry (GtkTreeModel *model, GtkTreeIter *iter,
-		     char **uri, char **title,
-		     gboolean *custom_title,
-		     SavePlaylistData *data)
-{
-	RBGenericPlayerPlaylistSourcePrivate *priv = GET_PRIVATE (data->source);
-	RhythmDBEntry *entry;
-	const char *host_uri;
-
-	entry = rhythmdb_query_model_iter_to_entry (RHYTHMDB_QUERY_MODEL (model),
-						    iter);
-	if (entry == NULL) {
-		return;
-	}
-
-	host_uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
-	*uri = rb_generic_player_source_uri_to_playlist_uri (priv->player_source, host_uri, data->playlist_type);
-	*title = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_TITLE);
-	*custom_title = TRUE;
-	rhythmdb_entry_unref (entry);
-}
-
-#endif
-
 /* this probably belongs more in totem than here */
 static const char *
 playlist_format_extension (TotemPlParserType playlist_type)
@@ -244,7 +214,6 @@ save_playlist (RBGenericPlayerPlaylistSource *source)
 	parser = totem_pl_parser_new ();
 	data.source = source;
 	data.playlist_type = playlist_type;
-#if TOTEM_PL_PARSER_CHECK_VERSION(2,29,1)
 	data.playlist = totem_pl_playlist_new ();
 
 	gtk_tree_model_foreach (GTK_TREE_MODEL (query_model),
@@ -257,20 +226,7 @@ save_playlist (RBGenericPlayerPlaylistSource *source)
 	result = totem_pl_parser_save (parser, data.playlist, file, name, playlist_type, &error);
 	g_object_unref (data.playlist);
 	data.playlist = NULL;
-#else
-	if (rb_debug_matches ("totem_pl_parser_write_with_title", "totem-pl-parser.c")) {
-		g_object_set (parser, "debug", TRUE, NULL);
-	}
 
-	result = totem_pl_parser_write_with_title (parser,
-						   GTK_TREE_MODEL (query_model),
-						   (TotemPlParserIterFunc) save_playlist_entry,
-						   temp_path,
-						   name,
-						   playlist_type,
-						   &data,
-						   &error);
-#endif
 	if (result == FALSE) {
 		/* XXX report this more usefully */
 		g_warning ("Playlist save failed: %s", error ? error->message : "<no error>");
@@ -601,3 +557,13 @@ rb_generic_player_playlist_source_class_init (RBGenericPlayerPlaylistSourceClass
 	g_type_class_add_private (klass, sizeof (RBGenericPlayerPlaylistSourcePrivate));
 }
 
+static void
+rb_generic_player_playlist_source_class_finalize (RBGenericPlayerPlaylistSourceClass *klass)
+{
+}
+
+void
+_rb_generic_player_playlist_source_register_type (GTypeModule *module)
+{
+	rb_generic_player_playlist_source_register_type (module);
+}
diff --git a/plugins/generic-player/rb-generic-player-playlist-source.h b/plugins/generic-player/rb-generic-player-playlist-source.h
index e65d6d2..57b3c54 100644
--- a/plugins/generic-player/rb-generic-player-playlist-source.h
+++ b/plugins/generic-player/rb-generic-player-playlist-source.h
@@ -51,7 +51,6 @@ typedef struct
 } RBGenericPlayerPlaylistSourceClass;
 
 GType		rb_generic_player_playlist_source_get_type	(void);
-GType		rb_generic_player_playlist_source_register_type	(GTypeModule *module);
 
 RBSource *	rb_generic_player_playlist_source_new (RBShell *shell,
 						       RBGenericPlayerSource *source,
@@ -60,6 +59,8 @@ RBSource *	rb_generic_player_playlist_source_new (RBShell *shell,
 						       RhythmDBEntryType *entry_type);
 void		rb_generic_player_playlist_delete_from_player (RBGenericPlayerPlaylistSource *source);
 
+void		_rb_generic_player_playlist_source_register_type (GTypeModule *module);
+
 G_END_DECLS
 
 #endif	/* __RB_GENERIC_PLAYER_PLAYLIST_SOURCE_H */
diff --git a/plugins/generic-player/rb-generic-player-plugin.c b/plugins/generic-player/rb-generic-player-plugin.c
index 3462375..3d06831 100644
--- a/plugins/generic-player/rb-generic-player-plugin.c
+++ b/plugins/generic-player/rb-generic-player-plugin.c
@@ -39,7 +39,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-dialog.h"
@@ -62,9 +62,8 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
-	RBShell *shell;
 	guint ui_merge_id;
 
 	GList *player_sources;
@@ -73,23 +72,19 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBGenericPlayerPluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_generic_player_plugin_get_type		(void) G_GNUC_CONST;
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule  *module);
 
 static void rb_generic_player_plugin_init (RBGenericPlayerPlugin *plugin);
-static void rb_generic_player_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
 static void rb_generic_player_plugin_new_playlist (GtkAction *action, RBSource *source);
 static void rb_generic_player_plugin_delete_playlist (GtkAction *action, RBSource *source);
 static void rb_generic_player_plugin_properties (GtkAction *action, RBSource *source);
 
-RB_PLUGIN_REGISTER(RBGenericPlayerPlugin, rb_generic_player_plugin)
+RB_DEFINE_PLUGIN(RB_TYPE_GENERIC_PLAYER_PLUGIN, RBGenericPlayerPlugin, rb_generic_player_plugin,)
 
 static GtkActionEntry rb_generic_player_plugin_actions[] = {
 	{ "GenericPlayerSourceNewPlaylist", RB_STOCK_PLAYLIST_NEW, N_("New Playlist"), NULL,
@@ -104,40 +99,12 @@ static GtkActionEntry rb_generic_player_plugin_actions[] = {
 };
 
 static void
-rb_generic_player_plugin_class_init (RBGenericPlayerPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_generic_player_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-
-	RB_PLUGIN_REGISTER_TYPE(rb_generic_player_source);
-	RB_PLUGIN_REGISTER_TYPE(rb_generic_player_playlist_source);
-	RB_PLUGIN_REGISTER_TYPE(rb_psp_source);
-	RB_PLUGIN_REGISTER_TYPE(rb_nokia770_source);
-}
-
-static void
 rb_generic_player_plugin_init (RBGenericPlayerPlugin *plugin)
 {
 	rb_debug ("RBGenericPlayerPlugin initialising");
 }
 
 static void
-rb_generic_player_plugin_finalize (GObject *object)
-{
-/*
-	RBGenericPlayerPlugin *plugin = RB_GENERIC_PLAYER_PLUGIN (object);
-*/
-	rb_debug ("RBGenericPlayerPlugin finalising");
-
-	G_OBJECT_CLASS (rb_generic_player_plugin_parent_class)->finalize (object);
-}
-
-static void
 rb_generic_player_plugin_source_deleted (RBGenericPlayerSource *source, RBGenericPlayerPlugin *plugin)
 {
 	plugin->player_sources = g_list_remove (plugin->player_sources, source);
@@ -184,20 +151,23 @@ static RBSource *
 create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *device_info, RBGenericPlayerPlugin *plugin)
 {
 	RBSource *source = NULL;
+	RBShell *shell;
+
+	g_object_get (plugin, "object", &shell, NULL);
 
 	if (rb_psp_is_mount_player (mount, device_info))
-		source = RB_SOURCE (rb_psp_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info));
+		source = RB_SOURCE (rb_psp_source_new (G_OBJECT (plugin), shell, mount, device_info));
 	if (source == NULL && rb_nokia770_is_mount_player (mount, device_info))
-		source = RB_SOURCE (rb_nokia770_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info));
+		source = RB_SOURCE (rb_nokia770_source_new (G_OBJECT (plugin), shell, mount, device_info));
 	if (source == NULL && rb_generic_player_is_mount_player (mount, device_info))
-		source = RB_SOURCE (rb_generic_player_source_new (RB_PLUGIN (plugin), plugin->shell, mount, device_info));
+		source = RB_SOURCE (rb_generic_player_source_new (G_OBJECT (plugin), shell, mount, device_info));
 
 	if (plugin->actions == NULL) {
 		plugin->actions = gtk_action_group_new ("GenericPlayerActions");
 		gtk_action_group_set_translation_domain (plugin->actions, GETTEXT_PACKAGE);
 
 		_rb_action_group_add_display_page_actions (plugin->actions,
-							   G_OBJECT (plugin->shell),
+							   G_OBJECT (shell),
 							   rb_generic_player_plugin_actions,
 							   G_N_ELEMENTS (rb_generic_player_plugin_actions));
 	}
@@ -207,16 +177,16 @@ create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *devic
 			GtkUIManager *uimanager = NULL;
 			char *file = NULL;
 
-			g_object_get (G_OBJECT (plugin->shell), "ui-manager", &uimanager, NULL);
+			g_object_get (shell, "ui-manager", &uimanager, NULL);
 
 			gtk_ui_manager_insert_action_group (uimanager, plugin->actions, 0);
 
-			file = rb_plugin_find_file (RB_PLUGIN (plugin), "generic-player-ui.xml");
+			file = rb_find_plugin_data_file (G_OBJECT (plugin), "generic-player-ui.xml");
 			plugin->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager,
 									       file,
 									       NULL);
 			g_free (file);
-			g_object_unref (G_OBJECT (uimanager));
+			g_object_unref (uimanager);
 		}
 
 		plugin->player_sources = g_list_prepend (plugin->player_sources, source);
@@ -225,23 +195,22 @@ create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *devic
 					 plugin, 0);
 	}
 
+	g_object_unref (shell);
 	return source;
 }
 
 
 
 static void
-impl_activate (RBPlugin *plugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *plugin)
 {
 	RBGenericPlayerPlugin *pi = RB_GENERIC_PLAYER_PLUGIN (plugin);
 	RBRemovableMediaManager *rmm;
+	RBShell *shell;
 	gboolean scanned;
 
-	pi->shell = shell;
-	g_object_get (G_OBJECT (shell),
-		      "removable-media-manager", &rmm,
-		      NULL);
+	g_object_get (plugin, "object", &shell, NULL);
+	g_object_get (shell, "removable-media-manager", &rmm, NULL);
 
 	/* watch for new removable media.  use connect_after so
 	 * plugins for more specific device types can get in first.
@@ -251,22 +220,24 @@ impl_activate (RBPlugin *plugin,
 				pi);
 
 	/* only scan if we're being loaded after the initial scan has been done */
-	g_object_get (G_OBJECT (rmm), "scanned", &scanned, NULL);
+	g_object_get (rmm, "scanned", &scanned, NULL);
 	if (scanned)
 		rb_removable_media_manager_scan (rmm);
 
-	g_object_unref (G_OBJECT (rmm));
+	g_object_unref (rmm);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBGenericPlayerPlugin *plugin = RB_GENERIC_PLAYER_PLUGIN (bplugin);
-	RBRemovableMediaManager *rmm = NULL;
-	GtkUIManager *uimanager = NULL;
+	RBRemovableMediaManager *rmm;
+	GtkUIManager *uimanager;
+	RBShell *shell;
 
-	g_object_get (G_OBJECT (shell),
+	g_object_get (plugin, "object", &shell, NULL);
+	g_object_get (shell,
 		      "removable-media-manager", &rmm,
 		      "ui-manager", &uimanager,
 		      NULL);
@@ -282,8 +253,9 @@ impl_deactivate	(RBPlugin *bplugin,
 		plugin->ui_merge_id = 0;
 	}
 
-	g_object_unref (G_OBJECT (uimanager));
-	g_object_unref (G_OBJECT (rmm));
+	g_object_unref (uimanager);
+	g_object_unref (rmm);
+	g_object_unref (shell);
 }
 
 static void
@@ -292,3 +264,17 @@ rb_generic_player_plugin_properties (GtkAction *action, RBSource *source)
 	g_return_if_fail (RB_IS_GENERIC_PLAYER_SOURCE (source));
 	rb_media_player_source_show_properties (RB_MEDIA_PLAYER_SOURCE (source));
 }
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_generic_player_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_generic_player_source_register_type (G_TYPE_MODULE (module));
+	_rb_generic_player_playlist_source_register_type (G_TYPE_MODULE (module));
+	_rb_nokia770_source_register_type (G_TYPE_MODULE (module));
+	_rb_psp_source_register_type (G_TYPE_MODULE (module));
+
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_GENERIC_PLAYER_PLUGIN);
+}
diff --git a/plugins/generic-player/rb-generic-player-source.c b/plugins/generic-player/rb-generic-player-source.c
index cea01a6..359bdca 100644
--- a/plugins/generic-player/rb-generic-player-source.c
+++ b/plugins/generic-player/rb-generic-player-source.c
@@ -47,7 +47,6 @@
 #include "rb-file-helpers.h"
 #include "rhythmdb.h"
 #include "rb-dialog.h"
-#include "rb-plugin.h"
 #include "rhythmdb-import-job.h"
 #include "rb-import-errors-source.h"
 #include "rb-builder-helpers.h"
@@ -130,7 +129,7 @@ typedef struct
 
 } RBGenericPlayerSourcePrivate;
 
-RB_PLUGIN_DEFINE_TYPE(RBGenericPlayerSource, rb_generic_player_source, RB_TYPE_MEDIA_PLAYER_SOURCE)
+G_DEFINE_DYNAMIC_TYPE (RBGenericPlayerSource, rb_generic_player_source, RB_TYPE_MEDIA_PLAYER_SOURCE)
 #define GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_GENERIC_PLAYER_SOURCE, RBGenericPlayerSourcePrivate))
 
 static void
@@ -201,6 +200,11 @@ rb_generic_player_source_class_init (RBGenericPlayerSourceClass *klass)
 }
 
 static void
+rb_generic_player_source_class_finalize (RBGenericPlayerSourceClass *klass)
+{
+}
+
+static void
 rb_generic_player_source_init (RBGenericPlayerSource *source)
 {
 
@@ -352,7 +356,7 @@ impl_dispose (GObject *object)
 }
 
 RBRemovableMediaSource *
-rb_generic_player_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
+rb_generic_player_source_new (GObject *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 {
 	RBGenericPlayerSource *source;
 	RhythmDBEntryType *entry_type;
@@ -1251,13 +1255,13 @@ impl_show_properties (RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidge
 	char *vendor_name;
 	char *model_name;
 	char *serial_id;
-	RBPlugin *plugin;
+	GObject *plugin;
 	char *text;
 	GList *output_formats;
 	GList *t;
 
 	g_object_get (source, "plugin", &plugin, NULL);
-	builder_file = rb_plugin_find_file (plugin, "generic-player-info.ui");
+	builder_file = rb_find_plugin_data_file (plugin, "generic-player-info.ui");
 	g_object_unref (plugin);
 
 	if (builder_file == NULL) {
@@ -1385,3 +1389,9 @@ impl_remove_playlists (RBMediaPlayerSource *source)
 
 	g_list_free (playlists);
 }
+
+void
+_rb_generic_player_source_register_type (GTypeModule *module)
+{
+	rb_generic_player_source_register_type (module);
+}
diff --git a/plugins/generic-player/rb-generic-player-source.h b/plugins/generic-player/rb-generic-player-source.h
index a93c018..d1d04b2 100644
--- a/plugins/generic-player/rb-generic-player-source.h
+++ b/plugins/generic-player/rb-generic-player-source.h
@@ -29,7 +29,6 @@
 #define __RB_GENERIC_PLAYER_SOURCE_H
 
 #include "rb-shell.h"
-#include "rb-plugin.h"
 #include "rb-media-player-source.h"
 #include "rhythmdb.h"
 
@@ -66,12 +65,11 @@ typedef struct
 	char *		(*impl_build_filename) (RBGenericPlayerSource *source, RhythmDBEntry *entry);
 } RBGenericPlayerSourceClass;
 
-RBRemovableMediaSource *rb_generic_player_source_new			(RBPlugin *plugin,
+RBRemovableMediaSource *rb_generic_player_source_new			(GObject *plugin,
 									 RBShell *shell,
 									 GMount *mount,
 									 MPIDDevice *device_info);
 GType			rb_generic_player_source_get_type		(void);
-GType			rb_generic_player_source_register_type		(GTypeModule *module);
 
 char *			rb_generic_player_source_get_mount_path		(RBGenericPlayerSource *source);
 char *			rb_generic_player_source_uri_from_playlist_uri  (RBGenericPlayerSource *source,
@@ -94,6 +92,8 @@ void			rb_generic_player_source_add_playlist		(RBGenericPlayerSource *source,
 									 RBShell *shell,
 									 RBSource *playlist);
 
+void			_rb_generic_player_source_register_type		(GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* __RB_GENERIC_PLAYER_SOURCE_H */
diff --git a/plugins/generic-player/rb-nokia770-source.c b/plugins/generic-player/rb-nokia770-source.c
index 8725b65..b23028a 100644
--- a/plugins/generic-player/rb-nokia770-source.c
+++ b/plugins/generic-player/rb-nokia770-source.c
@@ -42,21 +42,11 @@
 #include "rb-util.h"
 #include "rb-file-helpers.h"
 #include "rhythmdb.h"
-#include "rb-plugin.h"
 
 
 static char * impl_uri_from_playlist_uri (RBGenericPlayerSource *source, const char *uri);
 
-
-typedef struct {
-#ifdef __SUNPRO_C
-   int x;  /* To build with Solaris forte compiler */
-#endif
-} RBNokia770SourcePrivate;
-
-RB_PLUGIN_DEFINE_TYPE (RBNokia770Source, rb_nokia770_source, RB_TYPE_GENERIC_PLAYER_SOURCE)
-#define NOKIA770_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_NOKIA770_SOURCE, RBNokia770SourcePrivate))
-
+G_DEFINE_DYNAMIC_TYPE (RBNokia770Source, rb_nokia770_source, RB_TYPE_GENERIC_PLAYER_SOURCE)
 
 #define NOKIA_INTERNAL_MOUNTPOINT "file:///media/mmc1/"
 
@@ -66,8 +56,11 @@ rb_nokia770_source_class_init (RBNokia770SourceClass *klass)
 	RBGenericPlayerSourceClass *generic_class = RB_GENERIC_PLAYER_SOURCE_CLASS (klass);
 
 	generic_class->impl_uri_from_playlist_uri = impl_uri_from_playlist_uri;
+}
 
-	g_type_class_add_private (klass, sizeof (RBNokia770SourcePrivate));
+static void
+rb_nokia770_source_class_finalize (RBNokia770SourceClass *klass)
+{
 }
 
 static void
@@ -77,7 +70,7 @@ rb_nokia770_source_init (RBNokia770Source *source)
 }
 
 RBRemovableMediaSource *
-rb_nokia770_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
+rb_nokia770_source_new (GObject *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 {
 	RBNokia770Source *source;
 	RhythmDBEntryType *entry_type;
@@ -158,3 +151,8 @@ rb_nokia770_is_mount_player (GMount *mount, MPIDDevice *device_info)
 	return result;
 }
 
+void
+_rb_nokia770_source_register_type (GTypeModule *module)
+{
+	rb_nokia770_source_register_type (module);
+}
diff --git a/plugins/generic-player/rb-nokia770-source.h b/plugins/generic-player/rb-nokia770-source.h
index 4738a5a..a259294 100644
--- a/plugins/generic-player/rb-nokia770-source.h
+++ b/plugins/generic-player/rb-nokia770-source.h
@@ -30,7 +30,6 @@
 
 #include "mediaplayerid.h"
 
-#include "rb-plugin.h"
 #include "rb-shell.h"
 #include "rb-generic-player-source.h"
 #include "rhythmdb.h"
@@ -54,15 +53,16 @@ typedef struct
 	RBGenericPlayerSourceClass parent;
 } RBNokia770SourceClass;
 
-RBRemovableMediaSource *	rb_nokia770_source_new		(RBPlugin *plugin,
+RBRemovableMediaSource *	rb_nokia770_source_new		(GObject *plugin,
 								 RBShell *shell,
 								 GMount *mount,
 								 MPIDDevice *device_info);
 GType				rb_nokia770_source_get_type	(void);
-GType				rb_nokia770_source_register_type (GTypeModule *module);
 
 gboolean			rb_nokia770_is_mount_player	(GMount *mount, MPIDDevice *device_info);
 
+void				_rb_nokia770_source_register_type (GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* __RB_NOKIA770_SOURCE_H */
diff --git a/plugins/generic-player/rb-psp-source.c b/plugins/generic-player/rb-psp-source.c
index 036b013..39005d3 100644
--- a/plugins/generic-player/rb-psp-source.c
+++ b/plugins/generic-player/rb-psp-source.c
@@ -43,39 +43,32 @@
 #include "rb-file-helpers.h"
 #include "rb-auto-playlist-source.h"
 #include "rhythmdb.h"
-#include "rb-plugin.h"
 
 
 static void rb_psp_source_create_playlists (RBGenericPlayerSource *source);
 
-typedef struct
-{
-  char garbage_so_its_not_empty; /* To avoid run-time warnings. FIXME remove if no private needed */
-} RBPspSourcePrivate;
-
-
-RB_PLUGIN_DEFINE_TYPE (RBPspSource, rb_psp_source, RB_TYPE_GENERIC_PLAYER_SOURCE)
-#define PSP_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_PSP_SOURCE, RBPspSourcePrivate))
+G_DEFINE_DYNAMIC_TYPE (RBPspSource, rb_psp_source, RB_TYPE_GENERIC_PLAYER_SOURCE)
 
 
 static void
 rb_psp_source_class_init (RBPspSourceClass *klass)
 {
 	RBGenericPlayerSourceClass *generic_class = RB_GENERIC_PLAYER_SOURCE_CLASS (klass);
-
 	generic_class->impl_load_playlists = rb_psp_source_create_playlists;
+}
 
-	g_type_class_add_private (klass, sizeof (RBPspSourcePrivate));
+static void
+rb_psp_source_class_finalize (RBPspSourceClass *klass)
+{
 }
 
 static void
 rb_psp_source_init (RBPspSource *source)
 {
-
 }
 
 RBRemovableMediaSource *
-rb_psp_source_new (RBPlugin *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
+rb_psp_source_new (GObject *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 {
 	RBPspSource *source;
 	RhythmDBEntryType *entry_type;
@@ -288,3 +281,8 @@ rb_psp_is_mount_player (GMount *mount, MPIDDevice *device_info)
 	return result;
 }
 
+void
+_rb_psp_source_register_type (GTypeModule *module)
+{
+	rb_psp_source_register_type (module);
+}
diff --git a/plugins/generic-player/rb-psp-source.h b/plugins/generic-player/rb-psp-source.h
index 50940b0..7b9cab2 100644
--- a/plugins/generic-player/rb-psp-source.h
+++ b/plugins/generic-player/rb-psp-source.h
@@ -31,7 +31,6 @@
 #include "mediaplayerid.h"
 
 #include "rb-shell.h"
-#include "rb-plugin.h"
 #include "rb-generic-player-source.h"
 #include "rhythmdb.h"
 
@@ -54,15 +53,16 @@ typedef struct
 	RBGenericPlayerSourceClass parent;
 } RBPspSourceClass;
 
-RBRemovableMediaSource *rb_psp_source_new		(RBPlugin *plugin,
+RBRemovableMediaSource *rb_psp_source_new		(GObject *plugin,
 							 RBShell *shell,
 							 GMount *mount,
 							 MPIDDevice *device_info);
 GType			rb_psp_source_get_type		(void);
-GType			rb_psp_source_register_type	(GTypeModule *module);
 
 gboolean		rb_psp_is_mount_player		(GMount *mount, MPIDDevice *device_info);
 
+void			_rb_psp_source_register_type	(GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* __RB_PSP_SOURCE_H */
diff --git a/plugins/im-status/Makefile.am b/plugins/im-status/Makefile.am
index 3c193bc..7285519 100644
--- a/plugins/im-status/Makefile.am
+++ b/plugins/im-status/Makefile.am
@@ -1,12 +1,12 @@
 # IM Status Python Plugin
 
-plugin_in_files = im-status.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = im-status.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 plugindir = $(PLUGINDIR)/im-status
-plugin_PYTHON = im-status/__init__.py
+plugin_PYTHON = im-status.py
 
 EXTRA_DIST = $(plugin_in_files) $(plugin_PYTHON)
 
diff --git a/plugins/im-status/im-status.rb-plugin.in b/plugins/im-status/im-status.plugin.in
similarity index 93%
rename from plugins/im-status/im-status.rb-plugin.in
rename to plugins/im-status/im-status.plugin.in
index 28faca4..5857c6a 100644
--- a/plugins/im-status/im-status.rb-plugin.in
+++ b/plugins/im-status/im-status.plugin.in
@@ -1,7 +1,7 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=im-status
-IAge=1
+IAge=2
 _Name=IM Status
 _Description=Updates IM status according to the current song (works with Empathy, Gossip, and Pidgin)
 Authors=Vincent Untz <vuntz gnome org>
diff --git a/plugins/im-status/im-status/__init__.py b/plugins/im-status/im-status.py
similarity index 95%
rename from plugins/im-status/im-status/__init__.py
rename to plugins/im-status/im-status.py
index 861ef89..b38e751 100644
--- a/plugins/im-status/im-status/__init__.py
+++ b/plugins/im-status/im-status.py
@@ -26,6 +26,7 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
 import rb
+from gi.repository import GObject, Peas
 from gi.repository import RB
 
 try:
@@ -59,13 +60,16 @@ PURPLE_BUS_NAME = 'im.pidgin.purple.PurpleService'
 PURPLE_OBJ_PATH = '/im/pidgin/purple/PurpleObject'
 PURPLE_IFACE_NAME = 'im.pidgin.purple.PurpleInterface'
 
-class IMStatusPlugin (RB.Plugin):
+class IMStatusPlugin (GObject.Object, Peas.Activatable):
+  __gtype_name__ = 'IMStatusPlugin'
+  object = GObject.property(type=GObject.Object)
+
   def __init__ (self):
-    RB.Plugin.__init__ (self)
+    GObject.Object.__init__ (self)
 
-  def activate (self, shell):
-    self.shell = shell
-    sp = shell.get_player ()
+  def do_activate (self):
+    shell = self.object
+    sp = shell.props.shell_player
     self.psc_id  = sp.connect ('playing-song-changed',
                                self.playing_entry_changed)
     self.pc_id   = sp.connect ('playing-changed',
@@ -83,9 +87,9 @@ class IMStatusPlugin (RB.Plugin):
     if sp.get_playing ():
       self.set_entry (sp.get_playing_entry ())
 
-  def deactivate (self, shell):
-    self.shell = None
-    sp = shell.get_player ()
+  def do_deactivate (self):
+    shell = self.object
+    sp = shell.props.shell_player
     sp.disconnect (self.psc_id)
     sp.disconnect (self.pc_id)
     sp.disconnect (self.pspc_id)
@@ -134,7 +138,8 @@ class IMStatusPlugin (RB.Plugin):
     self.set_status_from_entry ()
 
   def set_status_from_entry (self):
-    db = self.shell.get_property ("db")
+    shell = self.object
+    db = shell.get_property ("db")
     self.current_artist = self.current_entry.get_string(RB.RhythmDBPropType.ARTIST)
     self.current_title = self.current_entry.get_string(RB.RhythmDBPropType.TITLE)
     self.current_album = self.current_entry.get_string(RB.RhythmDBPropType.ALBUM)
diff --git a/plugins/ipod/Makefile.am b/plugins/ipod/Makefile.am
index dd5f72c..c8e2c48 100644
--- a/plugins/ipod/Makefile.am
+++ b/plugins/ipod/Makefile.am
@@ -1,4 +1,5 @@
 plugindir = $(PLUGINDIR)/ipod
+plugindatadir = $(PLUGINDATADIR)/ipod
 plugin_LTLIBRARIES = libipod.la
 
 libipod_la_SOURCES = \
@@ -31,6 +32,7 @@ INCLUDES = 						\
 	-I$(top_srcdir)/sources/sync                   	\
 	-I$(top_srcdir)/podcast                    	\
 	-I$(top_srcdir)/shell				\
+	-I$(top_srcdir)/plugins				\
 	-DPIXMAP_DIR=\""$(datadir)/pixmaps"\"		\
 	-DSHARE_DIR=\"$(pkgdatadir)\"                   \
 	-DDATADIR=\""$(datadir)"\"			\
@@ -38,16 +40,16 @@ INCLUDES = 						\
 	$(IPOD_CFLAGS)					\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = ipod.rb-plugin.in
+plugin_in_files = ipod.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = ipod-ui.xml
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA = 					\
 	ipod-info.ui	 				\
 	ipod-init.ui
diff --git a/plugins/ipod/ipod.rb-plugin.in b/plugins/ipod/ipod.plugin.in
similarity index 92%
rename from plugins/ipod/ipod.rb-plugin.in
rename to plugins/ipod/ipod.plugin.in
index 4821e95..3d26eae 100644
--- a/plugins/ipod/ipod.rb-plugin.in
+++ b/plugins/ipod/ipod.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=ipod
-IAge=1
+IAge=2
 _Name=Portable Players - iPod
 _Description=Support for Apple iPod devices (show the content, play from device)
 Authors=James Livingston, Christophe Fergeau
diff --git a/plugins/ipod/rb-ipod-db.c b/plugins/ipod/rb-ipod-db.c
index 0c59d58..e78178e 100644
--- a/plugins/ipod/rb-ipod-db.c
+++ b/plugins/ipod/rb-ipod-db.c
@@ -114,7 +114,7 @@ typedef struct {
 
 } RbIpodDbPrivate;
 
-G_DEFINE_TYPE (RbIpodDb, rb_ipod_db, G_TYPE_OBJECT)
+G_DEFINE_DYNAMIC_TYPE (RbIpodDb, rb_ipod_db, G_TYPE_OBJECT)
 
 #define IPOD_DB_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_IPOD_DB, RbIpodDbPrivate))
 
@@ -235,6 +235,11 @@ rb_ipod_db_class_init (RbIpodDbClass *klass)
 	g_type_class_add_private (klass, sizeof (RbIpodDbPrivate));
 }
 
+static void
+rb_ipod_db_class_finalize (RbIpodDbClass *klass)
+{
+}
+
 enum _RbIpodDelayedActionType {
 	RB_IPOD_ACTION_SET_NAME,
 	RB_IPOD_ACTION_ADD_TRACK,
@@ -955,3 +960,9 @@ rb_ipod_db_get_database_version (RbIpodDb *ipod_db)
 
 	return priv->itdb->version;
 }
+
+void
+_rb_ipod_db_register_type (GTypeModule *module)
+{
+	rb_ipod_db_register_type (module);
+}
diff --git a/plugins/ipod/rb-ipod-db.h b/plugins/ipod/rb-ipod-db.h
index 27d30a7..e58c02c 100644
--- a/plugins/ipod/rb-ipod-db.h
+++ b/plugins/ipod/rb-ipod-db.h
@@ -53,6 +53,7 @@ typedef struct
 
 RbIpodDb *rb_ipod_db_new (GMount *mount);
 GType rb_ipod_db_get_type (void);
+void _rb_ipod_db_register_type (GTypeModule *module);
 
 void rb_ipod_db_save_async (RbIpodDb *db);
 
diff --git a/plugins/ipod/rb-ipod-plugin.c b/plugins/ipod/rb-ipod-plugin.c
index b606635..31a0d0b 100644
--- a/plugins/ipod/rb-ipod-plugin.c
+++ b/plugins/ipod/rb-ipod-plugin.c
@@ -44,7 +44,7 @@
 #include "rb-source.h"
 #include "rb-ipod-source.h"
 #include "rb-ipod-static-playlist-source.h"
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-file-helpers.h"
 #include "rb-util.h"
@@ -62,7 +62,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
 	RBShell *shell;
 	GtkActionGroup *action_group;
@@ -73,17 +73,13 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBIpodPluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_ipod_plugin_get_type		(void) G_GNUC_CONST;
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void rb_ipod_plugin_init (RBIpodPlugin *plugin);
-static void rb_ipod_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
 static RBSource * create_source_cb (RBRemovableMediaManager *rmm,
 				    GMount *mount,
@@ -95,7 +91,7 @@ static void  rb_ipod_plugin_cmd_playlist_rename (GtkAction *action, RBSource *so
 static void  rb_ipod_plugin_cmd_playlist_delete (GtkAction *action, RBSource *source);
 static void  rb_ipod_plugin_cmd_properties (GtkAction *action, RBSource *source);
 
-RB_PLUGIN_REGISTER(RBIpodPlugin, rb_ipod_plugin)
+RB_DEFINE_PLUGIN(RB_TYPE_IPOD_PLUGIN, RBIpodPlugin, rb_ipod_plugin,)
 
 
 static GtkActionEntry rb_ipod_plugin_actions [] =
@@ -117,23 +113,6 @@ static GtkActionEntry rb_ipod_plugin_actions [] =
 	  G_CALLBACK (rb_ipod_plugin_cmd_playlist_delete) },
 };
 
-
-static void
-rb_ipod_plugin_class_init (RBIpodPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_ipod_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-
-	/* register types used by the plugin */
-	RB_PLUGIN_REGISTER_TYPE (rb_ipod_source);
-	RB_PLUGIN_REGISTER_TYPE (rb_ipod_static_playlist_source);
-}
-
 static void
 rb_ipod_plugin_init (RBIpodPlugin *plugin)
 {
@@ -141,26 +120,16 @@ rb_ipod_plugin_init (RBIpodPlugin *plugin)
 }
 
 static void
-rb_ipod_plugin_finalize (GObject *object)
-{
-	/*RBIpodPlugin *plugin = RB_IPOD_PLUGIN (object);*/
-
-	rb_debug ("RBIpodPlugin finalising");
-
-	G_OBJECT_CLASS (rb_ipod_plugin_parent_class)->finalize (object);
-}
-
-static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBIpodPlugin *plugin = RB_IPOD_PLUGIN (bplugin);
 	RBRemovableMediaManager *rmm = NULL;
 	GtkUIManager *uimanager = NULL;
+	RBShell *shell;
 	gboolean scanned;
 	char *file;
 
-	plugin->shell = shell;
+	g_object_get (plugin, "object", &shell, NULL);
 
 	g_object_get (G_OBJECT (shell),
 		      "removable-media-manager", &rmm,
@@ -178,7 +147,7 @@ impl_activate (RBPlugin *bplugin,
 						   rb_ipod_plugin_actions,
 						   G_N_ELEMENTS (rb_ipod_plugin_actions));
 	gtk_ui_manager_insert_action_group (uimanager, plugin->action_group, 0);
-	file = rb_plugin_find_file (bplugin, "ipod-ui.xml");
+	file = rb_find_plugin_data_file (G_OBJECT (bplugin), "ipod-ui.xml");
 	plugin->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager,
 							       file,
 							       NULL);
@@ -194,19 +163,22 @@ impl_activate (RBPlugin *bplugin,
 	if (scanned)
 		rb_removable_media_manager_scan (rmm);
 
-	g_object_unref (G_OBJECT (rmm));
-	g_object_unref (G_OBJECT (uimanager));
+	g_object_unref (rmm);
+	g_object_unref (uimanager);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBIpodPlugin *plugin = RB_IPOD_PLUGIN (bplugin);
 	RBRemovableMediaManager *rmm = NULL;
 	GtkUIManager *uimanager = NULL;
+	RBShell *shell;
 
-	g_object_get (G_OBJECT (shell),
+	g_object_get (plugin, "object", &shell, NULL);
+
+	g_object_get (shell,
 		      "removable-media-manager", &rmm,
 		      "ui-manager", &uimanager,
 		      NULL);
@@ -220,8 +192,9 @@ impl_deactivate	(RBPlugin *bplugin,
 	g_list_free (plugin->ipod_sources);
 	plugin->ipod_sources = NULL;
 
-	g_object_unref (G_OBJECT (uimanager));
-	g_object_unref (G_OBJECT (rmm));
+	g_object_unref (uimanager);
+	g_object_unref (rmm);
+	g_object_unref (shell);
 }
 
 static void
@@ -234,6 +207,8 @@ static RBSource *
 create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *device_info, RBIpodPlugin *plugin)
 {
 	RBSource *src;
+	RBShell *shell;
+
 	if (!rb_ipod_helpers_is_ipod (mount, device_info)) {
 		return NULL;
 	}
@@ -241,7 +216,7 @@ create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *devic
 	if (rb_ipod_helpers_needs_init (mount)) {
 		gboolean inited;
 		gchar *builder_file;
-		builder_file = rb_plugin_find_file (RB_PLUGIN (plugin), "ipod-init.ui");
+		builder_file = rb_find_plugin_data_file (G_OBJECT (plugin), "ipod-init.ui");
 		inited = rb_ipod_helpers_show_first_time_dialog (mount,
 								 builder_file);
 		g_free (builder_file);
@@ -250,10 +225,12 @@ create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, MPIDDevice *devic
 		}
 	}
 
-	src = RB_SOURCE (rb_ipod_source_new (RB_PLUGIN (plugin),
-					     plugin->shell,
+	g_object_get (plugin, "object", &shell, NULL);
+	src = RB_SOURCE (rb_ipod_source_new (G_OBJECT (plugin),
+					     shell,
 					     mount,
 					     device_info));
+	g_object_unref (shell);
 
 	plugin->ipod_sources = g_list_prepend (plugin->ipod_sources, src);
 	g_signal_connect_object (G_OBJECT (src),
@@ -330,3 +307,14 @@ rb_ipod_plugin_cmd_playlist_new (GtkAction *action, RBSource *source)
 	rb_ipod_source_new_playlist (RB_IPOD_SOURCE (source));
 }
 
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_ipod_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_ipod_source_register_type (G_TYPE_MODULE (module));
+	_rb_ipod_static_playlist_source_register_type (G_TYPE_MODULE (module));
+	_rb_ipod_db_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_IPOD_PLUGIN);
+}
diff --git a/plugins/ipod/rb-ipod-source.c b/plugins/ipod/rb-ipod-source.c
index 6de98a4..e3ad7a0 100644
--- a/plugins/ipod/rb-ipod-source.c
+++ b/plugins/ipod/rb-ipod-source.c
@@ -41,7 +41,6 @@
 #include "rb-debug.h"
 #include "rb-file-helpers.h"
 #include "rb-builder-helpers.h"
-#include "rb-plugin.h"
 #include "rb-removable-media-manager.h"
 #include "rb-ipod-static-playlist-source.h"
 #include "rb-util.h"
@@ -56,7 +55,6 @@
 #include "rb-stock-icons.h"
 
 static void rb_ipod_source_constructed (GObject *object);
-static void rb_ipod_source_class_init (RBiPodSourceClass *klass);
 static void rb_ipod_source_dispose (GObject *object);
 
 static void impl_delete (RBSource *asource);
@@ -145,9 +143,7 @@ enum
 	PROP_DEVICE_SERIAL
 };
 
-RB_PLUGIN_DEFINE_TYPE(RBiPodSource,
-		      rb_ipod_source,
-		      RB_TYPE_MEDIA_PLAYER_SOURCE)
+G_DEFINE_DYNAMIC_TYPE(RBiPodSource, rb_ipod_source, RB_TYPE_MEDIA_PLAYER_SOURCE)
 
 #define IPOD_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_IPOD_SOURCE, RBiPodSourcePrivate))
 
@@ -204,6 +200,11 @@ rb_ipod_source_class_init (RBiPodSourceClass *klass)
 }
 
 static void
+rb_ipod_source_class_finalize (RBiPodSourceClass *klass)
+{
+}
+
+static void
 rb_ipod_source_set_property (GObject *object,
 			     guint prop_id,
 			     const GValue *value,
@@ -346,7 +347,7 @@ rb_ipod_source_dispose (GObject *object)
 }
 
 RBMediaPlayerSource *
-rb_ipod_source_new (RBPlugin *plugin,
+rb_ipod_source_new (GObject *plugin,
 		    RBShell *shell,
 		    GMount *mount,
 		    MPIDDevice *device_info)
@@ -1993,7 +1994,7 @@ impl_show_properties (RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidge
 	const gchar *mp;
 	char *builder_file;
 	Itdb_Device *ipod_dev;
-	RBPlugin *plugin;
+	GObject *plugin;
 	GList *output_formats;
 	GList *t;
 	GString *str;
@@ -2006,7 +2007,7 @@ impl_show_properties (RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidge
 	}
 
 	g_object_get (source, "plugin", &plugin, NULL);
-	builder_file = rb_plugin_find_file (plugin, "ipod-info.ui");
+	builder_file = rb_find_plugin_data_file (plugin, "ipod-info.ui");
 	g_object_unref (plugin);
 
 	if (builder_file == NULL) {
@@ -2162,3 +2163,9 @@ impl_get_entries (RBMediaPlayerSource *source, const char *category, GHashTable
 		}
 	}
 }
+
+void
+_rb_ipod_source_register_type (GTypeModule *module)
+{
+	rb_ipod_source_register_type (module);
+}
diff --git a/plugins/ipod/rb-ipod-source.h b/plugins/ipod/rb-ipod-source.h
index 2d362d2..f95d735 100644
--- a/plugins/ipod/rb-ipod-source.h
+++ b/plugins/ipod/rb-ipod-source.h
@@ -31,7 +31,6 @@
 #include "rb-shell.h"
 #include "rb-media-player-source.h"
 #include "rhythmdb.h"
-#include "rb-plugin.h"
 #include "mediaplayerid.h"
 #include "rb-ipod-db.h"
 
@@ -54,12 +53,12 @@ typedef struct
 	RBMediaPlayerSourceClass parent;
 } RBiPodSourceClass;
 
-RBMediaPlayerSource	*rb_ipod_source_new		(RBPlugin *plugin,
+RBMediaPlayerSource	*rb_ipod_source_new		(GObject *plugin,
 							 RBShell *shell,
 							 GMount *mount,
 							 MPIDDevice *device_info);
 GType			rb_ipod_source_get_type		(void);
-GType                   rb_ipod_source_register_type    (GTypeModule *module);
+void                    _rb_ipod_source_register_type   (GTypeModule *module);
 
 Itdb_Playlist *		rb_ipod_source_new_playlist	(RBiPodSource *source);
 void			rb_ipod_source_remove_playlist	(RBiPodSource *ipod_source,
diff --git a/plugins/ipod/rb-ipod-static-playlist-source.c b/plugins/ipod/rb-ipod-static-playlist-source.c
index e5fd4a0..a2f0248 100644
--- a/plugins/ipod/rb-ipod-static-playlist-source.c
+++ b/plugins/ipod/rb-ipod-static-playlist-source.c
@@ -25,7 +25,6 @@
 #include <gtk/gtk.h>
 #include <gpod/itdb.h>
 
-#include "rb-plugin.h"
 #include "rb-debug.h"
 #include "rb-util.h"
 #include "rhythmdb.h"
@@ -60,9 +59,7 @@ typedef struct
 	gboolean	was_reordered;
 } RBIpodStaticPlaylistSourcePrivate;
 
-RB_PLUGIN_DEFINE_TYPE(RBIpodStaticPlaylistSource,
-		      rb_ipod_static_playlist_source,
-		      RB_TYPE_STATIC_PLAYLIST_SOURCE)
+G_DEFINE_DYNAMIC_TYPE(RBIpodStaticPlaylistSource, rb_ipod_static_playlist_source, RB_TYPE_STATIC_PLAYLIST_SOURCE)
 
 #define IPOD_STATIC_PLAYLIST_SOURCE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_IPOD_STATIC_PLAYLIST_SOURCE, RBIpodStaticPlaylistSourcePrivate))
 
@@ -129,6 +126,11 @@ rb_ipod_static_playlist_source_class_init (RBIpodStaticPlaylistSourceClass *klas
 }
 
 static void
+rb_ipod_static_playlist_source_class_finalize (RBIpodStaticPlaylistSourceClass *klass)
+{
+}
+
+static void
 rb_ipod_static_playlist_source_init (RBIpodStaticPlaylistSource *source)
 {
 
@@ -299,3 +301,9 @@ source_name_changed_cb (RBIpodStaticPlaylistSource *source,
 	}
 	g_free (name);
 }
+
+void
+_rb_ipod_static_playlist_source_register_type (GTypeModule *module)
+{
+	rb_ipod_static_playlist_source_register_type (module);
+}
diff --git a/plugins/ipod/rb-ipod-static-playlist-source.h b/plugins/ipod/rb-ipod-static-playlist-source.h
index b793806..38afff0 100644
--- a/plugins/ipod/rb-ipod-static-playlist-source.h
+++ b/plugins/ipod/rb-ipod-static-playlist-source.h
@@ -46,7 +46,7 @@ typedef struct
 } RBIpodStaticPlaylistSourceClass;
 
 GType		rb_ipod_static_playlist_source_get_type 	(void);
-GType           rb_ipod_static_playlist_source_register_type    (GTypeModule *module);
+void		_rb_ipod_static_playlist_source_register_type   (GTypeModule *module);
 
 RBIpodStaticPlaylistSource *	rb_ipod_static_playlist_source_new (RBShell *shell,
 								    RBiPodSource *source,
diff --git a/plugins/iradio/Makefile.am b/plugins/iradio/Makefile.am
index aee79e4..10dda8d 100644
--- a/plugins/iradio/Makefile.am
+++ b/plugins/iradio/Makefile.am
@@ -1,6 +1,7 @@
 NULL =
 
 plugindir = $(PLUGINDIR)/iradio
+plugindatadir = $(PLUGINDATADIR)/iradio
 plugin_LTLIBRARIES = libiradio.la
 
 libiradio_la_SOURCES = 					\
@@ -38,31 +39,33 @@ INCLUDES = 						\
 	$(TOTEM_PLPARSER_CFLAGS)			\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA = \
 	station-properties.ui
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = iradio-ui.xml
 
-plugin_in_files = iradio.rb-plugin.in
+xspfdir = $(plugindatadir)
+xspf_DATA = iradio-initial.xspf
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = iradio.plugin.in
+
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
 BUILT_SOURCES =							\
-	$(plugin_in_files:.rb-plugin.in=.rb-plugin) 	\
+	$(plugin_in_files:.plugin.in=.plugin) 	\
 	$(NULL)
 
 plugin_DATA = 			\
 	$(BUILT_SOURCES)	\
-	iradio-initial.xspf	\
 	$(NULL)
 
 EXTRA_DIST = 			\
 	$(gtkbuilder_DATA)	\
 	$(uixml_DATA)		\
 	$(plugin_in_files)	\
-	iradio-initial.xspf	\
+	$(xspf_DATA)		\
 	$(NULL)
 
 CLEANFILES = 			\
diff --git a/plugins/iradio/iradio.rb-plugin.in b/plugins/iradio/iradio.plugin.in
similarity index 88%
rename from plugins/iradio/iradio.rb-plugin.in
rename to plugins/iradio/iradio.plugin.in
index 9c8a8ae..19013c3 100644
--- a/plugins/iradio/iradio.rb-plugin.in
+++ b/plugins/iradio/iradio.plugin.in
@@ -1,6 +1,7 @@
-[RB Plugin]
+[Plugin]
 Module=iradio
-IAge=1
+Builtin=true
+IAge=2
 _Name=Internet Radio
 _Description=Support for broadcasting services transmitted via the Internet
 Authors=Rhythmbox authors
diff --git a/plugins/iradio/rb-iradio-plugin.c b/plugins/iradio/rb-iradio-plugin.c
index 0bee52e..da8caa8 100644
--- a/plugins/iradio/rb-iradio-plugin.c
+++ b/plugins/iradio/rb-iradio-plugin.c
@@ -38,11 +38,12 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-dialog.h"
 #include "rb-iradio-source.h"
+#include "rb-iradio-source-search.h"
 #include "rb-file-helpers.h"
 #include "rb-display-page-group.h"
 
@@ -56,25 +57,21 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
+
 	RBSource *source;
 	guint ui_merge_id;
 } RBIRadioPlugin;
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBIRadioPluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_iradio_plugin_get_type		(void) G_GNUC_CONST;
-
-
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
-RB_PLUGIN_REGISTER(RBIRadioPlugin, rb_iradio_plugin)
+RB_DEFINE_PLUGIN(RB_TYPE_IRADIO_PLUGIN, RBIRadioPlugin, rb_iradio_plugin,)
 
 static void
 rb_iradio_plugin_init (RBIRadioPlugin *plugin)
@@ -83,31 +80,19 @@ rb_iradio_plugin_init (RBIRadioPlugin *plugin)
 }
 
 static void
-rb_iradio_plugin_finalize (GObject *object)
-{
-/*
-	RBIRadioPlugin *plugin = RB_IRADIO_PLUGIN (object);
-*/
-	rb_debug ("RBIRadioPlugin finalising");
-
-	G_OBJECT_CLASS (rb_iradio_plugin_parent_class)->finalize (object);
-}
-
-
-
-static void
-impl_activate (RBPlugin *plugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *plugin)
 {
 	RBIRadioPlugin *pi = RB_IRADIO_PLUGIN (plugin);
 	GtkUIManager *uimanager;
 	char *filename;
+	RBShell *shell;
 
-	pi->source = rb_iradio_source_new (shell, plugin);
+	g_object_get (pi, "object", &shell, NULL);
+	pi->source = rb_iradio_source_new (shell, G_OBJECT (plugin));
 	rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (pi->source), RB_DISPLAY_PAGE_GROUP_LIBRARY);
 
 	g_object_get (shell, "ui-manager", &uimanager, NULL);
-	filename = rb_plugin_find_file (plugin, "iradio-ui.xml");
+	filename = rb_find_plugin_data_file (G_OBJECT (plugin), "iradio-ui.xml");
 	if (filename != NULL) {
 		pi->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager,
                                                              filename,
@@ -118,14 +103,17 @@ impl_activate (RBPlugin *plugin,
 
 	g_free (filename);
 	g_object_unref (uimanager);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *plugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *plugin)
 {
 	RBIRadioPlugin *pi = RB_IRADIO_PLUGIN (plugin);
 	GtkUIManager *uimanager;
+	RBShell *shell;
+
+	g_object_get (pi, "object", &shell, NULL);
 
 	g_object_get (shell, "ui-manager", &uimanager, NULL);
 	gtk_ui_manager_remove_ui (uimanager, pi->ui_merge_id);
@@ -133,18 +121,17 @@ impl_deactivate	(RBPlugin *plugin,
 
 	rb_display_page_delete_thyself (RB_DISPLAY_PAGE (pi->source));
 	pi->source = NULL;
-}
 
+	g_object_unref (shell);
+}
 
-static void
-rb_iradio_plugin_class_init (RBIRadioPluginClass *klass)
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_iradio_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
+	rb_iradio_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_iradio_source_register_type (G_TYPE_MODULE (module));
+	_rb_iradio_source_search_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_IRADIO_PLUGIN);
 }
-
diff --git a/plugins/iradio/rb-iradio-source-search.c b/plugins/iradio/rb-iradio-source-search.c
index 3238a41..662d873 100644
--- a/plugins/iradio/rb-iradio-source-search.c
+++ b/plugins/iradio/rb-iradio-source-search.c
@@ -33,7 +33,7 @@
 static void	rb_iradio_source_search_class_init (RBIRadioSourceSearchClass *klass);
 static void	rb_iradio_source_search_init (RBIRadioSourceSearch *search);
 
-G_DEFINE_TYPE (RBIRadioSourceSearch, rb_iradio_source_search, RB_TYPE_SOURCE_SEARCH)
+G_DEFINE_DYNAMIC_TYPE (RBIRadioSourceSearch, rb_iradio_source_search, RB_TYPE_SOURCE_SEARCH)
 
 static RhythmDBQuery *
 impl_create_query (RBSourceSearch *bsearch, RhythmDB *db, const char *search_text)
@@ -57,6 +57,11 @@ rb_iradio_source_search_class_init (RBIRadioSourceSearchClass *klass)
 }
 
 static void
+rb_iradio_source_search_class_finalize (RBIRadioSourceSearchClass *klass)
+{
+}
+
+static void
 rb_iradio_source_search_init (RBIRadioSourceSearch *search)
 {
 	/* nothing */
@@ -69,3 +74,8 @@ rb_iradio_source_search_new ()
 	return g_object_new (RB_TYPE_IRADIO_SOURCE_SEARCH, NULL);
 }
 
+void
+_rb_iradio_source_search_register_type (GTypeModule *module)
+{
+	rb_iradio_source_search_register_type (module);
+}
diff --git a/plugins/iradio/rb-iradio-source-search.h b/plugins/iradio/rb-iradio-source-search.h
index 5e29512..0726655 100644
--- a/plugins/iradio/rb-iradio-source-search.h
+++ b/plugins/iradio/rb-iradio-source-search.h
@@ -60,6 +60,8 @@ GType		rb_iradio_source_search_get_type	(void);
 
 RBSourceSearch *rb_iradio_source_search_new 		(void);
 
+void		_rb_iradio_source_search_register_type	(GTypeModule *module);
+
 G_END_DECLS
 
 #endif	/* __RB_IRADIO_SOURCE_SEARCH_H */
diff --git a/plugins/iradio/rb-iradio-source.c b/plugins/iradio/rb-iradio-source.c
index 8f8d060..21110be 100644
--- a/plugins/iradio/rb-iradio-source.c
+++ b/plugins/iradio/rb-iradio-source.c
@@ -51,7 +51,6 @@
 #include "rb-shell-player.h"
 #include "rb-player.h"
 #include "rb-metadata.h"
-#include "rb-plugin.h"
 #include "rb-cut-and-paste-code.h"
 #include "rb-source-search-basic.h"
 
@@ -151,8 +150,6 @@ struct RBIRadioSourcePrivate
 	gint info_available_id;
 
 	gboolean dispose_has_run;
-
-	GSettings *settings;
 };
 
 #define RB_IRADIO_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_IRADIO_SOURCE, RBIRadioSourcePrivate))
@@ -169,9 +166,9 @@ static const GtkTargetEntry stations_view_drag_types[] = {
 	{  "_NETSCAPE_URL", 0, 1 },
 };
 
-G_DEFINE_TYPE (RBIRadioSource, rb_iradio_source, RB_TYPE_STREAMING_SOURCE);
+G_DEFINE_DYNAMIC_TYPE (RBIRadioSource, rb_iradio_source, RB_TYPE_STREAMING_SOURCE);
 
-G_DEFINE_TYPE (RBIRadioEntryType, rb_iradio_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
+G_DEFINE_DYNAMIC_TYPE (RBIRadioEntryType, rb_iradio_entry_type, RHYTHMDB_TYPE_ENTRY_TYPE);
 
 static void
 rb_iradio_entry_type_class_init (RBIRadioEntryTypeClass *klass)
@@ -182,6 +179,11 @@ rb_iradio_entry_type_class_init (RBIRadioEntryTypeClass *klass)
 }
 
 static void
+rb_iradio_entry_type_class_finalize (RBIRadioEntryTypeClass *klass)
+{
+}
+
+static void
 rb_iradio_entry_type_init (RBIRadioEntryType *etype)
 {
 }
@@ -222,6 +224,11 @@ rb_iradio_source_class_init (RBIRadioSourceClass *klass)
 }
 
 static void
+rb_iradio_source_class_finalize (RBIRadioSourceClass *klass)
+{
+}
+
+static void
 rb_iradio_source_init (RBIRadioSource *source)
 {
 	gint size;
@@ -308,11 +315,11 @@ rb_iradio_source_constructed (GObject *object)
 
 	settings = g_settings_new ("org.gnome.rhythmbox.plugins.iradio");
 	if (g_settings_get_boolean (settings, "initial-stations-loaded") == FALSE) {
-		RBPlugin *plugin;
+		GObject *plugin;
 		char *file;
 
 		g_object_get (source, "plugin", &plugin, NULL);
-		file = rb_plugin_find_file (plugin, "iradio-initial.xspf");
+		file = rb_find_plugin_data_file (plugin, "iradio-initial.xspf");
 		if (file != NULL) {
 			char *uri = g_filename_to_uri (file, NULL, NULL);
 			if (uri != NULL) {
@@ -324,9 +331,6 @@ rb_iradio_source_constructed (GObject *object)
 		g_object_unref (plugin);
 	}
 
-	source->priv->settings = g_settings_get_child (settings, "source");
-	g_object_unref (settings);
-
 	source->priv->action_group = _rb_display_page_register_action_group (RB_DISPLAY_PAGE (source),
 									     "IRadioActions",
 									     rb_iradio_source_actions,
@@ -375,6 +379,7 @@ rb_iradio_source_constructed (GObject *object)
 	source->priv->genres = rb_property_view_new (source->priv->db,
 						     RHYTHMDB_PROP_GENRE,
 						     _("Genre"));
+	gtk_widget_set_no_show_all (GTK_WIDGET (source->priv->genres), TRUE);
 	g_signal_connect_object (source->priv->genres,
 				 "property-selected",
 				 G_CALLBACK (genre_selected_cb),
@@ -447,11 +452,12 @@ rb_iradio_source_get_property (GObject *object,
 }
 
 RBSource *
-rb_iradio_source_new (RBShell *shell, RBPlugin *plugin)
+rb_iradio_source_new (RBShell *shell, GObject *plugin)
 {
 	RBSource *source;
 	RhythmDBEntryType *entry_type;
 	RhythmDB *db;
+	GSettings *settings;
 
 	g_object_get (shell, "db", &db, NULL);
 
@@ -467,13 +473,16 @@ rb_iradio_source_new (RBShell *shell, RBPlugin *plugin)
 	}
 	g_object_unref (db);
 
+	settings = g_settings_new ("org.gnome.rhythmbox.plugins.iradio");
 	source = RB_SOURCE (g_object_new (RB_TYPE_IRADIO_SOURCE,
 					  "name", _("Radio"),
 					  "shell", shell,
 					  "entry-type", entry_type,
 					  "plugin", plugin,
 					  "search-type", RB_SOURCE_SEARCH_INCREMENTAL,
+					  "settings", g_settings_get_child (settings, "source"),
 					  NULL));
+	g_object_unref (settings);
 	rb_shell_register_entry_type_for_source (shell, source, entry_type);
 	return source;
 }
@@ -633,7 +642,7 @@ static void
 impl_song_properties (RBSource *asource)
 {
 	RBIRadioSource *source = RB_IRADIO_SOURCE (asource);
-	RBPlugin *plugin;
+	GObject *plugin;
 	GtkWidget *dialog;
 
 	g_object_get (source, "plugin", &plugin, NULL);
@@ -1123,3 +1132,9 @@ playing_source_changed_cb (RBShellPlayer *player,
 	g_object_unref (backend);
 }
 
+void
+_rb_iradio_source_register_type (GTypeModule *module)
+{
+	rb_iradio_entry_type_register_type (module);
+	rb_iradio_source_register_type (module);
+}
diff --git a/plugins/iradio/rb-iradio-source.h b/plugins/iradio/rb-iradio-source.h
index 17217b1..224de0c 100644
--- a/plugins/iradio/rb-iradio-source.h
+++ b/plugins/iradio/rb-iradio-source.h
@@ -30,7 +30,6 @@
 #define __RB_IRADIO_SOURCE_H
 
 #include "rb-shell.h"
-#include "rb-plugin.h"
 #include "rb-streaming-source.h"
 
 G_BEGIN_DECLS
@@ -58,7 +57,7 @@ typedef struct
 
 GType		rb_iradio_source_get_type	(void);
 
-RBSource *	rb_iradio_source_new		(RBShell *shell, RBPlugin *plugin);
+RBSource *	rb_iradio_source_new		(RBShell *shell, GObject *plugin);
 
 void		rb_iradio_source_add_station	(RBIRadioSource *source,
 						 const char *uri, const char *title, const char *genre);
@@ -66,6 +65,8 @@ void		rb_iradio_source_add_station	(RBIRadioSource *source,
 void		rb_iradio_source_add_from_playlist (RBIRadioSource *source,
                                                     const char *uri);
 
+void		_rb_iradio_source_register_type (GTypeModule *module);
+
 G_END_DECLS
 
 #endif /* __RB_IRADIO_SOURCE_H */
diff --git a/plugins/iradio/rb-station-properties-dialog.c b/plugins/iradio/rb-station-properties-dialog.c
index fc59f31..151490e 100644
--- a/plugins/iradio/rb-station-properties-dialog.c
+++ b/plugins/iradio/rb-station-properties-dialog.c
@@ -39,7 +39,6 @@
 #include "rb-builder-helpers.h"
 #include "rb-dialog.h"
 #include "rb-rating.h"
-#include "rb-plugin.h"
 #include "rb-util.h"
 
 static void rb_station_properties_dialog_class_init (RBStationPropertiesDialogClass *klass);
@@ -80,7 +79,7 @@ static void rb_station_properties_dialog_location_changed_cb (GtkEntry *entry,
 
 struct RBStationPropertiesDialogPrivate
 {
-	RBPlugin    *plugin;
+	GObject     *plugin;
 	RBEntryView *entry_view;
 	RhythmDB    *db;
 	RhythmDBEntry *current_entry;
@@ -107,9 +106,7 @@ enum
 	PROP_PLUGIN
 };
 
-G_DEFINE_TYPE (RBStationPropertiesDialog,
-	       rb_station_properties_dialog,
-	       GTK_TYPE_DIALOG)
+G_DEFINE_DYNAMIC_TYPE (RBStationPropertiesDialog, rb_station_properties_dialog, GTK_TYPE_DIALOG)
 
 static void
 rb_station_properties_dialog_class_init (RBStationPropertiesDialogClass *klass)
@@ -133,9 +130,9 @@ rb_station_properties_dialog_class_init (RBStationPropertiesDialogClass *klass)
 	g_object_class_install_property (object_class,
 					 PROP_PLUGIN,
 					 g_param_spec_object ("plugin",
-					                      "RBPlugin",
-					                      "RBPlugin to use to find files",
-					                      RB_TYPE_PLUGIN,
+					                      "plugin instance",
+					                      "plugin instance to use to find files",
+					                      G_TYPE_OBJECT,
 					                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 	object_class->dispose = rb_station_properties_dialog_dispose;
@@ -145,6 +142,11 @@ rb_station_properties_dialog_class_init (RBStationPropertiesDialogClass *klass)
 }
 
 static void
+rb_station_properties_dialog_class_finalize (RBStationPropertiesDialogClass *klass)
+{
+}
+
+static void
 rb_station_properties_dialog_init (RBStationPropertiesDialog *dialog)
 {
         dialog->priv = RB_STATION_PROPERTIES_DIALOG_GET_PRIVATE (dialog);
@@ -172,7 +174,7 @@ rb_station_properties_dialog_constructed (GObject *object)
 	gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 	gtk_box_set_spacing (GTK_BOX (content_area), 2);
 
-	builder_file = rb_plugin_find_file (dialog->priv->plugin, "station-properties.ui");
+	builder_file = rb_find_plugin_data_file (dialog->priv->plugin, "station-properties.ui");
 	g_assert (builder_file != NULL);
 	builder = rb_builder_load (builder_file, dialog);
 	g_free (builder_file);
@@ -310,7 +312,7 @@ rb_station_properties_dialog_get_property (GObject *object,
 }
 
 GtkWidget *
-rb_station_properties_dialog_new (RBPlugin *plugin, RBEntryView *entry_view)
+rb_station_properties_dialog_new (GObject *plugin, RBEntryView *entry_view)
 {
 	RBStationPropertiesDialog *dialog;
 
@@ -600,3 +602,9 @@ rb_station_properties_dialog_location_changed_cb (GtkEntry *entry,
 						  RBStationPropertiesDialog *dialog)
 {
 }
+
+void
+_rb_station_properties_dialog_register_type (GTypeModule *module)
+{
+	rb_station_properties_dialog_register_type (module);
+}
diff --git a/plugins/iradio/rb-station-properties-dialog.h b/plugins/iradio/rb-station-properties-dialog.h
index 6d758c6..cdb3c6b 100644
--- a/plugins/iradio/rb-station-properties-dialog.h
+++ b/plugins/iradio/rb-station-properties-dialog.h
@@ -27,7 +27,6 @@
 
 #include <gtk/gtk.h>
 #include "rb-entry-view.h"
-#include "rb-plugin.h"
 
 #ifndef __RB_STATION_PROPERTIES_DIALOG_H
 #define __RB_STATION_PROPERTIES_DIALOG_H
@@ -57,7 +56,9 @@ typedef struct
 
 GType      rb_station_properties_dialog_get_type (void);
 
-GtkWidget *rb_station_properties_dialog_new      (RBPlugin *plugin, RBEntryView *view);
+GtkWidget *rb_station_properties_dialog_new      (GObject *plugin, RBEntryView *view);
+
+void       _rb_station_properties_dialog_register_type (GTypeModule *module);
 
 G_END_DECLS
 
diff --git a/plugins/jamendo/jamendo/JamendoConfigureDialog.py b/plugins/jamendo/JamendoConfigureDialog.py
similarity index 74%
rename from plugins/jamendo/jamendo/JamendoConfigureDialog.py
rename to plugins/jamendo/JamendoConfigureDialog.py
index 3fe72b9..5b337ca 100644
--- a/plugins/jamendo/jamendo/JamendoConfigureDialog.py
+++ b/plugins/jamendo/JamendoConfigureDialog.py
@@ -18,21 +18,25 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-import gobject
-
 import rb
-from gi.repository import Gtk, Gio
+from gi.repository import Gtk, Gio, GObject, PeasGtk
+
+format_list = ['ogg3', 'mp32']
 
-# format_list = ['ogg3', 'mp32']
+class JamendoConfigureDialog (GObject.Object, PeasGtk.Configurable):
+	__gtype_name__ = 'JamendoConfigureDialog'
+	object = GObject.property(type=GObject.Object)
 
-class JamendoConfigureDialog (object):
-	def __init__(self, builder_file):
+	def __init__(self):
+		GObject.Object.__init__(self)
 		self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.jamendo")
+		self.hate = self
 
+	def do_create_configure_widget(self):
 		builder = Gtk.Builder()
-		builder.add_from_file(builder_file)
+		builder.add_from_file(rb.find_plugin_file(self, "jamendo-prefs.ui"))
 
-		self.dialog = builder.get_object('preferences_dialog')
+		self.config = builder.get_object('config')
 		self.audio_combobox = builder.get_object("audio_combobox")
 
 		# probably should just bind this, but too lazy
@@ -46,14 +50,8 @@ class JamendoConfigureDialog (object):
 			format = 0
 		self.audio_combobox.set_active(format)
 
-		self.dialog.connect("response", self.dialog_response)
 		self.audio_combobox.connect("changed", self.audio_combobox_changed)
-
-	def get_dialog (self):
-		return self.dialog
-
-	def dialog_response (self, dialog, response):
-		dialog.hide()
+		return self.config
 
 	def audio_combobox_changed (self, combobox):
 		format = self.audio_combobox.get_active()
diff --git a/plugins/jamendo/jamendo/JamendoSaxHandler.py b/plugins/jamendo/JamendoSaxHandler.py
similarity index 100%
rename from plugins/jamendo/jamendo/JamendoSaxHandler.py
rename to plugins/jamendo/JamendoSaxHandler.py
diff --git a/plugins/jamendo/jamendo/JamendoSource.py b/plugins/jamendo/JamendoSource.py
similarity index 92%
rename from plugins/jamendo/jamendo/JamendoSource.py
rename to plugins/jamendo/JamendoSource.py
index a069478..0076eed 100644
--- a/plugins/jamendo/jamendo/JamendoSource.py
+++ b/plugins/jamendo/JamendoSource.py
@@ -54,15 +54,12 @@ artwork_url = "http://api.jamendo.com/get2/image/album/redirect/?id=%s&imagesize
 artist_url = "http://www.jamendo.com/get/artist/id/album/page/plain/";
 
 class JamendoSource(RB.BrowserSource):
-	__gproperties__ = {
-		'plugin': (RB.Plugin, 'plugin', 'plugin', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
-	}
 
 	def __init__(self):
-
-		RB.BrowserSource.__init__(self, name=_("Jamendo"), settings=Gio.Settings("org.gnome.rhythmbox.plugins.jamendo").get_child("source"))
+		RB.BrowserSource.__init__(self, name=_("Jamendo"))
 
 		# catalogue stuff
+		self.hate = self
 		self.__db = None
 		self.__saxHandler = None
 		self.__activated = False
@@ -86,18 +83,6 @@ class JamendoSource(RB.BrowserSource):
 
 		self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.jamendo")
 
-	def do_set_property(self, property, value):
-		if property.name == 'plugin':
-			self.__plugin = value
-		else:
-			raise AttributeError, 'unknown property %s' % property.name
-
-	def do_impl_get_browser_key (self):
-		return "/apps/rhythmbox/plugins/jamendo/show_browser"
-
-	def do_impl_get_paned_key (self):
-		return "/apps/rhythmbox/plugins/jamendo/paned_position"
-
 	def do_impl_can_delete (self):
 		return False
 
@@ -125,14 +110,14 @@ class JamendoSource(RB.BrowserSource):
 				progress = -1.0
 			return (_("Loading Jamendo catalog"), None, progress)
 		else:
-			qm = self.get_property("query-model")
+			qm = self.props.query_model
 			return (qm.compute_status_normal("%d song", "%d songs"), None, 2.0)
 
 	def do_selected(self):
 		if not self.__activated:
-			shell = self.get_property('shell')
-			self.__db = shell.get_property('db')
-			self.__entry_type = self.get_property('entry-type')
+			shell = self.props.shell
+			self.__db = shell.props.db
+			self.__entry_type = self.props.entry_type
 
 			self.__activated = True
 			self.__show_loading_screen (True)
@@ -253,7 +238,7 @@ class JamendoSource(RB.BrowserSource):
 		if self.__info_screen is None:
 			# load the builder stuff
 			builder = Gtk.Builder()
-			builder.add_from_file(self.__plugin.find_file("jamendo-loading.ui"))
+			builder.add_from_file(rb.find_plugin_file(self.props.plugin, "jamendo-loading.ui"))
 
 			self.__info_screen = builder.get_object("jamendo_loading_scrolledwindow")
 			self.pack_start(self.__info_screen, True, True, 0)
diff --git a/plugins/jamendo/Makefile.am b/plugins/jamendo/Makefile.am
index 5d5e9e2..e708eff 100644
--- a/plugins/jamendo/Makefile.am
+++ b/plugins/jamendo/Makefile.am
@@ -1,15 +1,19 @@
 # Jamendo Python Plugin
 
-SUBDIRS = jamendo
-
 plugindir = $(PLUGINDIR)/jamendo
+plugindatadir = $(PLUGINDATADIR)/jamendo
+plugin_PYTHON =                       \
+       JamendoSource.py	              \
+       JamendoSaxHandler.py	      \
+       JamendoConfigureDialog.py      \
+       jamendo.py
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
-
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
-plugin_in_files = jamendo.rb-plugin.in
+plugin_in_files = jamendo.plugin.in
 
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA =	\
 		jamendo-loading.ui			\
 		jamendo-prefs.ui			\
@@ -22,7 +26,6 @@ context = places
 icondir = $(themedir)/$(size)/$(context)
 icon_DATA = icons/hicolor/$(size)/$(context)/jamendo.png
 
-gtkbuilderdir = $(plugindir)
 EXTRA_DIST = $(plugin_in_files) $(gtkbuilder_DATA) $(icon_DATA)
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
diff --git a/plugins/jamendo/jamendo-prefs.ui b/plugins/jamendo/jamendo-prefs.ui
index 32aeebc..35599e7 100644
--- a/plugins/jamendo/jamendo-prefs.ui
+++ b/plugins/jamendo/jamendo-prefs.ui
@@ -1,8 +1,10 @@
 <?xml version="1.0"?>
-<!--*- mode: xml -*-->
 <interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkListStore" id="model1">
     <columns>
+      <!-- column-name gchararray -->
       <column type="gchararray"/>
     </columns>
     <data>
@@ -14,211 +16,106 @@
       </row>
     </data>
   </object>
-  <object class="GtkDialog" id="preferences_dialog">
+  <object class="GtkVBox" id="config">
     <property name="visible">True</property>
-    <property name="title" translatable="yes">Jamendo Preferences</property>
-    <property name="type">GTK_WINDOW_TOPLEVEL</property>
-    <property name="window_position">GTK_WIN_POS_NONE</property>
-    <property name="modal">False</property>
-    <property name="resizable">True</property>
-    <property name="destroy_with_parent">False</property>
-    <property name="decorated">True</property>
-    <property name="skip_taskbar_hint">False</property>
-    <property name="skip_pager_hint">False</property>
-    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-    <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-    <property name="focus_on_map">True</property>
-    <property name="urgency_hint">False</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+    <property name="border_width">5</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">18</property>
+    <child>
+      <object class="GtkImage" id="image1">
         <property name="visible">True</property>
-        <property name="homogeneous">False</property>
-        <property name="spacing">0</property>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
+        <property name="pixbuf">jamendo_logo_medium.png</property>
+      </object>
+      <packing>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label58">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">&lt;b&gt;Download&lt;/b&gt;</property>
+        <property name="use_markup">True</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkHBox" id="hbox21">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkLabel" id="audio_label">
             <property name="visible">True</property>
-            <property name="layout_style">GTK_BUTTONBOX_END</property>
-            <child>
-              <object class="GtkButton" id="closebutton1">
-                <property name="visible">True</property>
-                <property name="can_default">True</property>
-                <property name="can_focus">True</property>
-                <property name="label">gtk-close</property>
-                <property name="use_stock">True</property>
-                <property name="relief">GTK_RELIEF_NORMAL</property>
-                <property name="focus_on_click">True</property>
-              </object>
-            </child>
+            <property name="xpad">8</property>
+            <property name="label" translatable="yes">_Format:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">audio_combobox</property>
           </object>
           <packing>
-            <property name="padding">0</property>
             <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="pack_type">GTK_PACK_END</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkVBox" id="jamendo_vbox">
-            <property name="border_width">5</property>
+          <object class="GtkComboBox" id="audio_combobox">
             <property name="visible">True</property>
-            <property name="homogeneous">False</property>
-            <property name="spacing">18</property>
+            <property name="model">model1</property>
             <child>
-              <object class="GtkImage" id="image1">
-                <property name="visible">True</property>
-                <property name="pixbuf">jamendo_logo_medium.png</property>
-                <property name="xalign">0.5</property>
-                <property name="yalign">0.5</property>
-                <property name="xpad">0</property>
-                <property name="ypad">0</property>
-              </object>
-              <packing>
-                <property name="padding">0</property>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label58">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">&lt;b&gt;Download&lt;/b&gt;</property>
-                <property name="use_underline">False</property>
-                <property name="use_markup">True</property>
-                <property name="justify">GTK_JUSTIFY_LEFT</property>
-                <property name="wrap">False</property>
-                <property name="selectable">False</property>
-                <property name="xalign">0</property>
-                <property name="yalign">0.5</property>
-                <property name="xpad">0</property>
-                <property name="ypad">0</property>
-                <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-                <property name="width_chars">-1</property>
-                <property name="single_line_mode">False</property>
-                <property name="angle">0</property>
-              </object>
-              <packing>
-                <property name="padding">0</property>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkHBox" id="hbox21">
-                <property name="visible">True</property>
-                <property name="homogeneous">False</property>
-                <property name="spacing">0</property>
-                <child>
-                  <object class="GtkLabel" id="audio_label">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Format:</property>
-                    <property name="use_underline">True</property>
-                    <property name="use_markup">False</property>
-                    <property name="justify">GTK_JUSTIFY_LEFT</property>
-                    <property name="wrap">False</property>
-                    <property name="selectable">False</property>
-                    <property name="xalign">0.5</property>
-                    <property name="yalign">0.5</property>
-                    <property name="xpad">8</property>
-                    <property name="ypad">0</property>
-                    <property name="mnemonic_widget">audio_combobox</property>
-                    <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-                    <property name="width_chars">-1</property>
-                    <property name="single_line_mode">False</property>
-                    <property name="angle">0</property>
-                  </object>
-                  <packing>
-                    <property name="padding">0</property>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBox" id="audio_combobox">
-                    <property name="visible">True</property>
-                    <property name="add_tearoffs">False</property>
-                    <property name="focus_on_click">True</property>
-                    <property name="model">model1</property>
-                    <child>
-                      <object class="GtkCellRendererText" id="renderer1"/>
-                      <attributes>
-                        <attribute name="text">0</attribute>
-                      </attributes>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="padding">0</property>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="padding">0</property>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkHBox" id="hbox23">
-                <property name="visible">True</property>
-                <property name="homogeneous">False</property>
-                <property name="spacing">0</property>
-                <child>
-                  <object class="GtkLabel" id="label57">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">Visit Jamendo at </property>
-                    <property name="use_underline">False</property>
-                    <property name="use_markup">False</property>
-                    <property name="justify">GTK_JUSTIFY_LEFT</property>
-                    <property name="wrap">False</property>
-                    <property name="selectable">False</property>
-                    <property name="xalign">0.5</property>
-                    <property name="yalign">0.5</property>
-                    <property name="xpad">0</property>
-                    <property name="ypad">0</property>
-                    <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-                    <property name="width_chars">-1</property>
-                    <property name="single_line_mode">False</property>
-                    <property name="angle">0</property>
-                  </object>
-                  <packing>
-                    <property name="padding">0</property>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLinkButton" id="href1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="uri">http://www.jamendo.com/</property>
-                    <property name="label" translatable="yes">http://www.jamendo.com/</property>
-                    <property name="focus_on_click">True</property>
-                  </object>
-                  <packing>
-                    <property name="padding">0</property>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="padding">0</property>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-              </packing>
+              <object class="GtkCellRendererText" id="renderer1"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
             </child>
           </object>
           <packing>
-            <property name="padding">0</property>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkHBox" id="hbox23">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkLabel" id="label57">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Visit Jamendo at </property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLinkButton" id="href1">
+            <property name="label" translatable="yes">http://www.jamendo.com/</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="relief">none</property>
+            <property name="uri">http://www.jamendo.com/</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
+      <packing>
+        <property name="position">3</property>
+      </packing>
     </child>
-    <action-widgets>
-      <action-widget response="-7">closebutton1</action-widget>
-    </action-widgets>
   </object>
 </interface>
diff --git a/plugins/jamendo/jamendo.rb-plugin.in b/plugins/jamendo/jamendo.plugin.in
similarity index 89%
rename from plugins/jamendo/jamendo.rb-plugin.in
rename to plugins/jamendo/jamendo.plugin.in
index 3b967bf..0c4004c 100644
--- a/plugins/jamendo/jamendo.rb-plugin.in
+++ b/plugins/jamendo/jamendo.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=jamendo
-IAge=1
+IAge=2
+Depends=rb
 _Name=Jamendo
 _Description=Adds support to Rhythmbox for playing and downloading albums from Jamendo
 Authors=Guillaume Desmottes
diff --git a/plugins/jamendo/jamendo/__init__.py b/plugins/jamendo/jamendo.py
similarity index 82%
rename from plugins/jamendo/jamendo/__init__.py
rename to plugins/jamendo/jamendo.py
index 318392d..dc1a4d2 100644
--- a/plugins/jamendo/jamendo/__init__.py
+++ b/plugins/jamendo/jamendo.py
@@ -35,7 +35,7 @@ from JamendoSource import JamendoSource
 from JamendoConfigureDialog import JamendoConfigureDialog
 
 import rb
-from gi.repository import Gtk
+from gi.repository import Gtk, Gio, Peas
 from gi.repository import RB
 
 popup_ui = """
@@ -64,16 +64,17 @@ class JamendoEntryType(RB.RhythmDBEntryType):
 	def do_sync_metadata(self, entry, changes):
 		return
 
-class Jamendo(RB.Plugin):
+class Jamendo(gobject.GObject, Peas.Activatable):
+	__gtype_name__ = 'Jamendo'
+	object = gobject.property(type=gobject.GObject)
+
 	#
 	# Core methods
 	#
 
-	def __init__(self):
-		RB.Plugin.__init__(self)
-
-	def activate(self, shell):
-		self.db = shell.get_property("db")
+	def do_activate(self):
+		shell = self.object
+		self.db = shell.props.db
 
 		self.entry_type = JamendoEntryType()
 		self.db.register_entry_type(self.entry_type)
@@ -85,20 +86,22 @@ class Jamendo(RB.Plugin):
 		icon = rb.try_load_icon(theme, "jamendo", width, 0)
 
 		group = RB.DisplayPageGroup.get_by_id ("stores")
+		settings = Gio.Settings("org.gnome.rhythmbox.plugins.jamendo")
 		self.source = gobject.new (JamendoSource,
 					   shell=shell,
 					   entry_type=self.entry_type,
 					   plugin=self,
-					   pixbuf=icon)
+					   pixbuf=icon,
+					   settings=settings.get_child("source"))
 		shell.register_entry_type_for_source(self.source, self.entry_type)
 		shell.append_display_page(self.source, group)
 
 		# Add button
-		manager = shell.get_player().get_property('ui-manager')
+		manager = shell.props.ui_manager
 		action = Gtk.Action(name='JamendoDownloadAlbum', label=_('_Download Album'),
 				tooltip=_("Download this album using BitTorrent"),
 				stock_id='gtk-save')
-		action.connect('activate', lambda a: shell.get_property("selected-page").download_album())
+		action.connect('activate', lambda a: shell.props.selected_page.download_album())
 		self.action_group = Gtk.ActionGroup('JamendoPluginActions')
 		self.action_group.add_action(action)
 		
@@ -106,22 +109,23 @@ class Jamendo(RB.Plugin):
 		action = Gtk.Action(name='JamendoDonateArtist', label=_('_Donate to Artist'),
 				tooltip=_("Donate Money to this Artist"),
 				stock_id='gtk-jump-to')
-		action.connect('activate', lambda a: shell.get_property("selected-page").launch_donate())
+		action.connect('activate', lambda a: shell.props.selected_page.launch_donate())
 		self.action_group.add_action(action)
 
 		manager.insert_action_group(self.action_group, 0)
 		self.ui_id = manager.add_ui_from_string(popup_ui)
 		manager.ensure_update()
 
-		self.pec_id = shell.get_player().connect('playing-song-changed', self.playing_entry_changed)
+		self.pec_id = shell.props.shell_player.connect('playing-song-changed', self.playing_entry_changed)
 
-	def deactivate(self, shell):
-		manager = shell.get_player().get_property('ui-manager')
+	def do_deactivate(self):
+		shell = self.object
+		manager = shell.props.ui_manager
 		manager.remove_ui (self.ui_id)
 		manager.remove_action_group(self.action_group)
 		self.action_group = None
 
-		shell.get_player().disconnect (self.pec_id)
+		shell.props.shell_player.disconnect (self.pec_id)
 
 		self.db.entry_delete_by_type(self.entry_type)
 		self.db.commit()
@@ -131,12 +135,5 @@ class Jamendo(RB.Plugin):
 		self.source.delete_thyself()
 		self.source = None
 
-	def create_configure_dialog(self, dialog=None):
-		if not dialog:
-			builder_file = self.find_file("jamendo-prefs.ui")
-			dialog = JamendoConfigureDialog (builder_file).get_dialog()
-		dialog.present()
-		return dialog
-
 	def playing_entry_changed (self, sp, entry):
 		self.source.playing_entry_changed (entry)
diff --git a/plugins/lirc/Makefile.am b/plugins/lirc/Makefile.am
index 1906e09..7c060cb 100644
--- a/plugins/lirc/Makefile.am
+++ b/plugins/lirc/Makefile.am
@@ -1,4 +1,5 @@
 plugindir = $(PLUGINDIR)/rblirc
+plugindatadir = $(PLUGINDATADIR)/rblirc
 plugin_LTLIBRARIES = librblirc.la
 
 librblirc_la_SOURCES = \
@@ -9,7 +10,7 @@ librblirc_la_LIBTOOLFLAGS = --tag=disable-static
 
 librblirc_la_LIBADD = $(top_builddir)/shell/librhythmbox-core.la
 
-configdir = $(PLUGINDIR)/rblirc
+configdir = $(plugindatadir)
 config_DATA = rhythmbox_lirc_default
 
 INCLUDES = 						\
@@ -18,12 +19,9 @@ INCLUDES = 						\
 	-I$(top_srcdir) 				\
 	-I$(top_srcdir)/lib                        	\
 	-I$(top_srcdir)/metadata                       	\
-	-I$(top_srcdir)/player                       	\
 	-I$(top_srcdir)/rhythmdb                       	\
 	-I$(top_srcdir)/widgets                    	\
-	-I$(top_srcdir)/sources                    	\
 	-I$(top_srcdir)/iradio                    	\
-	-I$(top_srcdir)/podcast                    	\
 	-I$(top_srcdir)/plugins				\
 	-I$(top_srcdir)/shell				\
 	-DPIXMAP_DIR=\""$(datadir)/pixmaps"\"		\
@@ -32,14 +30,13 @@ INCLUDES = 						\
 	$(RHYTHMBOX_CFLAGS)				\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = lirc.rb-plugin.in
+plugin_in_files = lirc.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files) $(config_DATA)
 
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
-
diff --git a/plugins/lirc/lirc.rb-plugin.in b/plugins/lirc/lirc.plugin.in
similarity index 91%
rename from plugins/lirc/lirc.rb-plugin.in
rename to plugins/lirc/lirc.plugin.in
index 8db87c5..1a12782 100644
--- a/plugins/lirc/lirc.rb-plugin.in
+++ b/plugins/lirc/lirc.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=rblirc
-IAge=1
+IAge=2
 _Name=LIRC 
 _Description=Control Rhythmbox using an infrared remote control
 Authors=Jonathan Matthew <jonathan d14n org>
diff --git a/plugins/lirc/rb-lirc-plugin.c b/plugins/lirc/rb-lirc-plugin.c
index c506e4a..fc27c98 100644
--- a/plugins/lirc/rb-lirc-plugin.c
+++ b/plugins/lirc/rb-lirc-plugin.c
@@ -39,11 +39,12 @@
 #include <gmodule.h>
 #include <lirc/lirc_client.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-shell.h"
 #include "rb-debug.h"
 #include "rb-util.h"
 #include "rb-shell-player.h"
+#include "rb-file-helpers.h"
 
 #define RB_TYPE_LIRC_PLUGIN		(rb_lirc_plugin_get_type ())
 #define RB_LIRC_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_LIRC_PLUGIN, RBLircPlugin))
@@ -69,8 +70,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
-	RBShell *shell;
+	PeasExtensionBase parent;
 	RBShellPlayer *shell_player;
 	struct lirc_config *lirc_config;
 	GIOChannel *lirc_channel;
@@ -78,25 +78,14 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBLircPluginClass;
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_lirc_plugin_get_type		(void) G_GNUC_CONST;
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void rb_lirc_plugin_init (RBLircPlugin *plugin);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
-
-RB_PLUGIN_REGISTER(RBLircPlugin, rb_lirc_plugin)
 
-static void
-rb_lirc_plugin_class_init (RBLircPluginClass *klass)
-{
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-}
+RB_DEFINE_PLUGIN (RB_TYPE_LIRC_PLUGIN, RBLircPlugin, rb_lirc_plugin,)
 
 static void
 rb_lirc_plugin_init (RBLircPlugin *plugin)
@@ -176,7 +165,11 @@ rb_lirc_plugin_read_code (GIOChannel *source,
 				rb_shell_player_set_mute (plugin->shell_player, !mute, NULL);
 			}
 		} else if (strcmp (str,RB_IR_COMMAND_QUIT) == 0) {
-			rb_shell_quit (plugin->shell, NULL);
+			RBShell *shell;
+
+			g_object_get (plugin, "object", &shell, NULL);
+			rb_shell_quit (shell, NULL);
+			g_object_unref (shell);
 			/* the plugin will have been deactivated, so we can't continue the loop */
 			break;
 		}
@@ -188,31 +181,33 @@ rb_lirc_plugin_read_code (GIOChannel *source,
 }
 
 static void
-impl_activate (RBPlugin *rbplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	int fd;
 	char *path;
-	RBLircPlugin *plugin = RB_LIRC_PLUGIN (rbplugin);
+	RBLircPlugin *plugin = RB_LIRC_PLUGIN (bplugin);
+	RBShell *shell;
 
-	plugin->shell = g_object_ref (shell);
+	g_object_get (plugin, "object", &shell, NULL);
 
-	g_object_get (G_OBJECT (shell), "shell-player", &plugin->shell_player, NULL);
+	g_object_get (shell, "shell-player", &plugin->shell_player, NULL);
 
 	rb_debug ("Activating lirc plugin");
 
 	fd = lirc_init ("Rhythmbox", 1);
 	if (fd < 0) {
 		rb_debug ("Couldn't initialize lirc");
+		g_object_unref (shell);
 		return;
 	}
 
 	/* Load the default Rhythmbox setup */
-	path = rb_plugin_find_file (rbplugin, "rhythmbox_lirc_default");
+	path = rb_find_plugin_data_file (G_OBJECT (plugin), "rhythmbox_lirc_default");
 	if (path == NULL || lirc_readconfig (path, &plugin->lirc_config, NULL) == -1) {
 		g_free (path);
 		close (fd);
 		rb_debug ("Couldn't read lirc configuration");
+		g_object_unref (shell);
 		return;
 	}
 	g_free (path);
@@ -224,13 +219,14 @@ impl_activate (RBPlugin *rbplugin,
 	g_io_channel_set_buffered (plugin->lirc_channel, FALSE);
 	g_io_add_watch (plugin->lirc_channel, G_IO_IN | G_IO_ERR | G_IO_HUP,
 			(GIOFunc) rb_lirc_plugin_read_code, plugin);
+
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *rbplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
-	RBLircPlugin *plugin = RB_LIRC_PLUGIN (rbplugin);
+	RBLircPlugin *plugin = RB_LIRC_PLUGIN (bplugin);
 	GError *error = NULL;
 
 	rb_debug ("Deactivating lirc plugin");
@@ -256,10 +252,13 @@ impl_deactivate	(RBPlugin *rbplugin,
 		g_object_unref (G_OBJECT (plugin->shell_player));
 		plugin->shell_player = NULL;
 	}
-
-	if (plugin->shell) {
-		g_object_unref (G_OBJECT (plugin->shell));
-		plugin->shell = NULL;
-	}
 }
 
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_lirc_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_LIRC_PLUGIN);
+}
diff --git a/plugins/lyrics/lyrics/AstrawebParser.py b/plugins/lyrics/AstrawebParser.py
similarity index 96%
rename from plugins/lyrics/lyrics/AstrawebParser.py
rename to plugins/lyrics/AstrawebParser.py
index d14f56e..c94c1bf 100644
--- a/plugins/lyrics/lyrics/AstrawebParser.py
+++ b/plugins/lyrics/AstrawebParser.py
@@ -29,8 +29,6 @@ import urllib
 import re
 import rb
 
-from rb.stringmatch import string_match
-
 # these numbers pulled directly from the air
 artist_match = 0.8
 title_match = 0.5
@@ -67,11 +65,11 @@ class AstrawebParser (object):
 				title = re.split('(\/display[^>]*)([^<]*)', entry)[2][1:].strip()
 
 				if self.artist != "":
-					artist_str = string_match(self.artist, artist)
+					artist_str = rb.string_match(self.artist, artist)
 				else:
 					artist_str = artist_match + 0.1
 
-				title_str = string_match(self.title, title)
+				title_str = rb.string_match(self.title, title)
 
 				print "checking [%s,%s]: match strengths [%f,%f]" % (title.strip(), artist.strip(), title_str, artist_str)
 				if title_str > title_match and artist_str > artist_match:
diff --git a/plugins/lyrics/lyrics/DarkLyricsParser.py b/plugins/lyrics/DarkLyricsParser.py
similarity index 97%
rename from plugins/lyrics/lyrics/DarkLyricsParser.py
rename to plugins/lyrics/DarkLyricsParser.py
index 7370ece..9621e03 100644
--- a/plugins/lyrics/lyrics/DarkLyricsParser.py
+++ b/plugins/lyrics/DarkLyricsParser.py
@@ -30,7 +30,6 @@ import rb
 
 min_artist_match = .5
 min_song_match = .5
-from rb.stringmatch import string_match
 
 class DarkLyricsParser (object):
 	"""Parser for Lyrics from www.darklyrics.com"""
@@ -75,7 +74,7 @@ class DarkLyricsParser (object):
 			if artist_link[:5] == 'http:':
 				continue
 			artist_name = artist_name.strip()
-			smvalue = string_match (artist_name, self.artist_ascii)
+			smvalue = rb.string_match (artist_name, self.artist_ascii)
 			if smvalue > min_artist_match:
 				best_match = (smvalue, artist_url, artist_name)
 
@@ -119,7 +118,7 @@ class DarkLyricsParser (object):
 		best_match = ""
 		for line in matches:
 			artist, album, number, title = line
-			smvalue = string_match (title.lower().replace(' ', '' ),
+			smvalue = rb.string_match (title.lower().replace(' ', '' ),
 					   self.title.lower().replace(' ', ''))
 			if smvalue > min_song_match:
 				best_match  = self.SongFound(smvalue,
diff --git a/plugins/lyrics/lyrics/LeoslyricsParser.py b/plugins/lyrics/LeoslyricsParser.py
similarity index 95%
rename from plugins/lyrics/lyrics/LeoslyricsParser.py
rename to plugins/lyrics/LeoslyricsParser.py
index 8a9d74e..dccd3ab 100644
--- a/plugins/lyrics/lyrics/LeoslyricsParser.py
+++ b/plugins/lyrics/LeoslyricsParser.py
@@ -31,8 +31,6 @@ import urllib
 import re
 import rb
 
-from rb.stringmatch import string_match
-
 # these numbers pulled directly from the air
 artist_match = 0.8
 title_match = 0.5
@@ -79,11 +77,11 @@ class LeoslyricsParser(object):
 
 			# if we don't know the artist, then anyone will do
 			if self.artist != "":
-				artist_str = string_match(self.artist, matchartist)
+				artist_str = rb.string_match(self.artist, matchartist)
 			else:
 				artist_str = artist_match + 0.1
 
-			title_str = string_match(self.title, matchtitle)
+			title_str = rb.string_match(self.title, matchtitle)
 			if artist_str > artist_match and title_str > title_match:
 				print "found acceptable match, artist: %s (%f), title: %s (%f)" % (matchartist, artist_str, matchtitle, title_str)
 				match = m
diff --git a/plugins/lyrics/lyrics/LyrcParser.py b/plugins/lyrics/LyrcParser.py
similarity index 100%
rename from plugins/lyrics/lyrics/LyrcParser.py
rename to plugins/lyrics/LyrcParser.py
diff --git a/plugins/lyrics/lyrics/LyricWikiParser.py b/plugins/lyrics/LyricWikiParser.py
similarity index 100%
rename from plugins/lyrics/lyrics/LyricWikiParser.py
rename to plugins/lyrics/LyricWikiParser.py
diff --git a/plugins/lyrics/lyrics/LyricsConfigureDialog.py b/plugins/lyrics/LyricsConfigureDialog.py
similarity index 85%
rename from plugins/lyrics/lyrics/LyricsConfigureDialog.py
rename to plugins/lyrics/LyricsConfigureDialog.py
index fcf1274..f4bc5a7 100644
--- a/plugins/lyrics/lyrics/LyricsConfigureDialog.py
+++ b/plugins/lyrics/LyricsConfigureDialog.py
@@ -31,22 +31,26 @@ import gobject
 from os import system, path
 
 import rb
-from gi.repository import Gtk, Gio
+from gi.repository import Gtk, Gio, GObject, PeasGtk
 
-class LyricsConfigureDialog (object):
-	def __init__(self, builder_file):
+class LyricsConfigureDialog (GObject.Object, PeasGtk.Configurable):
+	__gtype_name__ = 'LyricsConfigureDialog'
+	object = GObject.property(type=GObject.Object)
+
+	def __init__(self):
+		GObject.Object.__init__(self)
 		self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.lyrics")
 
+	def do_create_configure_widget(self):
 		builder = Gtk.Builder()
-		builder.add_from_file(builder_file)
+		builder.add_from_file(rb.find_plugin_file(self, "lyrics-prefs.ui"))
 
-		self.dialog = builder.get_object("preferences_dialog")
+		self.config = builder.get_object("config")
 
 		self.choose_button = builder.get_object("choose_button")
 		self.path_display = builder.get_object("path_display")
 
 		self.choose_button.connect("clicked", self.choose_callback)
-		self.dialog.connect("response", self.dialog_response)
 
 		engines, self.folder = self.get_prefs()
 		if self.folder is None:
@@ -65,15 +69,7 @@ class LyricsConfigureDialog (object):
 
 		site_box.show_all()
 
-	def dialog_response(self, dialog, response):
-		if response == Gtk.ResponseType.OK:
-			self.set_values()
-			self.dialog.hide()
-		elif response == Gtk.ResponseType.CANCEL or response == Gtk.ResponseType.DELETE_EVENT:
-			self.dialog.hide()
-		else:
-			print "unexpected response type"
-
+		return self.config
 
 	def set_values(self):
 		sites = []
@@ -111,9 +107,6 @@ class LyricsConfigureDialog (object):
 		self.chooser.set_transient_for(self.dialog)
 		self.chooser.present()
 
-	def get_dialog (self):
-		return self.dialog
-	
 	def get_prefs (self):
 		try:
 			sites = self.settings['sites']
diff --git a/plugins/lyrics/lyrics/LyricsParse.py b/plugins/lyrics/LyricsParse.py
similarity index 100%
rename from plugins/lyrics/lyrics/LyricsParse.py
rename to plugins/lyrics/LyricsParse.py
diff --git a/plugins/lyrics/lyrics/LyricsSites.py b/plugins/lyrics/LyricsSites.py
similarity index 100%
rename from plugins/lyrics/lyrics/LyricsSites.py
rename to plugins/lyrics/LyricsSites.py
diff --git a/plugins/lyrics/Makefile.am b/plugins/lyrics/Makefile.am
index 5a6f824..4c0b3c3 100644
--- a/plugins/lyrics/Makefile.am
+++ b/plugins/lyrics/Makefile.am
@@ -1,20 +1,28 @@
 # Search Lyrics Python Plugin
 
-SUBDIRS = lyrics
-
 plugindir = $(PLUGINDIR)/lyrics
-
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
-
-
-plugin_in_files = lyrics.rb-plugin.in
-
+plugin_PYTHON =				\
+       LyricsParse.py			\
+       LyricsSites.py			\
+       LyricsConfigureDialog.py		\
+       lyrics.py			\
+       LyrcParser.py			\
+       AstrawebParser.py		\
+       LeoslyricsParser.py		\
+       LyricWikiParser.py		\
+       WinampcnParser.py		\
+       TerraParser.py			\
+       DarkLyricsParser.py
+
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+
+plugin_in_files = lyrics.plugin.in
+
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA =	\
 		lyrics-prefs.ui
 
-gtkbuilderdir = $(plugindir)
 EXTRA_DIST = $(plugin_in_files) $(gtkbuilder_DATA)
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
-
diff --git a/plugins/lyrics/lyrics/TerraParser.py b/plugins/lyrics/TerraParser.py
similarity index 100%
rename from plugins/lyrics/lyrics/TerraParser.py
rename to plugins/lyrics/TerraParser.py
diff --git a/plugins/lyrics/lyrics/WinampcnParser.py b/plugins/lyrics/WinampcnParser.py
similarity index 100%
rename from plugins/lyrics/lyrics/WinampcnParser.py
rename to plugins/lyrics/WinampcnParser.py
diff --git a/plugins/lyrics/lyrics-prefs.ui b/plugins/lyrics/lyrics-prefs.ui
index b1f8493..729e174 100644
--- a/plugins/lyrics/lyrics-prefs.ui
+++ b/plugins/lyrics/lyrics-prefs.ui
@@ -2,197 +2,136 @@
 <interface>
   <!-- interface-requires gtk+ 2.12 -->
   <!-- interface-naming-policy toplevel-contextual -->
-  <object class="GtkDialog" id="preferences_dialog">
+  <object class="GtkVBox" id="config">
     <property name="visible">True</property>
-    <property name="title" translatable="yes">Lyrics Plugin Preferences</property>
-    <property name="type_hint">dialog</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+    <property name="border_width">5</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">10</property>
+    <child>
+      <object class="GtkFrame" id="frame1">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
+        <property name="label_xalign">0</property>
+        <property name="shadow_type">none</property>
         <child>
-          <object class="GtkVBox" id="lyrics_vbox">
+          <object class="GtkAlignment" id="alignment1">
             <property name="visible">True</property>
-            <property name="border_width">5</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">10</property>
+            <property name="left_padding">12</property>
             <child>
-              <object class="GtkFrame" id="frame1">
+              <object class="GtkVBox" id="sites">
                 <property name="visible">True</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkAlignment" id="alignment1">
-                    <property name="visible">True</property>
-                    <property name="left_padding">12</property>
-                    <child>
-                      <object class="GtkVBox" id="sites">
-                        <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
-                        <property name="spacing">6</property>
-                        <child>
-                          <placeholder/>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label58">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label" translatable="yes">&lt;b&gt;Search engines&lt;/b&gt;</property>
-                    <property name="use_markup">True</property>
-                  </object>
+                  <placeholder/>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
             </child>
+          </object>
+        </child>
+        <child type="label">
+          <object class="GtkLabel" id="label58">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">&lt;b&gt;Search engines&lt;/b&gt;</property>
+            <property name="use_markup">True</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkFrame" id="frame2">
+        <property name="visible">True</property>
+        <property name="label_xalign">0</property>
+        <property name="shadow_type">none</property>
+        <child>
+          <object class="GtkAlignment" id="alignment2">
+            <property name="visible">True</property>
+            <property name="left_padding">12</property>
             <child>
-              <object class="GtkFrame" id="frame2">
+              <object class="GtkHBox" id="hbox23">
                 <property name="visible">True</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkEntry" id="path_display">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
                 <child>
-                  <object class="GtkAlignment" id="alignment2">
+                  <object class="GtkButton" id="choose_button">
                     <property name="visible">True</property>
-                    <property name="left_padding">12</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
                     <child>
-                      <object class="GtkHBox" id="hbox23">
+                      <object class="GtkAlignment" id="alignment3">
                         <property name="visible">True</property>
-                        <property name="spacing">6</property>
+                        <property name="xscale">0</property>
+                        <property name="yscale">0</property>
                         <child>
-                          <object class="GtkEntry" id="path_display">
+                          <object class="GtkHBox" id="hbox24">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                          </object>
-                          <packing>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkButton" id="choose_button">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
+                            <property name="spacing">2</property>
+                            <child>
+                              <object class="GtkImage" id="image1">
+                                <property name="visible">True</property>
+                                <property name="stock">gtk-open</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
                             <child>
-                              <object class="GtkAlignment" id="alignment3">
+                              <object class="GtkLabel" id="label60">
                                 <property name="visible">True</property>
-                                <property name="xscale">0</property>
-                                <property name="yscale">0</property>
-                                <child>
-                                  <object class="GtkHBox" id="hbox24">
-                                    <property name="visible">True</property>
-                                    <property name="spacing">2</property>
-                                    <child>
-                                      <object class="GtkImage" id="image1">
-                                        <property name="visible">True</property>
-                                        <property name="stock">gtk-open</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkLabel" id="label60">
-                                        <property name="visible">True</property>
-                                        <property name="label" translatable="yes">Browse...</property>
-                                        <property name="use_underline">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                </child>
+                                <property name="label" translatable="yes">Browse...</property>
+                                <property name="use_underline">True</property>
                               </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
                             </child>
                           </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </object>
                     </child>
                   </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label59">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label" translatable="yes">&lt;b&gt;Lyrics Folder&lt;/b&gt;</property>
-                    <property name="use_markup">True</property>
-                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
         </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
+        <child type="label">
+          <object class="GtkLabel" id="label59">
             <property name="visible">True</property>
-            <property name="layout_style">edge</property>
-            <child>
-              <object class="GtkButton" id="cancel_button">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="ok_button">
-                <property name="label">gtk-ok</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">&lt;b&gt;Lyrics Folder&lt;/b&gt;</property>
+            <property name="use_markup">True</property>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
         </child>
       </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">1</property>
+      </packing>
     </child>
-    <action-widgets>
-      <action-widget response="-6">cancel_button</action-widget>
-      <action-widget response="-5">ok_button</action-widget>
-    </action-widgets>
   </object>
 </interface>
diff --git a/plugins/lyrics/lyrics.rb-plugin.in b/plugins/lyrics/lyrics.plugin.in
similarity index 90%
rename from plugins/lyrics/lyrics.rb-plugin.in
rename to plugins/lyrics/lyrics.plugin.in
index 7b5d746..d7a2577 100644
--- a/plugins/lyrics/lyrics.rb-plugin.in
+++ b/plugins/lyrics/lyrics.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=lyrics
-IAge=1
+IAge=2
+Depends=rb
 _Name=Song Lyrics
 _Description=Fetch song lyrics from the Internet
 Authors=Jonathan Matthew, Eduardo Gonzalez, Sirio Bolaños
diff --git a/plugins/lyrics/lyrics/__init__.py b/plugins/lyrics/lyrics.py
similarity index 94%
rename from plugins/lyrics/lyrics/__init__.py
rename to plugins/lyrics/lyrics.py
index 99bbb48..9d427eb 100644
--- a/plugins/lyrics/lyrics/__init__.py
+++ b/plugins/lyrics/lyrics.py
@@ -29,7 +29,7 @@
 import os, re
 
 import rb
-from gi.repository import Gtk, Gio
+from gi.repository import Gtk, Gio, GObject, Peas
 from gi.repository import RB
 
 import LyricsParse
@@ -177,7 +177,7 @@ class LyricPane(object):
 	def __init__(self, db, song_info):
 		self.db = db
 		self.song_info = song_info
-		self.entry = self.song_info.get_property("current-entry")
+		self.entry = self.song_info.props.current_entry
 		
 		self.build_path()
 		
@@ -256,7 +256,7 @@ class LyricPane(object):
 		self.cache_path = cache_path
 
 	def entry_changed(self, pspec, duh):
-		self.entry = self.song_info.get_property("current-entry")
+		self.entry = self.song_info.props.current_entry
 		self.have_lyrics = 0
 		if self.visible != 0:
 			self.build_path()
@@ -302,7 +302,7 @@ class LyricWindow (Gtk.Window):
 		bbox.pack_start(close, True, True, 0)
 		lyrics_view.pack_start(bbox, False, False, 0)
 
-		sp = shell.get_player ()
+		sp = shell.props.shell_player
 		self.ppc_id = sp.connect('playing-song-property-changed', self.playing_property_changed)
 	
 		self.add(lyrics_view)
@@ -310,7 +310,7 @@ class LyricWindow (Gtk.Window):
 		self.show_all()
 
 	def destroy(self):
-		sp = self.shell.get_player ()
+		sp = self.shell.props.shell_player
 		sp.disconnect (self.ppc_id)
 		Gtk.Window.destroy(self)
 
@@ -330,14 +330,16 @@ class LyricWindow (Gtk.Window):
 		lyrics_grabber.search_lyrics(self.__got_lyrics)
 
 
-class LyricsDisplayPlugin(RB.Plugin):
+class LyricsDisplayPlugin(GObject.Object, Peas.Activatable):
+	__gtype_name__ = 'LyricsDisplayPlugin'
+	object = GObject.property(type=GObject.Object)
 
 	def __init__ (self):
-		RB.Plugin.__init__ (self)
+		GObject.Object.__init__ (self)
 		self.window = None
 
-	def activate (self, shell):
-		self.shell = shell
+	def do_activate (self):
+		shell = self.object
 		self.action = Gtk.Action (name='ViewSongLyrics', label=_('Song L_yrics'),
 					  tooltip=_('Display lyrics for the playing song'),
 					  stock_id='rb-song-lyrics')
@@ -351,7 +353,7 @@ class LyricsDisplayPlugin(RB.Plugin):
 		self.ui_id = uim.add_ui_from_string (ui_str)
 		uim.ensure_update ()
 
-		sp = shell.get_player ()
+		sp = shell.props.shell_player
 		self.pec_id = sp.connect('playing-song-changed', self.playing_entry_changed)
 		self.playing_entry_changed (sp, sp.get_playing_entry ())
 
@@ -360,7 +362,8 @@ class LyricsDisplayPlugin(RB.Plugin):
 		db = shell.props.db
 		self.lyric_req_id = db.connect_after ('entry-extra-metadata-request::rb:lyrics', self.lyrics_request)
 
-	def deactivate (self, shell):
+	def do_deactivate (self):
+		shell = self.object
 			
 		uim = shell.get_ui_manager()
 		uim.remove_ui (self.ui_id)
@@ -369,7 +372,7 @@ class LyricsDisplayPlugin(RB.Plugin):
 		self.action_group = None
 		self.action = None
 
-		sp = self.shell.get_player ()
+		sp = shell.props.shell_player
 		sp.disconnect (self.pec_id)
 
 		shell.disconnect (self.csi_id)
@@ -380,12 +383,6 @@ class LyricsDisplayPlugin(RB.Plugin):
 			self.window.destroy ()
 			self.window = None
 
-	def create_configure_dialog(self):
-		builder_file = self.find_file("lyrics-prefs.ui")
-		dialog = LyricsConfigureDialog (builder_file).get_dialog()
-		dialog.present()
-		return dialog
-
 
 	def show_song_lyrics (self, action, shell):
 
@@ -393,7 +390,7 @@ class LyricsDisplayPlugin(RB.Plugin):
 			self.window.destroy ()
 			self.window = None
 
-		sp = shell.get_player ()
+		sp = shell.props.shell_player
 		entry = sp.get_playing_entry ()
 
 		if entry is not None:
@@ -415,7 +412,7 @@ class LyricsDisplayPlugin(RB.Plugin):
 	
 	def create_song_info (self, shell, song_info, is_multiple):
 		if is_multiple is False:
-			x = LyricPane(shell.get_property ("db"), song_info)
+			x = LyricPane(shell.props.db, song_info)
 
 	def lyrics_request (self, db, entry):
 		def lyrics_results(text):
diff --git a/plugins/magnatune/magnatune/BuyAlbumHandler.py b/plugins/magnatune/BuyAlbumHandler.py
similarity index 100%
rename from plugins/magnatune/magnatune/BuyAlbumHandler.py
rename to plugins/magnatune/BuyAlbumHandler.py
diff --git a/plugins/magnatune/magnatune/MagnatuneSource.py b/plugins/magnatune/MagnatuneSource.py
similarity index 87%
rename from plugins/magnatune/magnatune/MagnatuneSource.py
rename to plugins/magnatune/MagnatuneSource.py
index b183c6f..6a880a0 100644
--- a/plugins/magnatune/magnatune/MagnatuneSource.py
+++ b/plugins/magnatune/MagnatuneSource.py
@@ -26,7 +26,7 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
 import os
-import gobject, gio
+import gobject
 import xml
 import urllib
 import urlparse
@@ -45,26 +45,23 @@ from BuyAlbumHandler import BuyAlbumHandler, MagnatunePurchaseError
 magnatune_partner_id = "rhythmbox"
 
 # URIs
-magnatune_song_info_uri = gio.File(uri="http://magnatune.com/info/song_info_xml.zip";)
+magnatune_song_info_uri = Gio.file_new_for_uri("http://magnatune.com/info/song_info_xml.zip";)
 magnatune_buy_album_uri = "https://magnatune.com/buy/choose?";
 magnatune_api_download_uri = "http://%s:%s download magnatune com/buy/membership_free_dl_xml?"
 
-magnatune_in_progress_dir = gio.File(path=RB.user_data_dir()).resolve_relative_path('magnatune')
-magnatune_cache_dir = gio.File(path=RB.user_cache_dir()).resolve_relative_path('magnatune')
+magnatune_in_progress_dir = Gio.file_new_for_path(RB.user_data_dir()).resolve_relative_path('magnatune')
+magnatune_cache_dir = Gio.file_new_for_path(RB.user_cache_dir()).resolve_relative_path('magnatune')
 
 magnatune_song_info = os.path.join(magnatune_cache_dir.get_path(), 'song_info.xml')
 magnatune_song_info_temp = os.path.join(magnatune_cache_dir.get_path(), 'song_info.zip.tmp')
 
 
 class MagnatuneSource(RB.BrowserSource):
-	__gproperties__ = {
-		'plugin': (RB.Plugin, 'plugin', 'plugin', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
-	}
-
 	def __init__(self):
-		self.__settings = Gio.Settings("org.gnome.rhythmbox.plugins.magnatune")
-		RB.BrowserSource.__init__(self, name=_("Magnatune"), settings=self.__settings.get_child("source"))
+		RB.BrowserSource.__init__(self)
+		self.hate = self
 
+		self.__settings = Gio.Settings("org.gnome.rhythmbox.plugins.magnatune")
 		# source state
 		self.__activated = False
 		self.__db = None
@@ -86,14 +83,7 @@ class MagnatuneSource(RB.BrowserSource):
 
 		# album download stuff
 		self.__downloads = {} # keeps track of download progress for each file
-		self.__cancellables = {} # keeps track of gio.Cancellable objects so we can abort album downloads
-
-
-	def do_set_property(self, property, value):
-		if property.name == 'plugin':
-			self.__plugin = value
-		else:
-			raise AttributeError, 'unknown property %s' % property.name
+		self.__cancellables = {} # keeps track of Gio.Cancellable objects so we can abort album downloads
 
 	#
 	# RBSource methods
@@ -118,7 +108,7 @@ class MagnatuneSource(RB.BrowserSource):
 				progress = -1.0
 			return (_("Downloading Magnatune Album(s)"), None, progress)
 		else:
-			qm = self.get_property("query-model")
+			qm = self.props.query_model
 			return (qm.compute_status_normal("%d song", "%d songs"), None, 2.0)
 
 	def do_get_ui_actions(self):
@@ -128,12 +118,12 @@ class MagnatuneSource(RB.BrowserSource):
 
 	def do_selected(self):
 		if not self.__activated:
-			shell = self.get_property('shell')
-			self.__db = shell.get_property('db')
-			self.__entry_type = self.get_property('entry-type')
+			shell = self.props.shell
+			self.__db = shell.props.db
+			self.__entry_type = self.props.entry_type
 
 			# move files from old ~/.gnome2 paths
-			if not magnatune_in_progress_dir.query_exists():
+			if not magnatune_in_progress_dir.query_exists(None):
 				self.__move_data_files()
 
 			self.__activated = True
@@ -143,14 +133,6 @@ class MagnatuneSource(RB.BrowserSource):
 			self.__update_id = gobject.timeout_add_seconds(6 * 60 * 60, self.__update_catalogue)
 			self.__update_catalogue()
 
-			self.get_entry_view().set_sorting_type(self.__client.get_string("/apps/rhythmbox/plugins/magnatune/sorting"))
-
-	def do_impl_get_browser_key(self):
-		return "/apps/rhythmbox/plugins/magnatune/show_browser"
-
-	def do_impl_get_paned_key(self):
-		return "/apps/rhythmbox/plugins/magnatune/paned_position"
-
 	def do_impl_can_delete(self):
 		return False
 
@@ -177,8 +159,6 @@ class MagnatuneSource(RB.BrowserSource):
 			self.__catalogue_check.cancel()
 			self.__catalogue_check = None
 
-		self.__client.set_string("/apps/rhythmbox/plugins/magnatune/sorting", self.get_entry_view().get_sorting_type())
-
 		RB.BrowserSource.do_delete_thyself(self)
 
 	#
@@ -288,17 +268,17 @@ class MagnatuneSource(RB.BrowserSource):
 
 			self.__updating = True
 
-			dest = gio.File(magnatune_song_info_temp)
-			self.__catalogue_loader = gio.Cancellable()
+			dest = Gio.file_new_for_path(magnatune_song_info_temp)
+			self.__catalogue_loader = Gio.Cancellable()
 			try:
-				# For some reason, gio.FILE_COPY_OVERWRITE doesn't work for copy_async
+				# For some reason, Gio.FileCopyFlags.OVERWRITE doesn't work for copy_async
 				dest.delete()
 			except:
 				pass
 			magnatune_song_info_uri.copy_async(dest,
 			                                   download_finished,
 							   progress_callback=download_progress,
-							   flags=gio.FILE_COPY_OVERWRITE,
+							   flags=Gio.FileCopyFlags.OVERWRITE,
 							   cancellable=self.__catalogue_loader)
 
 		def load_catalogue():
@@ -347,7 +327,7 @@ class MagnatuneSource(RB.BrowserSource):
 							continue
 						uri = magnatune_in_progress_dir.resolve_relative_path(name).load_contents()[0]
 						print "restarting download from %s" % uri
-						self.__download_album(gio.File(uri=uri), name[12:])
+						self.__download_album(Gio.file_new_for_uri(uri), name[12:])
 				else:
 					# hack around some weird chars that show up in the catalogue for some reason
 					result = result.replace("\x19", "'")
@@ -384,7 +364,7 @@ class MagnatuneSource(RB.BrowserSource):
 		if self.__info_screen is None:
 			# load the builder stuff
 			builder = Gtk.Builder()
-			builder.add_from_file(self.__plugin.find_file("magnatune-loading.ui"))
+			builder.add_from_file(rb.find_plugin_file(self.props.plugin, "magnatune-loading.ui"))
 			self.__info_screen = builder.get_object("magnatune_loading_scrolledwindow")
 			self.pack_start(self.__info_screen, True, True, 0)
 			self.get_entry_view().set_no_show_all(True)
@@ -455,7 +435,7 @@ class MagnatuneSource(RB.BrowserSource):
 				authed = (parsed[0], netloc, path) + parsed[3:]
 				audio_dl_uri = urlparse.urlunparse(authed)
 
-				self.__download_album(gio.File(audio_dl_uri), sku)
+				self.__download_album(Gio.file_new_for_uri(audio_dl_uri), sku)
 
 			except MagnatunePurchaseError, e:
 				RB.error_dialog(title = _("Download Error"),
@@ -488,8 +468,8 @@ class MagnatuneSource(RB.BrowserSource):
 				remove_download_files()
 
 			if len(self.__downloads) == 0: # All downloads are complete
-				shell = self.get_property('shell')
-				manager = shell.get_player().get_property('ui-manager')
+				shell = self.props.shell
+				manager = shell.props.ui_manager
 				manager.get_action("/MagnatuneSourceViewPopup/MagnatuneCancelDownload").set_sensitive(False)
 				if success:
 					shell.notify_custom(4000, _("Finished Downloading"), _("All Magnatune downloads have been completed."))
@@ -499,7 +479,7 @@ class MagnatuneSource(RB.BrowserSource):
 		def unzip_album():
 			# just use the first library location
 			library = Gio.Settings("org.gnome.rhythmbox.rhythmdb")
-			library_location = gio.File(library['locations'][0])
+			library_location = Gio.file_new_for_uri(library['locations'][0])
 
 			album = zipfile.ZipFile(dest.get_path())
 			for track in album.namelist():
@@ -508,7 +488,7 @@ class MagnatuneSource(RB.BrowserSource):
 				track_uri = RB.sanitize_uri_for_filesystem(track_uri)
 				RB.uri_create_parent_dirs(track_uri)
 
-				track_out = gio.File(uri=track_uri).create()
+				track_out = Gio.file_new_for_uri(track_uri).create()
 				if track_out is not None:
 					track_out.write(album.read(track))
 					track_out.close()
@@ -526,18 +506,18 @@ class MagnatuneSource(RB.BrowserSource):
 		dest = magnatune_in_progress_dir.resolve_relative_path(sku)
 
 		str_uri = audio_dl_uri.get_uri()
-		in_progress.replace_contents(str_uri, None, False, flags=gio.FILE_CREATE_PRIVATE|gio.FILE_CREATE_REPLACE_DESTINATION)
+		in_progress.replace_contents(str_uri, None, False, flags=Gio.FileCreateFlags.PRIVATE|Gio.FileCreateFlags.REPLACE_DESTINATION)
 
-		shell = self.get_property('shell')
-		manager = shell.get_player().get_property('ui-manager')
+		shell = self.props.shell
+		manager = shell.props.ui_manager
 		manager.get_action("/MagnatuneSourceViewPopup/MagnatuneCancelDownload").set_sensitive(True)
 
 		self.__downloads[str_uri] = (0, 0) # (current, total)
 
-		cancel = gio.Cancellable()
+		cancel = Gio.Cancellable()
 		self.__cancellables[str_uri] = cancel
 		try:
-			# For some reason, gio.FILE_COPY_OVERWRITE doesn't work for copy_async
+			# For some reason, Gio.FileCopyFlags.OVERWRITE doesn't work for copy_async
 			dest.delete()
 		except:
 			pass
@@ -546,7 +526,7 @@ class MagnatuneSource(RB.BrowserSource):
 		audio_dl_uri.copy_async(dest,
 		                        download_finished,
 					progress_callback=download_progress,
-					flags=gio.FILE_COPY_OVERWRITE,
+					flags=Gio.FileCopyFlags.OVERWRITE,
 					cancellable=cancel)
 
 
@@ -554,8 +534,8 @@ class MagnatuneSource(RB.BrowserSource):
 		for cancel in self.__cancellables.values():
 			cancel.cancel()
 
-		shell = self.get_property('shell')
-		manager = shell.get_player().get_property('ui-manager')
+		shell = self.props.shell
+		manager = shell.props.ui_manager
 		manager.get_action("/MagnatuneSourceViewPopup/MagnatuneCancelDownload").set_sensitive(False)
 
 	def playing_entry_changed(self, entry):
diff --git a/plugins/magnatune/Makefile.am b/plugins/magnatune/Makefile.am
index 5c0445e..1fa6861 100644
--- a/plugins/magnatune/Makefile.am
+++ b/plugins/magnatune/Makefile.am
@@ -1,15 +1,19 @@
 # Magnatune Store Python Plugin
 
-SUBDIRS = magnatune
-
 plugindir = $(PLUGINDIR)/magnatune
+plugindatadir = $(PLUGINDATADIR)/magnatune
+plugin_PYTHON =                       \
+       MagnatuneSource.py             \
+       BuyAlbumHandler.py             \
+       TrackListHandler.py            \
+       magnatune.py
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
-
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
-plugin_in_files = magnatune.rb-plugin.in
+plugin_in_files = magnatune.plugin.in
 
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA =	\
 		magnatune-loading.ui			\
 		magnatune-prefs.ui			\
@@ -22,8 +26,6 @@ context = places
 icondir = $(themedir)/$(size)/$(context)
 icon_DATA = icons/hicolor/$(size)/$(context)/magnatune.png
 
-gtkbuilderdir = $(plugindir)
 EXTRA_DIST = $(plugin_in_files) $(gtkbuilder_DATA) $(icon_DATA)
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
-
diff --git a/plugins/magnatune/magnatune/TrackListHandler.py b/plugins/magnatune/TrackListHandler.py
similarity index 100%
rename from plugins/magnatune/magnatune/TrackListHandler.py
rename to plugins/magnatune/TrackListHandler.py
diff --git a/plugins/magnatune/magnatune-prefs.ui b/plugins/magnatune/magnatune-prefs.ui
index 789afd3..7b90fe9 100644
--- a/plugins/magnatune/magnatune-prefs.ui
+++ b/plugins/magnatune/magnatune-prefs.ui
@@ -119,308 +119,129 @@
       </row>
     </data>
   </object>
-  <object class="GtkDialog" id="preferences_dialog">
+  <object class="GtkVBox" id="magnatune_vbox">
     <property name="visible">True</property>
-    <property name="title" translatable="yes">Magnatune Preferences</property>
-    <property name="type_hint">dialog</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+    <property name="border_width">5</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">18</property>
+    <child>
+      <object class="GtkImage" id="image1">
         <property name="visible">True</property>
+        <property name="pixbuf">magnatune_logo_color_small.png</property>
+      </object>
+      <packing>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="account_details_box">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="magnatune_label">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">Magnatune Information</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
         <child>
-          <object class="GtkVBox" id="magnatune_vbox">
+          <object class="GtkVBox" id="vbox1">
             <property name="visible">True</property>
-            <property name="border_width">5</property>
-            <property name="spacing">18</property>
+            <property name="orientation">vertical</property>
             <child>
-              <object class="GtkImage" id="image1">
+              <object class="GtkRadioButton" id="no_account_radio">
+                <property name="label" translatable="yes">I don't have a Magnatune account</property>
                 <property name="visible">True</property>
-                <property name="pixbuf">magnatune_logo_color_small.png</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="active">True</property>
+                <property name="draw_indicator">True</property>
+                <signal name="toggled" handler="rb_magnatune_radio_account_toggled_cb"/>
               </object>
               <packing>
                 <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="account_details_box">
+              <object class="GtkRadioButton" id="stream_account_radio">
+                <property name="label" translatable="yes">I have a streaming account</property>
                 <property name="visible">True</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkLabel" id="magnatune_label">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label" translatable="yes">Magnatune Information</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox1">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <object class="GtkRadioButton" id="no_account_radio">
-                        <property name="label" translatable="yes">I don't have a Magnatune account</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
-                        <signal name="toggled" handler="rb_magnatune_radio_account_toggled_cb"/>
-                      </object>
-                      <packing>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkRadioButton" id="stream_account_radio">
-                        <property name="label" translatable="yes">I have a streaming account</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
-                        <property name="group">no_account_radio</property>
-                        <signal name="toggled" handler="rb_magnatune_radio_account_toggled_cb"/>
-                      </object>
-                      <packing>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkRadioButton" id="download_account_radio">
-                        <property name="label" translatable="yes">I have a download account</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="active">True</property>
-                        <property name="draw_indicator">True</property>
-                        <property name="group">no_account_radio</property>
-                        <signal name="toggled" handler="rb_magnatune_radio_account_toggled_cb"/>
-                      </object>
-                      <packing>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkTable" id="table1">
-                        <property name="visible">True</property>
-                        <property name="n_rows">2</property>
-                        <property name="n_columns">2</property>
-                        <child>
-                          <object class="GtkLabel" id="username_label">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Username:</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="password_label">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">Password:</property>
-                          </object>
-                          <packing>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkEntry" id="username_entry">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="invisible_char">&#x25CF;</property>
-                            <signal name="changed" handler="rb_magnatune_username_changed_cb"/>
-                          </object>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkEntry" id="password_entry">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="visibility">False</property>
-                            <property name="invisible_char">&#x25CF;</property>
-                            <signal name="changed" handler="rb_magnatune_password_changed_cb"/>
-                          </object>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="position">3</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="draw_indicator">True</property>
+                <property name="group">no_account_radio</property>
+                <signal name="toggled" handler="rb_magnatune_radio_account_toggled_cb"/>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
                 <property name="position">1</property>
               </packing>
             </child>
             <child>
-              <object class="GtkHBox" id="hbox21">
+              <object class="GtkRadioButton" id="download_account_radio">
+                <property name="label" translatable="yes">I have a download account</property>
                 <property name="visible">True</property>
-                <child>
-                  <object class="GtkLabel" id="audio_label">
-                    <property name="visible">True</property>
-                    <property name="xpad">8</property>
-                    <property name="label" translatable="yes">Preferred audio _format:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">audio_combobox</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBox" id="audio_combobox">
-                    <property name="visible">True</property>
-                    <property name="model">model3</property>
-                    <signal name="changed" handler="rb_magnatune_audio_combobox_changed_cb"/>
-                    <child>
-                      <object class="GtkCellRendererText" id="renderer3"/>
-                      <attributes>
-                        <attribute name="text">0</attribute>
-                      </attributes>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="draw_indicator">True</property>
+                <property name="group">no_account_radio</property>
+                <signal name="toggled" handler="rb_magnatune_radio_account_toggled_cb"/>
               </object>
               <packing>
                 <property name="position">2</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox14">
+              <object class="GtkTable" id="table1">
                 <property name="visible">True</property>
+                <property name="n_rows">2</property>
+                <property name="n_columns">2</property>
                 <child>
-                  <object class="GtkHBox" id="hbox23">
+                  <object class="GtkLabel" id="username_label">
                     <property name="visible">True</property>
-                    <child>
-                      <object class="GtkLabel" id="label57">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Get an account at </property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLinkButton" id="href1">
-                        <property name="label" translatable="yes">http://magnatune.com/compare_plans</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="uri">http://magnatune.com/compare_plans?referal_id=rhythmbox</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
+                    <property name="label" translatable="yes">Username:</property>
                   </object>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkHBox" id="hbox15">
+                  <object class="GtkLabel" id="password_label">
                     <property name="visible">True</property>
-                    <child>
-                      <object class="GtkLabel" id="label21">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Find out about Magnatune at </property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">magnatune_link</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLinkButton" id="magnatune_link">
-                        <property name="label" translatable="yes">http://www.magnatune.com/info/</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="uri">http://www.magnatune.com/info/</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
+                    <property name="label" translatable="yes">Password:</property>
                   </object>
                   <packing>
-                    <property name="position">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkHBox" id="hbox17">
+                  <object class="GtkEntry" id="username_entry">
                     <property name="visible">True</property>
-                    <child>
-                      <object class="GtkLabel" id="label27">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Redownload purchased music at </property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">redownload_link</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLinkButton" id="redownload_link">
-                        <property name="label" translatable="yes">http://www.magnatune.com/info/redownload</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="uri">http://www.magnatune.com/info/redownload</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                    <signal name="changed" handler="rb_magnatune_username_changed_cb"/>
                   </object>
                   <packing>
-                    <property name="position">2</property>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="account_changed_label">
+                  <object class="GtkEntry" id="password_entry">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes">Your account details have changed. Changes will be applied the next time you start Rhythmbox.</property>
+                    <property name="can_focus">True</property>
+                    <property name="visibility">False</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                    <signal name="changed" handler="rb_magnatune_password_changed_cb"/>
                   </object>
                   <packing>
-                    <property name="position">3</property>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
                   </packing>
                 </child>
               </object>
@@ -430,21 +251,138 @@
             </child>
           </object>
           <packing>
-            <property name="position">2</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkHBox" id="hbox21">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkLabel" id="audio_label">
+            <property name="visible">True</property>
+            <property name="xpad">8</property>
+            <property name="label" translatable="yes">Preferred audio _format:</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">audio_combobox</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="audio_combobox">
+            <property name="visible">True</property>
+            <property name="model">model3</property>
+            <signal name="changed" handler="rb_magnatune_audio_combobox_changed_cb"/>
+            <child>
+              <object class="GtkCellRendererText" id="renderer3"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="vbox14">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHBox" id="hbox23">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label57">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Get an account at </property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLinkButton" id="href1">
+                <property name="label" translatable="yes">http://magnatune.com/compare_plans</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="relief">none</property>
+                <property name="uri">http://magnatune.com/compare_plans?referal_id=rhythmbox</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">0</property>
           </packing>
         </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
+        <child>
+          <object class="GtkHBox" id="hbox15">
             <property name="visible">True</property>
-            <property name="layout_style">end</property>
             <child>
-              <object class="GtkButton" id="closebutton1">
-                <property name="label">gtk-close</property>
+              <object class="GtkLabel" id="label21">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Find out about Magnatune at </property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">magnatune_link</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLinkButton" id="magnatune_link">
+                <property name="label" translatable="yes">http://www.magnatune.com/info/</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
+                <property name="receives_default">True</property>
+                <property name="relief">none</property>
+                <property name="uri">http://www.magnatune.com/info/</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkHBox" id="hbox17">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label27">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Redownload purchased music at </property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">redownload_link</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -452,17 +390,39 @@
                 <property name="position">0</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLinkButton" id="redownload_link">
+                <property name="label" translatable="yes">http://www.magnatune.com/info/redownload</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="relief">none</property>
+                <property name="uri">http://www.magnatune.com/info/redownload</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="account_changed_label">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Your account details have changed. Changes will be applied the next time you start Rhythmbox.</property>
+          </object>
+          <packing>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>
+      <packing>
+        <property name="position">3</property>
+      </packing>
     </child>
-    <action-widgets>
-      <action-widget response="-7">closebutton1</action-widget>
-    </action-widgets>
   </object>
 </interface>
diff --git a/plugins/magnatune/magnatune.rb-plugin.in b/plugins/magnatune/magnatune.plugin.in
similarity index 91%
rename from plugins/magnatune/magnatune.rb-plugin.in
rename to plugins/magnatune/magnatune.plugin.in
index 26950cc..56fcf15 100644
--- a/plugins/magnatune/magnatune.rb-plugin.in
+++ b/plugins/magnatune/magnatune.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=magnatune
-IAge=1
+IAge=2
+Depends=rb
 _Name=Magnatune Store
 _Description=Adds support to Rhythmbox for playing and purchasing from the Magnatune online music store
 Authors=Adam Zimmerman, James Livingston
diff --git a/plugins/magnatune/magnatune/__init__.py b/plugins/magnatune/magnatune.py
similarity index 56%
rename from plugins/magnatune/magnatune/__init__.py
rename to plugins/magnatune/magnatune.py
index 5d8a74c..f7d03ac 100644
--- a/plugins/magnatune/magnatune/__init__.py
+++ b/plugins/magnatune/magnatune.py
@@ -37,7 +37,7 @@ import gnomekeyring as keyring
 
 import rb
 from gi.repository import RB
-from gi.repository import Gtk, Gio
+from gi.repository import Gtk, Gio, Peas, PeasGtk
 # XXX use GnomeKeyring when available
 
 from MagnatuneSource import MagnatuneSource
@@ -69,20 +69,18 @@ class MagnatuneEntryType(RB.RhythmDBEntryType):
 	def sync_metadata(self, entry, changes):
 		return
 
-class Magnatune(RB.Plugin):
+class Magnatune(gobject.GObject, Peas.Activatable):
+	__gtype_name__ = 'Magnatune'
+	object = gobject.property(type=gobject.GObject)
 
 	format_list = ['ogg', 'flac', 'wav', 'mp3-vbr', 'mp3-cbr']
 
-	#
-	# Core methods
-	#
-
 	def __init__(self):
-		RB.Plugin.__init__(self)
+		gobject.GObject.__init__(self)
 
-	def activate(self, shell):
-		self.shell = shell # so the source can update the progress bar
-		self.db = shell.get_property("db")
+	def do_activate(self):
+		shell = self.object
+		self.db = shell.props.db
 
 		self.entry_type = MagnatuneEntryType()
 		self.db.register_entry_type(self.entry_type)
@@ -96,49 +94,53 @@ class Magnatune(RB.Plugin):
 		icon = rb.try_load_icon(theme, "magnatune", width, 0)
 
 		group = RB.DisplayPageGroup.get_by_id ("stores")
+		settings = Gio.Settings("org.gnome.rhythmbox.plugins.magnatune")
 		self.source = gobject.new(MagnatuneSource,
 					  shell=shell,
 					  entry_type=self.entry_type,
 					  pixbuf=icon,
-					  plugin=self)
+					  plugin=self,
+					  settings=settings.get_child("source"),
+					  name=_("Magnatune"))
 
 		shell.register_entry_type_for_source(self.source, self.entry_type)
 		shell.append_display_page(self.source, group)
 
-		manager = shell.get_player().get_property('ui-manager')
+		manager = shell.props.ui_manager
 		# Add the popup menu actions
 		self.action_group = Gtk.ActionGroup(name='MagnatunePluginActions')
 
 		action = Gtk.Action(name='MagnatuneDownloadAlbum', label=_('Download Album'),
 				tooltip=_("Download this album from Magnatune"),
 				stock_id='gtk-save')
-		action.connect('activate', lambda a: self.shell.get_property("selected-page").download_album())
+		action.connect('activate', lambda a: shell.props.selected_page.download_album())
 		self.action_group.add_action(action)
 		action = Gtk.Action(name='MagnatuneArtistInfo', label=_('Artist Information'),
 				tooltip=_("Get information about this artist"),
 				stock_id='gtk-info')
-		action.connect('activate', lambda a: self.shell.get_property("selected-page").display_artist_info())
+		action.connect('activate', lambda a: shell.props.selected_page.display_artist_info())
 		self.action_group.add_action(action)
 		action = Gtk.Action(name='MagnatuneCancelDownload', label=_('Cancel Downloads'),
 				tooltip=_("Stop downloading purchased albums"),
 				stock_id='gtk-stop')
-		action.connect('activate', lambda a: self.shell.get_property("selected-page").cancel_downloads())
+		action.connect('activate', lambda a: shell.props.selected_page.cancel_downloads())
 		action.set_sensitive(False)
 		self.action_group.add_action(action)
 
 		manager.insert_action_group(self.action_group, 0)
 		self.ui_id = manager.add_ui_from_string(popup_ui)
 
-		self.pec_id = shell.get_player().connect('playing-song-changed', self.playing_entry_changed)
+		self.pec_id = shell.props.shell_player.connect('playing-song-changed', self.playing_entry_changed)
 		manager.ensure_update()
 
-	def deactivate(self, shell):
-		manager = shell.get_player().get_property('ui-manager')
+	def do_deactivate(self):
+		shell = self.object
+		manager = shell.props.ui_manager
 		manager.remove_ui(self.ui_id)
 		manager.remove_action_group(self.action_group)
 		self.action_group = None
 
-		shell.get_player().disconnect(self.pec_id)
+		shell.props.shell_player.disconnect(self.pec_id)
 
 		self.db.entry_delete_by_type(self.entry_type)
 		self.db.commit()
@@ -146,12 +148,19 @@ class Magnatune(RB.Plugin):
 		self.entry_type = None
 		self.source.delete_thyself()
 		self.source = None
-		self.shell = None
 
 	def playing_entry_changed (self, sp, entry):
 		self.source.playing_entry_changed(entry)
 
-	def create_configure_dialog(self, dialog=None):
+
+class MagnatuneConfig(gobject.GObject, PeasGtk.Configurable):
+	__gtype_name__ = 'MagnatuneConfig'
+	object = gobject.property(type=gobject.GObject)
+
+	def __init__(self):
+		gobject.GObject.__init__(self)
+
+	def do_create_configure_widget(self):
 		# We use a dictionary so we can modify these values from within inner functions
 		keyring_data = {
 			'id': 0,
@@ -193,91 +202,91 @@ class Magnatune(RB.Plugin):
 				dialog.present()
 
 
-		if dialog == None:
-			def fill_account_details():
-				account_type = self.settings['account_type'])
-				builder.get_object("no_account_radio").set_active(account_type == "none")
-				builder.get_object("stream_account_radio").set_active(account_type == "stream")
-				builder.get_object("download_account_radio").set_active(account_type == "download")
-
-				username = ""
-				password = ""
-				try:
-					if keyring_data['item']:
-						username, password = keyring_data['item'].get_secret().split('\n')
-				except ValueError: # Couldn't parse the secret, probably because it's empty
-					pass
-				builder.get_object("username_entry").set_text(username)
-				builder.get_object("password_entry").set_text(password)
-
-				has_account = account_type != "none"
-				builder.get_object("username_entry").set_sensitive(has_account)
-				builder.get_object("password_entry").set_sensitive(has_account)
-				builder.get_object("username_label").set_sensitive(has_account)
-				builder.get_object("password_label").set_sensitive(has_account)
-
-				builder.get_object("account_changed_label").hide()
-
-			def account_type_toggled (button):
-				print "account type radiobutton toggled: " + button.get_name()
-				account_type = {"no_account_radio": "none", "stream_account_radio": "stream", "download_account_radio": "download"}
-				if button.get_active():
-					self.settings['account_type'] = account_type[button.get_name()]
-					if account_type[button.get_name()] == 'none':
-						builder.get_object("username_label").set_sensitive(False)
-						builder.get_object("username_entry").set_sensitive(False)
-						builder.get_object("password_label").set_sensitive(False)
-						builder.get_object("password_entry").set_sensitive(False)
-					else:
-						builder.get_object("username_label").set_sensitive(True)
-						builder.get_object("username_entry").set_sensitive(True)
-						builder.get_object("password_label").set_sensitive(True)
-						builder.get_object("password_entry").set_sensitive(True)
-					builder.get_object("account_changed_label").show()
-
-			def account_details_changed(entry):
-				username = builder.get_object("username_entry").get_text()
-				password = builder.get_object("password_entry").get_text()
-				if keyring_data['item']:
-					keyring_data['item'].set_secret('\n'.join((username, password)))
+		def fill_account_details():
+			account_type = self.settings['account_type']
+			builder.get_object("no_account_radio").set_active(account_type == "none")
+			builder.get_object("stream_account_radio").set_active(account_type == "stream")
+			builder.get_object("download_account_radio").set_active(account_type == "download")
 
+			username = ""
+			password = ""
+			try:
+				if keyring_data['item']:
+					username, password = keyring_data['item'].get_secret().split('\n')
+			except ValueError: # Couldn't parse the secret, probably because it's empty
+				pass
+			builder.get_object("username_entry").set_text(username)
+			builder.get_object("password_entry").set_text(password)
+
+			has_account = account_type != "none"
+			builder.get_object("username_entry").set_sensitive(has_account)
+			builder.get_object("password_entry").set_sensitive(has_account)
+			builder.get_object("username_label").set_sensitive(has_account)
+			builder.get_object("password_label").set_sensitive(has_account)
+
+			builder.get_object("account_changed_label").hide()
+
+		def account_type_toggled (button):
+			print "account type radiobutton toggled: " + button.get_name()
+			account_type = {"no_account_radio": "none", "stream_account_radio": "stream", "download_account_radio": "download"}
+			if button.get_active():
+				self.settings['account_type'] = account_type[button.get_name()]
+				if account_type[button.get_name()] == 'none':
+					builder.get_object("username_label").set_sensitive(False)
+					builder.get_object("username_entry").set_sensitive(False)
+					builder.get_object("password_label").set_sensitive(False)
+					builder.get_object("password_entry").set_sensitive(False)
+				else:
+					builder.get_object("username_label").set_sensitive(True)
+					builder.get_object("username_entry").set_sensitive(True)
+					builder.get_object("password_label").set_sensitive(True)
+					builder.get_object("password_entry").set_sensitive(True)
 				builder.get_object("account_changed_label").show()
 
-			def close_button_pressed(x, y):
-				try:
-					if keyring_data['id'] and keyring_data['item']:
-						# The async version is not in the python bindings, grr...
-						keyring.item_set_info_sync(None, keyring_data['id'], keyring_data['item'])
-					else:
-						RB.error_dialog(title = _("Couldn't store account information"),
-						                message = _("There was a problem accessing the keyring. Check the debug output for more information."))
-				except Exception, e:
-					RB.error_dialog(title = _("Couldn't store account information"),
-					                message = str(e))
-				dialog.hide()
-
+		def account_details_changed(entry):
+			username = builder.get_object("username_entry").get_text()
+			password = builder.get_object("password_entry").get_text()
+			if keyring_data['item']:
+				keyring_data['item'].set_secret('\n'.join((username, password)))
 
-			self.configure_callback_dic = {
-				"rb_magnatune_audio_combobox_changed_cb" : lambda w: self.settings['format'] = self.format_list[w.get_active()],
+			builder.get_object("account_changed_label").show()
 
-				"rb_magnatune_radio_account_toggled_cb" : account_type_toggled,
-				"rb_magnatune_username_changed_cb" : account_details_changed,
-				"rb_magnatune_password_changed_cb" : account_details_changed
-			}
+		def close_button_pressed(x, y):
+			try:
+				if keyring_data['id'] and keyring_data['item']:
+					# The async version is not in the python bindings, grr...
+					keyring.item_set_info_sync(None, keyring_data['id'], keyring_data['item'])
+				else:
+					RB.error_dialog(title = _("Couldn't store account information"),
+							message = _("There was a problem accessing the keyring. Check the debug output for more information."))
+			except Exception, e:
+				RB.error_dialog(title = _("Couldn't store account information"),
+						message = str(e))
+			dialog.hide()
+
+		def format_selection_changed(self, button):
+			self.settings['format'] = self.format_list[button.get_active()]
+
+		self.configure_callback_dic = {
+			"rb_magnatune_audio_combobox_changed_cb" : self.format_selection_changed,
+			"rb_magnatune_radio_account_toggled_cb" : account_type_toggled,
+			"rb_magnatune_username_changed_cb" : account_details_changed,
+			"rb_magnatune_password_changed_cb" : account_details_changed
+		}
 
-			builder = Gtk.Builder()
-			builder.add_from_file(self.find_file("magnatune-prefs.ui"))
+		builder = Gtk.Builder()
+		builder.add_from_file(rb.find_plugin_file(self, "magnatune-prefs.ui"))
 
-			dialog = builder.get_object('preferences_dialog')
+		dialog = builder.get_object('preferences_dialog')
 
-			# Set the names of the radio buttons so we can tell which one has been clicked
-			for name in ("no_account_radio", "stream_account_radio", "download_account_radio"):
-				builder.get_object(name).set_name(name)
+		# Set the names of the radio buttons so we can tell which one has been clicked
+		for name in ("no_account_radio", "stream_account_radio", "download_account_radio"):
+			builder.get_object(name).set_name(name)
 
-			builder.get_object("audio_combobox").set_active(self.format_list.index(self.settings['format']))
+		builder.get_object("audio_combobox").set_active(self.format_list.index(self.settings['format']))
 
-			builder.connect_signals(self.configure_callback_dic)
-			dialog.connect("response", close_button_pressed)
+		builder.connect_signals(self.configure_callback_dic)
+		dialog.connect("response", close_button_pressed)
 
 		keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)
 		return dialog
diff --git a/plugins/mmkeys/Makefile.am b/plugins/mmkeys/Makefile.am
index d3dd415..cc77e07 100644
--- a/plugins/mmkeys/Makefile.am
+++ b/plugins/mmkeys/Makefile.am
@@ -33,11 +33,11 @@ INCLUDES = 						\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE			\
 	$(NULL)
 
-plugin_in_files = mmkeys.rb-plugin.in
+plugin_in_files = mmkeys.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/mmkeys/mmkeys.rb-plugin.in b/plugins/mmkeys/mmkeys.plugin.in
similarity index 87%
rename from plugins/mmkeys/mmkeys.rb-plugin.in
rename to plugins/mmkeys/mmkeys.plugin.in
index e67109f..1376bcf 100644
--- a/plugins/mmkeys/mmkeys.rb-plugin.in
+++ b/plugins/mmkeys/mmkeys.plugin.in
@@ -1,6 +1,7 @@
-[RB Plugin]
+[Plugin]
 Module=mmkeys
-IAge=1
+IAge=2
+Builtin=true
 _Name=Media Player Keys
 _Description=Control Rhythmbox using key shortcuts
 Authors=Rhythmbox authors
diff --git a/plugins/mmkeys/rb-mmkeys-plugin.c b/plugins/mmkeys/rb-mmkeys-plugin.c
index ce35374..85f264f 100644
--- a/plugins/mmkeys/rb-mmkeys-plugin.c
+++ b/plugins/mmkeys/rb-mmkeys-plugin.c
@@ -4,7 +4,7 @@
  *  Copyright (C) 2002, 2003 Jorn Baayen <jorn nl linux org>
  *  Copyright (C) 2002,2003 Colin Walters <walters debian org>
  *  Copyright (C) 2007  James Livingston  <doclivingston gmail com>
- *  Copyright (C) 2007  Jonathan Matthew  <jonathan kaolin wh9 net>
+ *  Copyright (C) 2007  Jonathan Matthew  <jonathan d14n 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
@@ -40,8 +40,8 @@
 #include <gio/gio.h>
 #include <glib.h>
 
+#include "rb-plugin-macros.h"
 #include "rb-util.h"
-#include "rb-plugin.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-shell-player.h"
@@ -62,7 +62,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
 	enum {
 		NONE = 0,
@@ -76,14 +76,12 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBMMKeysPluginClass;
 
+RB_DEFINE_PLUGIN(RB_TYPE_MMKEYS_PLUGIN, RBMMKeysPlugin, rb_mmkeys_plugin,)
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_mmkeys_plugin_get_type		(void) G_GNUC_CONST;
-
-RB_PLUGIN_REGISTER(RBMMKeysPlugin, rb_mmkeys_plugin)
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void
 rb_mmkeys_plugin_init (RBMMKeysPlugin *plugin)
@@ -365,8 +363,7 @@ first_call_complete (GObject *proxy, GAsyncResult *res, RBMMKeysPlugin *plugin)
 }
 
 static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *pplugin)
 {
 	GDBusConnection *bus;
 	RBMMKeysPlugin *plugin;
@@ -374,11 +371,9 @@ impl_activate (RBPlugin *bplugin,
 
 	rb_debug ("activating media player keys plugin");
 
-	plugin = RB_MMKEYS_PLUGIN (bplugin);
-	g_object_get (shell,
-		      "shell-player", &plugin->shell_player,
-		      NULL);
-	plugin->shell = g_object_ref (shell);
+	plugin = RB_MMKEYS_PLUGIN (pplugin);
+	g_object_get (plugin, "object", &plugin->shell, NULL);
+	g_object_get (plugin->shell, "shell-player", &plugin->shell_player, NULL);
 
 	bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 	if (plugin->grab_type == NONE && bus != NULL) {
@@ -436,12 +431,11 @@ final_call_complete (GObject *proxy, GAsyncResult *res, gpointer nothing)
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *pplugin)
 {
 	RBMMKeysPlugin *plugin;
 
-	plugin = RB_MMKEYS_PLUGIN (bplugin);
+	plugin = RB_MMKEYS_PLUGIN (pplugin);
 	if (plugin->shell_player != NULL) {
 		g_object_unref (plugin->shell_player);
 		plugin->shell_player = NULL;
@@ -477,12 +471,11 @@ impl_deactivate	(RBPlugin *bplugin,
 #endif
 }
 
-
-static void
-rb_mmkeys_plugin_class_init (RBMMKeysPluginClass *klass)
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
+	rb_mmkeys_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_MMKEYS_PLUGIN);
 }
diff --git a/plugins/mpris/Makefile.am b/plugins/mpris/Makefile.am
index 0c9eb9d..aedb97d 100644
--- a/plugins/mpris/Makefile.am
+++ b/plugins/mpris/Makefile.am
@@ -27,11 +27,11 @@ INCLUDES = 						\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE			\
 	$(NULL)
 
-plugin_in_files = mpris.rb-plugin.in
+plugin_in_files = mpris.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/mpris/mpris.rb-plugin.in b/plugins/mpris/mpris.plugin.in
similarity index 92%
rename from plugins/mpris/mpris.rb-plugin.in
rename to plugins/mpris/mpris.plugin.in
index 760152c..c499a47 100644
--- a/plugins/mpris/mpris.rb-plugin.in
+++ b/plugins/mpris/mpris.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=mpris
-IAge=1
+IAge=2
 _Name=MPRIS D-Bus interface
 _Description=Provides an implementation of the MPRIS D-Bus interface specification
 Authors=Jonathan Matthew
diff --git a/plugins/mpris/rb-mpris-plugin.c b/plugins/mpris/rb-mpris-plugin.c
index 97344b7..265d3b2 100644
--- a/plugins/mpris/rb-mpris-plugin.c
+++ b/plugins/mpris/rb-mpris-plugin.c
@@ -39,7 +39,7 @@
 #include <lib/rb-util.h>
 #include <lib/rb-debug.h>
 #include <lib/eggdesktopfile.h>
-#include <shell/rb-plugin.h>
+#include <plugins/rb-plugin-macros.h>
 #include <shell/rb-shell.h>
 #include <shell/rb-shell-player.h>
 #include <backends/rb-player.h>
@@ -60,7 +60,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
 	GDBusConnection *connection;
 	GDBusNodeInfo *node_info;
@@ -69,7 +69,6 @@ typedef struct
 	guint player_id;
 	guint playlists_id;
 
-	RBShell *shell;
 	RBShellPlayer *player;
 	RhythmDB *db;
 	RBDisplayPageModel *page_model;
@@ -87,16 +86,13 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBMprisPluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_mpris_plugin_get_type		(void) G_GNUC_CONST;
-
-RB_PLUGIN_REGISTER(RBMprisPlugin, rb_mpris_plugin)
-#define RB_MPRIS_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), RB_TYPE_MPRIS_PLUGIN, RBMprisPluginPrivate))
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
+RB_DEFINE_PLUGIN(RB_TYPE_MPRIS_PLUGIN, RBMprisPlugin, rb_mpris_plugin,)
 
 static void
 rb_mpris_plugin_init (RBMprisPlugin *plugin)
@@ -213,6 +209,8 @@ handle_root_method_call (GDBusConnection *connection,
 			 GDBusMethodInvocation *invocation,
 			 RBMprisPlugin *plugin)
 {
+	RBShell *shell;
+
 	if (g_strcmp0 (object_path, MPRIS_OBJECT_NAME) != 0 ||
 	    g_strcmp0 (interface_name, MPRIS_ROOT_INTERFACE) != 0) {
 		g_dbus_method_invocation_return_error (invocation,
@@ -225,10 +223,14 @@ handle_root_method_call (GDBusConnection *connection,
 	}
 
 	if (g_strcmp0 (method_name, "Raise") == 0) {
-		rb_shell_present (plugin->shell, GDK_CURRENT_TIME, NULL);
+		g_object_get (plugin, "object", &shell, NULL);
+		rb_shell_present (shell, GDK_CURRENT_TIME, NULL);
+		g_object_unref (shell);
 		g_dbus_method_invocation_return_value (invocation, NULL);
 	} else if (g_strcmp0 (method_name, "Quit") == 0) {
-		rb_shell_quit (plugin->shell, NULL);
+		g_object_get (plugin, "object", &shell, NULL);
+		rb_shell_quit (shell, NULL);
+		g_object_unref (shell);
 		g_dbus_method_invocation_return_value (invocation, NULL);
 	} else {
 		g_dbus_method_invocation_return_error (invocation,
@@ -677,8 +679,12 @@ handle_player_method_call (GDBusConnection *connection,
 		handle_result (invocation, ret, error);
 	} else if (g_strcmp0 (method_name, "OpenUri") == 0) {
 		const char *uri;
+		RBShell *shell;
+
 		g_variant_get (parameters, "(&s)", &uri);
-		ret = rb_shell_load_uri (plugin->shell, uri, TRUE, &error);
+		g_object_get (plugin, "object", &shell, NULL);
+		ret = rb_shell_load_uri (shell, uri, TRUE, &error);
+		g_object_unref (shell);
 		handle_result (invocation, ret, error);
 	} else {
 		g_dbus_method_invocation_return_error (invocation,
@@ -969,7 +975,10 @@ activate_source_by_id (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter
 			    -1);
 	id = g_object_get_data (G_OBJECT (page), MPRIS_PLAYLIST_ID_ITEM);
 	if (g_strcmp0 (data->playlist_id, id) == 0) {
-		rb_shell_activate_source (data->plugin->shell, RB_SOURCE (page), RB_SHELL_ACTIVATION_ALWAYS_PLAY, NULL);
+		RBShell *shell;
+		g_object_get (data->plugin, "object", &shell, NULL);
+		rb_shell_activate_source (shell, RB_SOURCE (page), RB_SHELL_ACTIVATION_ALWAYS_PLAY, NULL);
+		g_object_unref (shell);
 		return TRUE;
 	}
 	return FALSE;
@@ -1361,28 +1370,29 @@ name_lost_cb (GDBusConnection *connection, const char *name, RBMprisPlugin *plug
 }
 
 static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBMprisPlugin *plugin;
 	GtkUIManager *ui_manager;
 	GDBusInterfaceInfo *ifaceinfo;
 	GError *error = NULL;
+	RBShell *shell;
 
 	rb_debug ("activating MPRIS plugin");
 
 	plugin = RB_MPRIS_PLUGIN (bplugin);
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell,
 		      "shell-player", &plugin->player,
 		      "ui-manager", &ui_manager,
 		      "db", &plugin->db,
 		      "display-page-model", &plugin->page_model,
 		      NULL);
-	plugin->shell = g_object_ref (shell);
 
 	plugin->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 	if (error != NULL) {
 		g_warning ("Unable to connect to D-Bus session bus: %s", error->message);
+		g_object_unref (shell);
 		return;
 	}
 
@@ -1390,6 +1400,7 @@ impl_activate (RBPlugin *bplugin,
 	plugin->node_info = g_dbus_node_info_new_for_xml (mpris_introspection_xml, &error);
 	if (error != NULL) {
 		g_warning ("Unable to read MPRIS interface specificiation: %s", error->message);
+		g_object_unref (shell);
 		return;
 	}
 
@@ -1503,11 +1514,11 @@ impl_activate (RBPlugin *bplugin,
 					      (GBusNameLostCallback) name_lost_cb,
 					      g_object_ref (plugin),
 					      g_object_unref);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBMprisPlugin *plugin;
 
@@ -1544,10 +1555,6 @@ impl_deactivate	(RBPlugin *bplugin,
 		g_object_unref (plugin->player);
 		plugin->player = NULL;
 	}
-	if (plugin->shell != NULL) {
-		g_object_unref (plugin->shell);
-		plugin->shell = NULL;
-	}
 	if (plugin->db != NULL) {
 		g_object_unref (plugin->db);
 		plugin->db = NULL;
@@ -1568,12 +1575,11 @@ impl_deactivate	(RBPlugin *bplugin,
 	}
 }
 
-
-static void
-rb_mpris_plugin_class_init (RBMprisPluginClass *klass)
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
+	rb_mpris_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_MPRIS_PLUGIN);
 }
diff --git a/plugins/mtpdevice/Makefile.am b/plugins/mtpdevice/Makefile.am
index 51fcfae..b023000 100644
--- a/plugins/mtpdevice/Makefile.am
+++ b/plugins/mtpdevice/Makefile.am
@@ -1,6 +1,7 @@
 NULL =
 
 plugindir = $(PLUGINDIR)/mtpdevice
+plugindatadir = $(PLUGINDATADIR)/mtpdevice
 plugin_LTLIBRARIES = libmtpdevice.la
 
 libmtpdevice_la_SOURCES = \
@@ -33,6 +34,7 @@ INCLUDES = 						\
 	-I$(top_srcdir)/sources                    	\
 	-I$(top_srcdir)/sources/sync                   	\
 	-I$(top_srcdir)/podcast                    	\
+	-I$(top_srcdir)/plugins                    	\
 	-I$(top_srcdir)/shell				\
 	-DPIXMAP_DIR=\""$(datadir)/pixmaps"\"		\
 	-DSHARE_DIR=\"$(pkgdatadir)\"                   \
@@ -43,16 +45,16 @@ INCLUDES = 						\
 	$(MTP_CFLAGS)					\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = mtpdevice.rb-plugin.in
+plugin_in_files = mtpdevice.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-uixmldir = $(plugindir)
+uixmldir = $(plugindatadir)
 uixml_DATA = mtp-ui.xml
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
-gtkbuilderdir = $(plugindir)
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA = 					\
 	mtp-info.ui
 
diff --git a/plugins/mtpdevice/mtpdevice.rb-plugin.in b/plugins/mtpdevice/mtpdevice.plugin.in
similarity index 92%
rename from plugins/mtpdevice/mtpdevice.rb-plugin.in
rename to plugins/mtpdevice/mtpdevice.plugin.in
index bab8bcb..028d927 100644
--- a/plugins/mtpdevice/mtpdevice.rb-plugin.in
+++ b/plugins/mtpdevice/mtpdevice.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=mtpdevice
-IAge=1
+IAge=2
 _Name=Portable Players - MTP
 _Description=Support for MTP devices (show the content, transfer, play from device)
 Authors=Peter Grundström
diff --git a/plugins/mtpdevice/rb-mtp-gst-sink.c b/plugins/mtpdevice/rb-mtp-gst-sink.c
index 6825382..bc89012 100644
--- a/plugins/mtpdevice/rb-mtp-gst-sink.c
+++ b/plugins/mtpdevice/rb-mtp-gst-sink.c
@@ -456,7 +456,7 @@ rb_mtp_sink_class_init (RBMTPSinkClass *klass)
 					 g_param_spec_object ("device-thread",
 							      "device-thread",
 							      "device handling thread",
-							      RB_TYPE_MTP_THREAD,
+							      G_TYPE_OBJECT,
 							      G_PARAM_READWRITE));
 }
 
diff --git a/plugins/mtpdevice/rb-mtp-gst-src.c b/plugins/mtpdevice/rb-mtp-gst-src.c
index 1138856..9b431e5 100644
--- a/plugins/mtpdevice/rb-mtp-gst-src.c
+++ b/plugins/mtpdevice/rb-mtp-gst-src.c
@@ -419,7 +419,7 @@ rb_mtp_src_class_init (RBMTPSrcClass *klass)
 					 g_param_spec_object ("device-thread",
 							      "device-thread",
 							      "device handling thread",
-							      RB_TYPE_MTP_THREAD,
+							      G_TYPE_OBJECT,
 							      G_PARAM_READWRITE));
 }
 
diff --git a/plugins/mtpdevice/rb-mtp-plugin.c b/plugins/mtpdevice/rb-mtp-plugin.c
index 9f15f18..f8fb0ea 100644
--- a/plugins/mtpdevice/rb-mtp-plugin.c
+++ b/plugins/mtpdevice/rb-mtp-plugin.c
@@ -48,11 +48,12 @@
 #include <dbus/dbus-glib-lowlevel.h>
 #endif
 
+#include "rb-plugin-macros.h"
 #include "rb-source.h"
 #include "rb-display-page-group.h"
 #include "rb-display-page-tree.h"
 #include "rb-mtp-source.h"
-#include "rb-plugin.h"
+#include "rb-mtp-thread.h"
 #include "rb-debug.h"
 #include "rb-file-helpers.h"
 #include "rb-util.h"
@@ -71,9 +72,8 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
-	RBShell *shell;
 	GtkActionGroup *action_group;
 	guint ui_merge_id;
 
@@ -89,17 +89,13 @@ typedef struct
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBMtpPluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType rb_mtp_plugin_get_type (void) G_GNUC_CONST;
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void rb_mtp_plugin_init (RBMtpPlugin *plugin);
-static void rb_mtp_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
 #if defined(HAVE_GUDEV)
 static RBSource* create_source_device_cb (RBRemovableMediaManager *rmm, GObject *device, RBMtpPlugin *plugin);
@@ -116,7 +112,7 @@ static void rb_mtp_plugin_properties (GtkAction *action, RBSource *source);
 GType rb_mtp_src_get_type (void);
 GType rb_mtp_sink_get_type (void);
 
-RB_PLUGIN_REGISTER(RBMtpPlugin, rb_mtp_plugin)
+RB_DEFINE_PLUGIN(RB_TYPE_MTP_PLUGIN, RBMtpPlugin, rb_mtp_plugin,)
 
 static GtkActionEntry rb_mtp_plugin_actions [] =
 {
@@ -129,25 +125,6 @@ static GtkActionEntry rb_mtp_plugin_actions [] =
 };
 
 static void
-rb_mtp_plugin_class_init (RBMtpPluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_mtp_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-
-	/* register types used by the plugin */
-	RB_PLUGIN_REGISTER_TYPE (rb_mtp_source);
-
-	/* ensure the gstreamer elements get linked in */
-	rb_mtp_src_get_type ();
-	rb_mtp_sink_get_type ();
-}
-
-static void
 rb_mtp_plugin_init (RBMtpPlugin *plugin)
 {
 	rb_debug ("RBMtpPlugin initialising");
@@ -155,20 +132,13 @@ rb_mtp_plugin_init (RBMtpPlugin *plugin)
 }
 
 static void
-rb_mtp_plugin_finalize (GObject *object)
-{
-	rb_debug ("RBMtpPlugin finalising");
-
-	G_OBJECT_CLASS (rb_mtp_plugin_parent_class)->finalize (object);
-}
-
-static void
-impl_activate (RBPlugin *bplugin, RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBMtpPlugin *plugin = RB_MTP_PLUGIN (bplugin);
 	GtkUIManager *uimanager = NULL;
 	RBRemovableMediaManager *rmm;
 	char *file = NULL;
+	RBShell *shell;
 #if defined(HAVE_GUDEV)
 	gboolean rmm_scanned = FALSE;
 #else
@@ -176,7 +146,7 @@ impl_activate (RBPlugin *bplugin, RBShell *shell)
 	LIBMTP_raw_device_t *mtp_devices;
 #endif
 
-	plugin->shell = shell;
+	g_object_get (plugin, "object", &shell, NULL);
 
 	g_object_get (shell,
 		     "ui-manager", &uimanager,
@@ -189,13 +159,14 @@ impl_activate (RBPlugin *bplugin, RBShell *shell)
 	gtk_action_group_set_translation_domain (plugin->action_group,
 						 GETTEXT_PACKAGE);
 	_rb_action_group_add_display_page_actions (plugin->action_group,
-						   G_OBJECT (plugin->shell),
+						   G_OBJECT (shell),
 						   rb_mtp_plugin_actions,
 						   G_N_ELEMENTS (rb_mtp_plugin_actions));
 	gtk_ui_manager_insert_action_group (uimanager, plugin->action_group, 0);
-	file = rb_plugin_find_file (bplugin, "mtp-ui.xml");
+	file = rb_find_plugin_data_file (G_OBJECT (bplugin), "mtp-ui.xml");
 	plugin->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager, file, NULL);
 	g_object_unref (uimanager);
+	g_object_unref (shell);
 
 	/* device detection */
 #if defined(HAVE_GUDEV)
@@ -243,12 +214,14 @@ impl_activate (RBPlugin *bplugin, RBShell *shell)
 }
 
 static void
-impl_deactivate (RBPlugin *bplugin, RBShell *shell)
+impl_deactivate (PeasActivatable *bplugin)
 {
 	RBMtpPlugin *plugin = RB_MTP_PLUGIN (bplugin);
 	GtkUIManager *uimanager = NULL;
 	RBRemovableMediaManager *rmm = NULL;
+	RBShell *shell;
 
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell,
 		      "ui-manager", &uimanager,
 		      "removable-media-manager", &rmm,
@@ -283,6 +256,7 @@ impl_deactivate (RBPlugin *bplugin, RBShell *shell)
 
 	g_object_unref (uimanager);
 	g_object_unref (rmm);
+	g_object_unref (shell);
 }
 
 static void
@@ -371,6 +345,7 @@ create_source_device_cb (RBRemovableMediaManager *rmm, GObject *device_obj, RBMt
 		    device_list[i].product_id == model) {
 			LIBMTP_raw_device_t rawdevice;
 			RBSource *source;
+			RBShell *shell;
 
 			rb_debug ("found libmtp device list entry (model: %s, vendor: %s)",
 				  device_list[i].vendor, device_list[i].product);
@@ -379,12 +354,14 @@ create_source_device_cb (RBRemovableMediaManager *rmm, GObject *device_obj, RBMt
 			rawdevice.bus_location = busnum;
 			rawdevice.devnum = devnum;
 
-			source = rb_mtp_source_new (plugin->shell, RB_PLUGIN (plugin), device, &rawdevice);
+			g_object_get (plugin, "object", &shell, NULL);
+			source = rb_mtp_source_new (shell, G_OBJECT (plugin), device, &rawdevice);
 
 			plugin->mtp_sources = g_list_prepend (plugin->mtp_sources, source);
 			g_signal_connect_object (G_OBJECT (source),
 						"deleted", G_CALLBACK (source_deleted_cb),
 						plugin, 0);
+			g_object_unref (shell);
 			return source;
 		}
 	}
@@ -425,15 +402,18 @@ rb_mtp_plugin_maybe_add_source (RBMtpPlugin *plugin, const char *udi, LIBMTP_raw
 		rb_debug ("detected MTP device: device number %d (bus location %u)", raw_devices[i].devnum, raw_devices[i].bus_location);
 		if (raw_devices[i].devnum == device_num) {
 			RBSource *source;
+			RBShell *shell;
 
 			rb_debug ("device matched, creating a source");
-			source = RB_SOURCE (rb_mtp_source_new (plugin->shell, RB_PLUGIN (plugin), udi, &raw_devices[i]));
+			g_object_get (plugin, "object", &shell, NULL);
+			source = RB_SOURCE (rb_mtp_source_new (shell, G_OBJECT (plugin), udi, &raw_devices[i]));
 
-			rb_shell_append_display_page (plugin->shell, RB_DISPLAY_PAGE (source), RB_DISPLAY_PAGE_GROUP_DEVICES);
+			rb_shell_append_display_page (shell, RB_DISPLAY_PAGE (source), RB_DISPLAY_PAGE_GROUP_DEVICES);
 			plugin->mtp_sources = g_list_prepend (plugin->mtp_sources, source);
 			g_signal_connect_object (source,
 						"deleted", G_CALLBACK (source_deleted_cb),
 						plugin, 0);
+			g_object_unref (shell);
 		}
 	}
 }
@@ -513,3 +493,19 @@ rb_mtp_plugin_setup_dbus_hal_connection (RBMtpPlugin *plugin)
 }
 
 #endif
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_mtp_plugin_register_type (G_TYPE_MODULE (module));
+	_rb_mtp_source_register_type (G_TYPE_MODULE (module));
+	_rb_mtp_thread_register_type (G_TYPE_MODULE (module));
+
+	/* ensure the gstreamer elements get linked in */
+	rb_mtp_src_get_type ();
+	rb_mtp_sink_get_type ();
+
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_MTP_PLUGIN);
+}
diff --git a/plugins/mtpdevice/rb-mtp-source.c b/plugins/mtpdevice/rb-mtp-source.c
index 8030100..72d4f85 100644
--- a/plugins/mtpdevice/rb-mtp-source.c
+++ b/plugins/mtpdevice/rb-mtp-source.c
@@ -40,7 +40,6 @@
 #include "rhythmdb.h"
 #include "rb-debug.h"
 #include "rb-file-helpers.h"
-#include "rb-plugin.h"
 #include "rb-builder-helpers.h"
 #include "rb-removable-media-manager.h"
 #include "rb-static-playlist-source.h"
@@ -157,9 +156,7 @@ typedef struct
 
 } RBMtpSourcePrivate;
 
-RB_PLUGIN_DEFINE_TYPE(RBMtpSource,
-		       rb_mtp_source,
-		       RB_TYPE_MEDIA_PLAYER_SOURCE)
+G_DEFINE_DYNAMIC_TYPE(RBMtpSource, rb_mtp_source, RB_TYPE_MEDIA_PLAYER_SOURCE)
 
 #define MTP_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_MTP_SOURCE, RBMtpSourcePrivate))
 
@@ -243,6 +240,11 @@ rb_mtp_source_class_init (RBMtpSourceClass *klass)
 }
 
 static void
+rb_mtp_source_class_finalize (RBMtpSourceClass *klass)
+{
+}
+
+static void
 rb_mtp_source_name_changed_cb (RBMtpSource *source,
 			       GParamSpec *spec,
 			       gpointer data)
@@ -538,7 +540,7 @@ rb_mtp_source_finalize (GObject *object)
 
 RBSource *
 rb_mtp_source_new (RBShell *shell,
-		   RBPlugin *plugin,
+		   GObject *plugin,
 #if defined(HAVE_GUDEV)
 		   GUdevDevice *udev_device,
 #else
@@ -1535,14 +1537,14 @@ impl_show_properties (RBMediaPlayerSource *source, GtkWidget *info_box, GtkWidge
 	int num_podcasts;
 	char *device_name;
 	char *builder_file;
-	RBPlugin *plugin;
+	GObject *plugin;
 	char *text;
 	GList *output_formats;
 	GList *t;
 	GString *str;
 
 	g_object_get (source, "plugin", &plugin, NULL);
-	builder_file = rb_plugin_find_file (plugin, "mtp-info.ui");
+	builder_file = rb_find_plugin_data_file (G_OBJECT (plugin), "mtp-info.ui");
 	g_object_unref (plugin);
 
 	if (builder_file == NULL) {
@@ -1733,3 +1735,9 @@ find_mount_for_device (GUdevDevice *device)
 }
 
 #endif
+
+void
+_rb_mtp_source_register_type (GTypeModule *module)
+{
+	rb_mtp_source_register_type (module);
+}
diff --git a/plugins/mtpdevice/rb-mtp-source.h b/plugins/mtpdevice/rb-mtp-source.h
index 95c98aa..19e7c0e 100644
--- a/plugins/mtpdevice/rb-mtp-source.h
+++ b/plugins/mtpdevice/rb-mtp-source.h
@@ -31,7 +31,6 @@
 #include "rb-shell.h"
 #include "rb-removable-media-source.h"
 #include "rb-media-player-source.h"
-#include "rb-plugin.h"
 #include "rhythmdb.h"
 #include <libmtp.h>
 
@@ -55,7 +54,7 @@ typedef struct
 } RBMtpSourceClass;
 
 RBSource *		rb_mtp_source_new		(RBShell *shell,
-							 RBPlugin *plugin,
+							 GObject *plugin,
 #if defined(HAVE_GUDEV)
 							 GUdevDevice *udev_device,
 #else
@@ -64,7 +63,7 @@ RBSource *		rb_mtp_source_new		(RBShell *shell,
 							 LIBMTP_raw_device_t *device);
 
 GType			rb_mtp_source_get_type		(void);
-GType			rb_mtp_source_register_type	(GTypeModule *module);
+void			_rb_mtp_source_register_type	(GTypeModule *module);
 
 G_END_DECLS
 
diff --git a/plugins/mtpdevice/rb-mtp-thread.c b/plugins/mtpdevice/rb-mtp-thread.c
index b547661..763409c 100644
--- a/plugins/mtpdevice/rb-mtp-thread.c
+++ b/plugins/mtpdevice/rb-mtp-thread.c
@@ -38,7 +38,7 @@
 #include "rb-dialog.h"
 #include "rb-debug.h"
 
-G_DEFINE_TYPE(RBMtpThread, rb_mtp_thread, G_TYPE_OBJECT)
+G_DEFINE_DYNAMIC_TYPE(RBMtpThread, rb_mtp_thread, G_TYPE_OBJECT)
 
 
 typedef struct {
@@ -912,6 +912,11 @@ rb_mtp_thread_class_init (RBMtpThreadClass *klass)
 	object_class->finalize = impl_finalize;
 }
 
+static void
+rb_mtp_thread_class_finalize (RBMtpThreadClass *klass)
+{
+}
+
 RBMtpThread *
 rb_mtp_thread_new (void)
 {
@@ -949,3 +954,8 @@ rb_mtp_thread_error_get_type (void)
 	return etype;
 }
 
+void
+_rb_mtp_thread_register_type (GTypeModule *module)
+{
+	rb_mtp_thread_register_type (module);
+}
diff --git a/plugins/mtpdevice/rb-mtp-thread.h b/plugins/mtpdevice/rb-mtp-thread.h
index 8085634..76c6743 100644
--- a/plugins/mtpdevice/rb-mtp-thread.h
+++ b/plugins/mtpdevice/rb-mtp-thread.h
@@ -87,6 +87,7 @@ typedef void (*RBMtpCreateFolderCallback) (uint32_t folder_id, gpointer user_dat
 
 GType		rb_mtp_thread_get_type (void);
 RBMtpThread *	rb_mtp_thread_new (void);
+void            _rb_mtp_thread_register_type (GTypeModule *module);
 
 void		rb_mtp_thread_report_errors (RBMtpThread *thread, gboolean use_dialog);
 
diff --git a/plugins/notification/Makefile.am b/plugins/notification/Makefile.am
index 8be085b..6b5ef7b 100644
--- a/plugins/notification/Makefile.am
+++ b/plugins/notification/Makefile.am
@@ -24,6 +24,7 @@ INCLUDES = 						\
 	-I$(top_srcdir)/widgets                    	\
 	-I$(top_srcdir)/sources                    	\
 	-I$(top_srcdir)/shell				\
+	-I$(top_srcdir)/plugins				\
 	-DPIXMAP_DIR=\""$(datadir)/pixmaps"\"		\
 	-DSHARE_DIR=\"$(pkgdatadir)\"                   \
 	-DDATADIR=\""$(datadir)"\"			\
@@ -31,12 +32,12 @@ INCLUDES = 						\
 	$(NOTIFY_CFLAGS)				\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = notification.rb-plugin.in
+plugin_in_files = notification.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-BUILT_SOURCES =							\
-	$(plugin_in_files:.rb-plugin.in=.rb-plugin) 	\
+BUILT_SOURCES =					\
+	$(plugin_in_files:.plugin.in=.plugin) 	\
 	$(NULL)
 
 plugin_DATA = 			\
diff --git a/plugins/notification/notification.rb-plugin.in b/plugins/notification/notification.plugin.in
similarity index 90%
rename from plugins/notification/notification.rb-plugin.in
rename to plugins/notification/notification.plugin.in
index 50030a3..fdc748e 100644
--- a/plugins/notification/notification.rb-plugin.in
+++ b/plugins/notification/notification.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=notification
-IAge=1
+IAge=2
 _Name=Notification
 _Description=Notification popups
 Authors=Jonathan Matthew
diff --git a/plugins/notification/rb-notification-plugin.c b/plugins/notification/rb-notification-plugin.c
index 2138e0d..20248b3 100644
--- a/plugins/notification/rb-notification-plugin.c
+++ b/plugins/notification/rb-notification-plugin.c
@@ -37,7 +37,7 @@
 #include <libnotify/notify.h>
 
 #include "rb-util.h"
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-shell-player.h"
@@ -54,7 +54,7 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
 	/* current playing data */
 	char *current_title;
@@ -67,20 +67,17 @@ typedef struct
 	gboolean notify_supports_persistence;
 
 	RBShellPlayer *shell_player;
-	RBShell *shell;
 	RhythmDB *db;
 } RBNotificationPlugin;
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBNotificationPluginClass;
 
-GType	rb_notification_plugin_get_type		(void) G_GNUC_CONST;
-
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule  *module);
 
-RB_PLUGIN_REGISTER(RBNotificationPlugin, rb_notification_plugin)
+RB_DEFINE_PLUGIN(RB_TYPE_NOTIFICATION_PLUGIN, RBNotificationPlugin, rb_notification_plugin,)
 
 static gchar *
 markup_escape (const char *text)
@@ -534,24 +531,24 @@ db_stream_metadata_cb (RhythmDB *db,
 /* plugin infrastructure */
 
 static void
-impl_activate (RBPlugin *bplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBNotificationPlugin *plugin;
 	GDBusConnection *bus;
+	RBShell *shell;
 
 	rb_debug ("activating notification plugin");
 
 	plugin = RB_NOTIFICATION_PLUGIN (bplugin);
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell,
 		      "shell-player", &plugin->shell_player,
 		      "db", &plugin->db,
 		      NULL);
-	plugin->shell = g_object_ref (shell);
 
 	/* connect various things */
-	g_signal_connect_object (plugin->shell, "notify-playing-entry", G_CALLBACK (shell_notify_playing_cb), plugin, 0);
-	g_signal_connect_object (plugin->shell, "notify-custom", G_CALLBACK (shell_notify_custom_cb), plugin, 0);
+	g_signal_connect_object (shell, "notify-playing-entry", G_CALLBACK (shell_notify_playing_cb), plugin, 0);
+	g_signal_connect_object (shell, "notify-custom", G_CALLBACK (shell_notify_custom_cb), plugin, 0);
 
 	g_signal_connect_object (plugin->shell_player, "playing-song-changed", G_CALLBACK (playing_entry_changed_cb), plugin, 0);
 
@@ -590,16 +587,20 @@ impl_activate (RBPlugin *bplugin,
 	}
 
 	/* hook into shell preferences so we can poke stuff into the general prefs page? */
+
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *bplugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *bplugin)
 {
 	RBNotificationPlugin *plugin;
+	RBShell *shell;
 
 	plugin = RB_NOTIFICATION_PLUGIN (bplugin);
 
+	g_object_get (plugin, "object", &shell, NULL);
+
 	cleanup_notification (plugin);
 
 	/* disconnect signal handlers used to update the icon */
@@ -618,10 +619,8 @@ impl_deactivate	(RBPlugin *bplugin,
 		plugin->db = NULL;
 	}
 
-	g_signal_handlers_disconnect_by_func (plugin->shell, shell_notify_playing_cb, plugin);
-	g_signal_handlers_disconnect_by_func (plugin->shell, shell_notify_custom_cb, plugin);
-	g_object_unref (plugin->shell);
-	plugin->shell = NULL;
+	g_signal_handlers_disconnect_by_func (shell, shell_notify_playing_cb, plugin);
+	g_signal_handlers_disconnect_by_func (shell, shell_notify_custom_cb, plugin);
 
 	/* forget what's playing */
 	g_free (plugin->current_title);
@@ -630,6 +629,8 @@ impl_deactivate	(RBPlugin *bplugin,
 	plugin->current_title = NULL;
 	plugin->current_album_and_artist = NULL;
 	plugin->notify_art_path = NULL;
+
+	g_object_unref (shell);
 }
 
 static void
@@ -637,11 +638,11 @@ rb_notification_plugin_init (RBNotificationPlugin *plugin)
 {
 }
 
-static void
-rb_notification_plugin_class_init (RBNotificationPluginClass *klass)
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
+	rb_notification_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_NOTIFICATION_PLUGIN);
 }
diff --git a/plugins/power-manager/Makefile.am b/plugins/power-manager/Makefile.am
index dd11ccb..103d7b7 100644
--- a/plugins/power-manager/Makefile.am
+++ b/plugins/power-manager/Makefile.am
@@ -29,11 +29,11 @@ INCLUDES = 						\
 	$(RHYTHMBOX_CFLAGS)				\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = power-manager.rb-plugin.in
+plugin_in_files = power-manager.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/power-manager/power-manager.rb-plugin.in b/plugins/power-manager/power-manager.plugin.in
similarity index 89%
rename from plugins/power-manager/power-manager.rb-plugin.in
rename to plugins/power-manager/power-manager.plugin.in
index 6012a3a..eabfac7 100644
--- a/plugins/power-manager/power-manager.rb-plugin.in
+++ b/plugins/power-manager/power-manager.plugin.in
@@ -1,6 +1,7 @@
-[RB Plugin]
+[Plugin]
 Module=power-manager
-IAge=1
+IAge=2
+Builtin=true
 _Name=Power Manager
 _Description=Inhibit Power Manager from suspending the machine while playing
 Authors=Jonathan Matthew <jonathan d14n org>
diff --git a/plugins/power-manager/rb-power-manager-plugin.c b/plugins/power-manager/rb-power-manager-plugin.c
index ade0c06..5e34634 100644
--- a/plugins/power-manager/rb-power-manager-plugin.c
+++ b/plugins/power-manager/rb-power-manager-plugin.c
@@ -37,8 +37,9 @@
 #include <gdk/gdkx.h>
 #include <gio/gio.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
+#include "rb-shell.h"
 
 #define RB_TYPE_GPM_PLUGIN		(rb_gpm_plugin_get_type ())
 #define RB_GPM_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_GPM_PLUGIN, RBGPMPlugin))
@@ -49,36 +50,22 @@
 
 typedef struct
 {
-	RBPlugin parent;
+	PeasExtensionBase parent;
 
 	GDBusProxy *proxy;
 	guint32 cookie;
 	gint handler_id;
 	gint timeout_id;
-	RBShell *shell;
 } RBGPMPlugin;
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBGPMPluginClass;
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_gpm_plugin_get_type		(void) G_GNUC_CONST;
-
-static void rb_gpm_plugin_init (RBGPMPlugin *plugin);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
-RB_PLUGIN_REGISTER(RBGPMPlugin, rb_gpm_plugin)
-
-static void
-rb_gpm_plugin_class_init (RBGPMPluginClass *klass)
-{
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-}
+RB_DEFINE_PLUGIN(RB_TYPE_GPM_PLUGIN, RBGPMPlugin, rb_gpm_plugin,)
 
 static void
 rb_gpm_plugin_init (RBGPMPlugin *plugin)
@@ -149,6 +136,7 @@ inhibit_done (GObject *proxy, GAsyncResult *res, RBGPMPlugin *plugin)
 
 		g_variant_unref (result);
 	}
+	g_object_unref (plugin);
 }
 
 static gboolean
@@ -157,6 +145,7 @@ inhibit (RBGPMPlugin *plugin)
 	GtkWindow *window;
 	gulong xid = 0;
 	GError *error = NULL;
+	RBShell *shell;
 
 	plugin->timeout_id = 0;
 	if (plugin->cookie != 0) {
@@ -170,7 +159,11 @@ inhibit (RBGPMPlugin *plugin)
 
 	rb_debug ("inhibiting");
 	g_object_ref (plugin);
-	g_object_get (plugin->shell, "window", &window, NULL);
+
+	g_object_get (plugin, "object", &shell, NULL);
+	g_object_get (shell, "window", &window, NULL);
+	g_object_unref (shell);
+
 	xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (window)));
 	g_dbus_proxy_call (plugin->proxy,
 			   "Inhibit",
@@ -185,6 +178,7 @@ inhibit (RBGPMPlugin *plugin)
 		g_clear_error (&error);
 	}
 
+	g_object_unref (window);
 	return FALSE;
 }
 
@@ -208,6 +202,7 @@ uninhibit_done (GObject *proxy, GAsyncResult *res, RBGPMPlugin *plugin)
 
 		g_variant_unref (result);
 	}
+	g_object_unref (plugin);
 }
 
 static gboolean
@@ -232,7 +227,7 @@ uninhibit (RBGPMPlugin *plugin)
 			   -1,
 			   NULL,
 			   (GAsyncReadyCallback) uninhibit_done,
-			   plugin);
+			   g_object_ref (plugin));
 	return FALSE;
 }
 
@@ -253,17 +248,16 @@ playing_changed_cb (GObject *player, gboolean playing, RBGPMPlugin *plugin)
 }
 
 static void
-impl_activate (RBPlugin *rbplugin,
-	       RBShell *shell)
+impl_activate (PeasActivatable *bplugin)
 {
 	RBGPMPlugin *plugin;
 	GObject *shell_player;
 	gboolean playing;
+	RBShell *shell;
 
-	plugin = RB_GPM_PLUGIN (rbplugin);
-
-	plugin->shell = g_object_ref (shell);
+	plugin = RB_GPM_PLUGIN (bplugin);
 
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell, "shell-player", &shell_player, NULL);
 
 	plugin->handler_id = g_signal_connect_object (shell_player,
@@ -277,16 +271,17 @@ impl_activate (RBPlugin *rbplugin,
 	}
 
 	g_object_unref (shell_player);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate (RBPlugin *rbplugin,
-		 RBShell *shell)
+impl_deactivate (PeasActivatable *bplugin)
 {
 	RBGPMPlugin *plugin;
 	GObject *shell_player;
+	RBShell *shell;
 
-	plugin = RB_GPM_PLUGIN (rbplugin);
+	plugin = RB_GPM_PLUGIN (bplugin);
 
 	if (plugin->timeout_id != 0) {
 		g_source_remove (plugin->timeout_id);
@@ -298,6 +293,7 @@ impl_deactivate (RBPlugin *rbplugin,
 		plugin->cookie = 0;
 	}
 
+	g_object_get (plugin, "object", &shell, NULL);
 	g_object_get (shell, "shell-player", &shell_player, NULL);
 
 	if (plugin->handler_id != 0) {
@@ -305,7 +301,7 @@ impl_deactivate (RBPlugin *rbplugin,
 		plugin->handler_id = 0;
 	}
 
-	g_object_unref (plugin->shell);
+	g_object_unref (shell);
 	g_object_unref (shell_player);
 
 	if (plugin->proxy != NULL) {
@@ -313,3 +309,12 @@ impl_deactivate (RBPlugin *rbplugin,
 		plugin->proxy = NULL;
 	}
 }
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_gpm_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_GPM_PLUGIN);
+}
diff --git a/plugins/pythonconsole/Makefile.am b/plugins/pythonconsole/Makefile.am
index 2ee8979..dab71a8 100644
--- a/plugins/pythonconsole/Makefile.am
+++ b/plugins/pythonconsole/Makefile.am
@@ -2,10 +2,10 @@
 plugindir = $(PLUGINDIR)/python-console
 plugin_PYTHON = pythonconsole.py
 
-plugin_in_files = pythonconsole.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = pythonconsole.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/pythonconsole/pythonconsole.rb-plugin.in b/plugins/pythonconsole/pythonconsole.plugin.in
similarity index 92%
rename from plugins/pythonconsole/pythonconsole.rb-plugin.in
rename to plugins/pythonconsole/pythonconsole.plugin.in
index ab39a50..5811f69 100644
--- a/plugins/pythonconsole/pythonconsole.rb-plugin.in
+++ b/plugins/pythonconsole/pythonconsole.plugin.in
@@ -1,7 +1,7 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=pythonconsole
-IAge=1
+IAge=2
 _Name=Python Console
 _Description=Interactive python console
 Authors=Steve Frécinaux <steve istique net>
diff --git a/plugins/pythonconsole/pythonconsole.py b/plugins/pythonconsole/pythonconsole.py
index bd82b9f..a1c81af 100644
--- a/plugins/pythonconsole/pythonconsole.py
+++ b/plugins/pythonconsole/pythonconsole.py
@@ -36,9 +36,8 @@ import string
 import sys
 import re
 import traceback
-import gobject
 
-from gi.repository import Gtk, Gdk, Pango
+from gi.repository import Gtk, Gdk, GObject, Pango, Peas
 from gi.repository import RB
 
 try:
@@ -60,14 +59,19 @@ ui_str = """
 </ui>
 """
 
-class PythonConsolePlugin(RB.Plugin):
+class PythonConsolePlugin(GObject.Object, Peas.Activatable):
+	__gtype_name__ = 'PythonConsolePlugin'
+
+	object = GObject.property (type = GObject.Object)
+
 	def __init__(self):
-		RB.Plugin.__init__(self)
+		GObject.Object.__init__(self)
 		self.window = None
 			
-	def activate(self, shell):
+	def do_activate(self):
 		data = dict()
-		manager = shell.get_player().get_property('ui-manager')
+		shell = self.object
+		manager = shell.props.ui_manager
 		
 		data['action_group'] = Gtk.ActionGroup(name='PythonConsolePluginActions')
 
@@ -92,10 +96,11 @@ class PythonConsolePlugin(RB.Plugin):
 		
 		shell.set_data('PythonConsolePluginInfo', data)
 	
-	def deactivate(self, shell):
+	def do_deactivate(self):
+		shell = self.object
 		data = shell.get_data('PythonConsolePluginInfo')
 
-		manager = shell.get_player().get_property('ui-manager')
+		manager = shell.props.ui_manager
 		manager.remove_ui(data['ui_id'])
 		manager.remove_action_group(data['action_group'])
 		manager.ensure_update()
@@ -142,7 +147,7 @@ class PythonConsolePlugin(RB.Plugin):
 				rpdb2.start_embedded_debugger(password)
 				return False
 
-			gobject.idle_add(start_debugger, password)
+			GObject.idle_add(start_debugger, password)
 		dialog.destroy()
 	
 	def destroy_console(self, *args):
@@ -232,7 +237,7 @@ class PythonConsole(Gtk.ScrolledWindow):
 				cur = self.get_end_iter()
 				
 			buffer.place_cursor(cur)
-			gobject.idle_add(self.scroll_to_end)
+			GObject.idle_add(self.scroll_to_end)
 			return True
 		
 		elif event.keyval == Gdk.KEY_Return:
@@ -276,7 +281,7 @@ class PythonConsole(Gtk.ScrolledWindow):
 			cur = self.get_end_iter()
 			buffer.move_mark(inp_mark, cur)
 			buffer.place_cursor(cur)
-			gobject.idle_add(self.scroll_to_end)
+			GObject.idle_add(self.scroll_to_end)
 			return True
 
 		elif event.keyval == Gdk.KEY_KP_Down or \
@@ -284,7 +289,7 @@ class PythonConsole(Gtk.ScrolledWindow):
 			# Next entry from history
 			view.emit_stop_by_name("key_press_event")
 			self.history_down()
-			gobject.idle_add(self.scroll_to_end)
+			GObject.idle_add(self.scroll_to_end)
 			return True
 
 		elif event.keyval == Gdk.KEY_KP_Up or \
@@ -292,7 +297,7 @@ class PythonConsole(Gtk.ScrolledWindow):
 			# Previous entry from history
 			view.emit_stop_by_name("key_press_event")
 			self.history_up()
-			gobject.idle_add(self.scroll_to_end)
+			GObject.idle_add(self.scroll_to_end)
 			return True
 
 		elif event.keyval == Gdk.KEY_KP_Left or \
@@ -371,7 +376,7 @@ class PythonConsole(Gtk.ScrolledWindow):
 			start_iter = Gtk.TextIter()
 			start_iter = buffer.get_iter_at_offset(offset)
 			buffer.apply_tag(tag, start_iter, self.get_end_iter())
-		gobject.idle_add(self.scroll_to_end)
+		GObject.idle_add(self.scroll_to_end)
  	
  	def eval(self, command, display_command = False):
 		buffer = self.view.get_buffer()
diff --git a/plugins/rb-plugin-macros.h b/plugins/rb-plugin-macros.h
new file mode 100644
index 0000000..9fe9f2c
--- /dev/null
+++ b/plugins/rb-plugin-macros.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011  Jonathan Matthew <jonathan d14n 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301  USA.
+ */
+
+#ifndef RB_PLUGIN_MACROS_H
+#define RB_PLUGIN_MACROS_H
+
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+enum {
+	PROP_0,
+	PROP_OBJECT
+};
+
+#define RB_DEFINE_PLUGIN(TYPE_NAME, TypeName, type_name, TYPE_CODE)	\
+ GType type_name##_get_type (void) G_GNUC_CONST;			\
+ static void impl_activate (PeasActivatable *plugin);			\
+ static void impl_deactivate (PeasActivatable *plugin);			\
+ static void peas_activatable_iface_init (PeasActivatableInterface *iface); \
+ \
+ G_DEFINE_DYNAMIC_TYPE_EXTENDED (TypeName,				\
+		 		 type_name,				\
+		 		 PEAS_TYPE_EXTENSION_BASE,		\
+				 0,					\
+				 G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_TYPE_ACTIVATABLE,\
+					 			peas_activatable_iface_init)\
+		 		 TYPE_CODE)				\
+ \
+ static void peas_activatable_iface_init (PeasActivatableInterface *iface) \
+ {									\
+	iface->activate = impl_activate;				\
+	iface->deactivate = impl_deactivate;				\
+ }									\
+ \
+ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) \
+ {									\
+	switch (prop_id) {						\
+	case PROP_OBJECT:						\
+		g_object_set_data_full (object,				\
+					"rb-shell",			\
+					g_value_dup_object (value),	\
+					g_object_unref);		\
+		break;							\
+	default:							\
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); \
+		break;							\
+	}								\
+ }									\
+ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) \
+ {									\
+	switch (prop_id) {						\
+	case PROP_OBJECT:						\
+		g_value_set_object (value, g_object_get_data (object, "rb-shell")); \
+		break;							\
+	default:							\
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); \
+		break;							\
+	}								\
+ }									\
+ static void type_name##_class_init (TypeName##Class *klass)		\
+ {									\
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);		\
+	object_class->set_property = set_property;			\
+	object_class->get_property = get_property;			\
+	g_object_class_override_property (object_class, PROP_OBJECT, "object"); \
+ }									\
+ static void type_name##_class_finalize (TypeName##Class *klass)	\
+ {									\
+ }
+ 
+
+G_END_DECLS
+
+#endif /* RB_PLUGIN_MACROS_H */
diff --git a/plugins/rb/Loader.py b/plugins/rb/Loader.py
index 872bb57..8276001 100644
--- a/plugins/rb/Loader.py
+++ b/plugins/rb/Loader.py
@@ -24,7 +24,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
-import gobject
+import gobject, glib
 from gi.repository import Gdk, Gio
 import sys
 
diff --git a/plugins/rb/Makefile.am b/plugins/rb/Makefile.am
index 32baf37..569c407 100644
--- a/plugins/rb/Makefile.am
+++ b/plugins/rb/Makefile.am
@@ -5,5 +5,6 @@ plugin_PYTHON = \
 		Coroutine.py		\
 		URLCache.py		\
 		stringmatch.py		\
-		__init__.py
+		rb.py
 
+plugin_DATA = rb.plugin
diff --git a/plugins/rb/rb.plugin b/plugins/rb/rb.plugin
new file mode 100644
index 0000000..6625f02
--- /dev/null
+++ b/plugins/rb/rb.plugin
@@ -0,0 +1,7 @@
+[Plugin]
+Loader=python
+Module=rb
+Builtin=true
+IAge=2
+Name=Shared plugin code
+Description=Not actually a plugin
diff --git a/plugins/rb/__init__.py b/plugins/rb/rb.py
similarity index 92%
rename from plugins/rb/__init__.py
rename to plugins/rb/rb.py
index df817cb..925fc71 100644
--- a/plugins/rb/__init__.py
+++ b/plugins/rb/rb.py
@@ -56,8 +56,7 @@ def append_plugin_source_path(theme, iconpath):
 	# and if found, append the icon path
 	dir = filename[:filename.rfind(os.sep)]
 	if os.path.exists(dir + "/Makefile.am"):
-		plugindir = dir[:dir.rfind(os.sep)]
-		icondir = plugindir + iconpath
+		icondir = dir + iconpath
 		theme.append_search_path(icondir)
 
 def entry_equal(a, b):
@@ -67,6 +66,17 @@ def entry_equal(a, b):
 		return False
 	return a.get_string(RB.RhythmDBPropType.LOCATION) == b.get_string(RB.RhythmDBPropType.LOCATION)
 
+def find_plugin_file(plugin, filename):
+	info = plugin.plugin_info
+	data_dir = info.get_data_dir()
+	path = os.path.join(data_dir, filename)
+	print "looking for " + filename + " in " + data_dir
+	if os.path.exists(path):
+		return path
+
+	return RB.file(filename)
+
+
 class _rbdebugfile:
 	def __init__(self, fn):
 		self.fn = fn
diff --git a/plugins/rbzeitgeist/Makefile.am b/plugins/rbzeitgeist/Makefile.am
index eb8fa0d..ca59118 100644
--- a/plugins/rbzeitgeist/Makefile.am
+++ b/plugins/rbzeitgeist/Makefile.am
@@ -1,12 +1,12 @@
 # Zeitgeist Python Plugin
 
-plugin_in_files = rbzeitgeist.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = rbzeitgeist.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 plugindir = $(PLUGINDIR)/rbzeitgeist
-plugin_PYTHON = rbzeitgeist/__init__.py
+plugin_PYTHON = rbzeitgeist.py
 
 EXTRA_DIST = $(plugin_in_files) $(plugin_PYTHON)
 
diff --git a/plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in b/plugins/rbzeitgeist/rbzeitgeist.plugin.in
similarity index 88%
rename from plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in
rename to plugins/rbzeitgeist/rbzeitgeist.plugin.in
index 8a36dda..21be7d1 100644
--- a/plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in
+++ b/plugins/rbzeitgeist/rbzeitgeist.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=rbzeitgeist
-IAge=1
+IAge=2
+Depends=rb
 _Name=Zeitgeist
 _Description=Inform Zeitgeist about your activity
 Authors=Markus Korn <thekorn gmx de>
diff --git a/plugins/rbzeitgeist/rbzeitgeist/__init__.py b/plugins/rbzeitgeist/rbzeitgeist.py
similarity index 86%
rename from plugins/rbzeitgeist/rbzeitgeist/__init__.py
rename to plugins/rbzeitgeist/rbzeitgeist.py
index 10f0217..0b60126 100644
--- a/plugins/rbzeitgeist/rbzeitgeist/__init__.py
+++ b/plugins/rbzeitgeist/rbzeitgeist.py
@@ -27,10 +27,10 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
 import time
-import gobject
+import rb
 
+from gi.repository import GObject, Gio, GLib, Peas
 from gi.repository import RB
-from gi.repository import Gio
 
 from zeitgeist.client import ZeitgeistClient
 from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation
@@ -41,23 +41,25 @@ except RuntimeError, e:
     print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e
     IFACE = None
 
-class ZeitgeistPlugin(RB.Plugin):
+class ZeitgeistPlugin(GObject.Object, Peas.Activatable):
+    __gtype_name__ = 'ZeitgeistPlugin'
+    object = GObject.property(type=GObject.Object)
 
     def __init__(self):
-        RB.Plugin.__init__(self)
+	GObject.Object.__init__(self)
 
-    def activate(self, shell):
+    def do_activate(self):
         print "Loading Zeitgeist plugin..."
         if IFACE is not None:
-            shell_player = shell.get_player()
+	    shell = self.object
+            shell_player = shell.props.shell_player
             self.__psc_id = shell_player.connect("playing-song-changed", self.playing_song_changed)
 
-            backend_player = shell_player.get_property("player")
+            backend_player = shell_player.props.player
             self.__eos_id = backend_player.connect("eos", self.on_backend_eos)
 
             self.__manual_switch = True
             self.__current_song = None
-            self._shell = shell
 
             if IFACE.get_version() >= [0, 3, 2, 999]:
                 IFACE.register_data_source("org.gnome.Rhythmbox,dataprovider", "Rhythmbox", "Play and organize your music collection",
@@ -89,7 +91,7 @@ class ZeitgeistPlugin(RB.Plugin):
             self.send_to_zeitgeist_async(entry, Interpretation.ACCESS_EVENT)
 
         self.__current_song = entry
-        gobject.idle_add(self.reset_manual_switch)
+        GObject.idle_add(self.reset_manual_switch)
 
     def reset_manual_switch(self):
         """
@@ -107,8 +109,9 @@ class ZeitgeistPlugin(RB.Plugin):
         idle, it means there are no more signals scheduled, so we
         will have already received the eos if it was coming.
         """
-        db = self._shell.get_property("db")
-        gobject.idle_add(self.send_to_zeitgeist, db, entry, event_type)
+	shell = self.object
+        db = shell.props.db
+        GObject.idle_add(self.send_to_zeitgeist, db, entry, event_type)
 
     def send_to_zeitgeist(self, db, entry, event_type):
         song = self.get_song_info(db, entry)
@@ -144,18 +147,18 @@ class ZeitgeistPlugin(RB.Plugin):
             IFACE.insert_event(event)
 
         f = Gio.file_new_for_uri(song["location"])
-        f.query_info_async(Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, Gio.FileQueryInfoFlags.NONE, glib.PRIORITY_DEFAULT, None, file_info_complete)
+        f.query_info_async(Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_DEFAULT, None, file_info_complete, None)
 
-    def deactivate(self, shell):
-        print "Unloading Zeitgeist plugin..."
+    def do_deactivate(self):
+        print "Deactivating Zeitgeist plugin..."
         if IFACE is not None:
-            shell_player = shell.get_player()
+	    shell = self.object
+            shell_player = shell.props.shell_player
             shell_player.disconnect(self.__psc_id)
             self.__psc_id = None
 
-            backend_player = shell_player.get_property("player")
+            backend_player = shell_player.props.player
             backend_player.disconnect(self.__eos_id)
             self.__eos_id = None
 
-            self._shell = None
             self.__current_song = None
diff --git a/plugins/replaygain/Makefile.am b/plugins/replaygain/Makefile.am
index 6731456..616e549 100644
--- a/plugins/replaygain/Makefile.am
+++ b/plugins/replaygain/Makefile.am
@@ -1,19 +1,22 @@
-SUBDIRS = replaygain
-
 plugindir = $(PLUGINDIR)/replaygain
+plugindatadir = $(PLUGINDATADIR)/replaygain
+plugin_PYTHON =				\
+	config.py			\
+	player.py			\
+	replaygain.py
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_in_files = replaygain.rb-plugin.in
+plugin_in_files = replaygain.plugin.in
 
+gtkbuilderdir = $(plugindatadir)
 gtkbuilder_DATA =			\
 		replaygain-prefs.ui
 
-gtkbuilderdir = $(plugindir)
 EXTRA_DIST = $(plugin_in_files) $(gtkbuilder_DATA)
 CLEANFILES = $(plugin_DATA)
 DISTCLEANFILES = $(plugin_DATA)
 
-BUILT_SOURCES =	$(plugin_in_files:.rb-plugin.in=.rb-plugin)
+BUILT_SOURCES =	$(plugin_in_files:.plugin.in=.plugin)
 
 plugin_DATA = $(BUILT_SOURCES)
diff --git a/plugins/replaygain/replaygain/config.py b/plugins/replaygain/config.py
similarity index 86%
rename from plugins/replaygain/replaygain/config.py
rename to plugins/replaygain/config.py
index eccb44e..f354570 100644
--- a/plugins/replaygain/replaygain/config.py
+++ b/plugins/replaygain/config.py
@@ -25,10 +25,8 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 #
 
-import gobject
 import rb
-from gi.repository import Gtk
-from gi.repository import Gio
+from gi.repository import Gtk, Gio, GObject, PeasGtk
 from gi.repository import RB
 
 # modes
@@ -39,22 +37,18 @@ REPLAYGAIN_MODE_ALBUM = 1
 # to apply for tracks that aren't tagged
 AVERAGE_GAIN_SAMPLES = 10
 
-class ReplayGainConfigDialog(Gtk.Dialog):
-	def __init__(self, plugin):
-		Gtk.Dialog.__init__(self)
-		self.set_border_width(12)
+class ReplayGainConfig(GObject.Object, PeasGtk.Configurable):
+	__gtype_name__ = 'ReplayGainConfig'
+	object = GObject.property(type=GObject.Object)
 
+	def do_create_configure_widget(self):
 		self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.replaygain")
 
-		ui_file = plugin.find_file("replaygain-prefs.ui")
+		ui_file = rb.find_plugin_file(self, "replaygain-prefs.ui")
 		self.builder = Gtk.Builder()
 		self.builder.add_from_file(ui_file)
 
 		content = self.builder.get_object("replaygain-prefs")
-		self.get_content_area().add(content)
-
-		self.add_action_widget(Gtk.Button(stock=Gtk.STOCK_CLOSE), 0)
-		self.show_all()
 
 		label = self.builder.get_object("headerlabel")
 		label.set_markup("<b>%s</b>" % label.get_text())
@@ -75,6 +69,8 @@ class ReplayGainConfigDialog(Gtk.Dialog):
 		limiter = self.builder.get_object("limiter")
 		self.settings.bind("limiter", limiter, "active", Gio.SettingsBindFlags.DEFAULT)
 
+		return content
+
 	def preamp_changed_cb(self, preamp):
 		RB.settings_delayed_sync(self.settings, self.sync_preamp, preamp)
 
@@ -83,4 +79,4 @@ class ReplayGainConfigDialog(Gtk.Dialog):
 		print "preamp gain changed to %f" % v
 		settings['preamp'] = v
 
-gobject.type_register(ReplayGainConfigDialog)
+GObject.type_register(ReplayGainConfig)
diff --git a/plugins/replaygain/replaygain/player.py b/plugins/replaygain/player.py
similarity index 100%
rename from plugins/replaygain/replaygain/player.py
rename to plugins/replaygain/player.py
diff --git a/plugins/replaygain/replaygain.rb-plugin.in b/plugins/replaygain/replaygain.plugin.in
similarity index 89%
rename from plugins/replaygain/replaygain.rb-plugin.in
rename to plugins/replaygain/replaygain.plugin.in
index 3ed2279..746ab86 100644
--- a/plugins/replaygain/replaygain.rb-plugin.in
+++ b/plugins/replaygain/replaygain.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=replaygain
-IAge=1
+IAge=2
+Depends=rb
 _Name=ReplayGain
 _Description=Use ReplayGain to provide a consistent playback volume
 Authors=Jonathan Matthew
diff --git a/plugins/replaygain/replaygain/__init__.py b/plugins/replaygain/replaygain.py
similarity index 73%
rename from plugins/replaygain/replaygain/__init__.py
rename to plugins/replaygain/replaygain.py
index 8ad9ebb..8685078 100644
--- a/plugins/replaygain/replaygain/__init__.py
+++ b/plugins/replaygain/replaygain.py
@@ -26,32 +26,24 @@
 #
 
 import rb
+from gi.repository import GObject, Peas
 from gi.repository import RB
 
-from config import ReplayGainConfigDialog
+from config import ReplayGainConfig
 from player import ReplayGainPlayer
 
-class ReplayGainPlugin(RB.Plugin):
+class ReplayGainPlugin(GObject.Object, Peas.Activatable):
+	__gtype_name__ = 'ReplayGainPlugin'
+	object = GObject.property (type=GObject.Object)
 
 	def __init__ (self):
-		RB.Plugin.__init__ (self)
+		GObject.Object.__init__ (self)
 		self.config_dialog = None
 
-	def activate (self, shell):
-		self.player = ReplayGainPlayer(shell)
+	def do_activate (self):
+		self.player = ReplayGainPlayer(self.object)
 
-	def deactivate (self, shell):
+	def do_deactivate (self):
 		self.config_dialog = None
 		self.player.deactivate()
 		self.player = None
-
-	def create_configure_dialog(self, dialog=None):
-		if self.config_dialog is None:
-			self.config_dialog = ReplayGainConfigDialog(self)
-			self.config_dialog.connect('response', self.config_dialog_response_cb)
-
-		self.config_dialog.present()
-		return self.config_dialog
-
-	def config_dialog_response_cb(self, dialog, response):
-		dialog.hide()
diff --git a/plugins/sample-python/Makefile.am b/plugins/sample-python/Makefile.am
index 8ec0d78..118a426 100644
--- a/plugins/sample-python/Makefile.am
+++ b/plugins/sample-python/Makefile.am
@@ -1,11 +1,11 @@
 # sample python plugin
-plugindir = $(PLUGINDIR)
+plugindir = $(PLUGINDIR)/sample-python
 #plugin_PYTHON = sample-python.py
 
-plugin_in_files = sample-python.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = sample-python.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-#plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+#plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files) sample-python.py
 
diff --git a/plugins/sample-python/sample-python.rb-plugin.in b/plugins/sample-python/sample-python.plugin.in
similarity index 92%
rename from plugins/sample-python/sample-python.rb-plugin.in
rename to plugins/sample-python/sample-python.plugin.in
index 4fb3e49..e7c588e 100644
--- a/plugins/sample-python/sample-python.rb-plugin.in
+++ b/plugins/sample-python/sample-python.plugin.in
@@ -1,7 +1,7 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=sample-python
-IAge=1
+IAge=2
 _Name=Python Sample Plugin
 _Description=A sample plugin in Python with no features
 Authors=James Livingston <doclivingston gmail com>
diff --git a/plugins/sample-python/sample-python.py b/plugins/sample-python/sample-python.py
index 4db47f2..bcb17fb 100644
--- a/plugins/sample-python/sample-python.py
+++ b/plugins/sample-python/sample-python.py
@@ -1,29 +1,28 @@
-
-import gobject
-import rb
+from gi.repository import GObject, Peas
 from gi.repository import RB
 
-class SamplePython(RB.Plugin):
+class SamplePython(GObject.Object, Peas.Activatable):
+	__gtype_name = 'SamplePythonPlugin'
 
 	def __init__(self):
-		RB.Plugin.__init__(self)
+		GObject.Object.__init__(self)
 			
-	def activate(self, shell):
+	def do_activate(self):
 		print "activating sample python plugin"
 
-		db = shell.get_property("db")
+		shell = self.object
+		db = shell.props.db
 		model = db.query_model_new_empty()
 		self.source = gobject.new (PythonSource, shell=shell, name=_("Python Source"), query_model=model)
 		shell.append_source(self.source, None)
 	
-	def deactivate(self, shell):
+	def do_deactivate(self):
 		print "deactivating sample python plugin"
 		self.source.delete_thyself()
 		self.source = None
 
-
 class PythonSource(RB.Source):
 	def __init__(self):
 		RB.Source.__init__(self)
-		
-gobject.type_register(PythonSource)
+
+GObject.type_register_dynamic(PythonSource)
diff --git a/plugins/sample-vala/Makefile.am b/plugins/sample-vala/Makefile.am
index 9f0e7de..00e874d 100644
--- a/plugins/sample-vala/Makefile.am
+++ b/plugins/sample-vala/Makefile.am
@@ -33,16 +33,16 @@ INCLUDES = 						\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
 
-plugin_in_files = sample-vala.rb-plugin.in
+plugin_in_files = sample-vala.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po); $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po); $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
 VALAFLAGS = --vapidir=$(top_srcdir)/bindings/vala --pkg=rhythmdb --pkg=rb --pkg=gstreamer-0.10
 
 %.c %.h: %.vala
 	$(VALAC) -C $(VALAFLAGS) $^
 	
-# plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+# plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/sample-vala/rb-sample-vala-plugin.vala b/plugins/sample-vala/rb-sample-vala-plugin.vala
index 029805c..8b8c44a 100644
--- a/plugins/sample-vala/rb-sample-vala-plugin.vala
+++ b/plugins/sample-vala/rb-sample-vala-plugin.vala
@@ -1,22 +1,22 @@
 using GLib;
 using RB;
-using RhythmDB;
 
-class SampleValaPlugin: RB.Plugin {
-	public override void activate (RB.Shell shell) {
+class SampleValaPlugin: Peas.ExtensionBase, Peas.Activatable {
+	public override void activate () {
 		stdout.printf ("Hello world\n");
 	}
 
-	public override void deactivate (RB.Shell shell) {
+	public override void deactivate () {
 		stdout.printf ("Goodbye world\n");
 	}
 }
 
 
 [ModuleInit]
-public GLib.Type register_rb_plugin (GLib.TypeModule module)
+public void peas_register_types (GLib.TypeModule module) {
 {
+	var objmodule = module as Peas.ObjectModule;
 	stdout.printf ("Registering plugin %s\n", "SampleValaPlugin");
 
-	return typeof (SampleValaPlugin);
+	objmodule.register_extension_type (typeof (Peas.Activatable), typeof (SampleValaPlugin));
 }
diff --git a/plugins/sample-vala/sample-vala.rb-plugin.in b/plugins/sample-vala/sample-vala.plugin.in
similarity index 92%
rename from plugins/sample-vala/sample-vala.rb-plugin.in
rename to plugins/sample-vala/sample-vala.plugin.in
index 520f528..f3c382b 100644
--- a/plugins/sample-vala/sample-vala.rb-plugin.in
+++ b/plugins/sample-vala/sample-vala.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=sample-vala
-IAge=1
+IAge=2
 _Name=Vala Sample Plugin
 _Description=A sample plugin in Vala with no features
 Authors=James Livingston <doclivingston gmail com>
diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am
index 21ff446..bffd865 100644
--- a/plugins/sample/Makefile.am
+++ b/plugins/sample/Makefile.am
@@ -15,11 +15,9 @@ INCLUDES = 						\
 	-I$(top_srcdir) 				\
 	-I$(top_srcdir)/lib                        	\
 	-I$(top_srcdir)/metadata                       	\
-	-I$(top_srcdir)/player                       	\
 	-I$(top_srcdir)/rhythmdb                       	\
 	-I$(top_srcdir)/widgets                    	\
 	-I$(top_srcdir)/sources                    	\
-	-I$(top_srcdir)/iradio                    	\
 	-I$(top_srcdir)/podcast                    	\
 	-I$(top_srcdir)/plugins				\
 	-I$(top_srcdir)/shell				\
@@ -29,11 +27,11 @@ INCLUDES = 						\
 	$(RHYTHMBOX_CFLAGS)				\
 	-D_XOPEN_SOURCE -D_BSD_SOURCE
 
-plugin_in_files = sample.rb-plugin.in
+plugin_in_files = sample.plugin.in
 
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-#plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+#plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/sample/rb-sample-plugin.c b/plugins/sample/rb-sample-plugin.c
index 21dbc00..a97ac47 100644
--- a/plugins/sample/rb-sample-plugin.c
+++ b/plugins/sample/rb-sample-plugin.c
@@ -37,7 +37,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "rb-plugin.h"
+#include "rb-plugin-macros.h"
 #include "rb-debug.h"
 #include "rb-shell.h"
 #include "rb-dialog.h"
@@ -52,82 +52,48 @@
 
 typedef struct
 {
-	gpointer dummy;
-} RBSamplePluginPrivate;
-
-typedef struct
-{
-	RBPlugin parent;
-	RBSamplePluginPrivate *priv;
+	PeasExtensionBase parent;
 } RBSamplePlugin;
 
 typedef struct
 {
-	RBPluginClass parent_class;
+	PeasExtensionBaseClass parent_class;
 } RBSamplePluginClass;
 
 
-G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
-GType	rb_sample_plugin_get_type		(void) G_GNUC_CONST;
-
-
+G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
 
 static void rb_sample_plugin_init (RBSamplePlugin *plugin);
-static void rb_sample_plugin_finalize (GObject *object);
-static void impl_activate (RBPlugin *plugin, RBShell *shell);
-static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
-
-RB_PLUGIN_REGISTER(RBSamplePlugin, rb_sample_plugin)
-#define RB_SAMPLE_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), RB_TYPE_SAMPLE_PLUGIN, RBSamplePluginPrivate))
 
-
-static void
-rb_sample_plugin_class_init (RBSamplePluginClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
-
-	object_class->finalize = rb_sample_plugin_finalize;
-
-	plugin_class->activate = impl_activate;
-	plugin_class->deactivate = impl_deactivate;
-	
-	g_type_class_add_private (object_class, sizeof (RBSamplePluginPrivate));
-}
+RB_DEFINE_PLUGIN(RB_TYPE_SAMPLE_PLUGIN, RBSamplePlugin, rb_sample_plugin,)
 
 static void
 rb_sample_plugin_init (RBSamplePlugin *plugin)
 {
-	plugin->priv = RB_SAMPLE_PLUGIN_GET_PRIVATE (plugin);
-
 	rb_debug ("RBSamplePlugin initialising");
 }
 
 static void
-rb_sample_plugin_finalize (GObject *object)
+impl_activate (PeasActivatable *plugin)
 {
-/*
-	RBSamplePlugin *plugin = RB_SAMPLE_PLUGIN (object);
-*/
-	rb_debug ("RBSamplePlugin finalising");
-
-	G_OBJECT_CLASS (rb_sample_plugin_parent_class)->finalize (object);
-}
-
-
+	RBShell *shell;
 
-static void
-impl_activate (RBPlugin *plugin,
-	       RBShell *shell)
-{
+	g_object_get (plugin, "object", &shell, NULL);
 	rb_error_dialog (NULL, _("Sample Plugin"), "Sample plugin activated, with shell %p", shell);
+	g_object_unref (shell);
 }
 
 static void
-impl_deactivate	(RBPlugin *plugin,
-		 RBShell *shell)
+impl_deactivate	(PeasActivatable *plugin)
 {
 	rb_error_dialog (NULL, _("Sample Plugin"), "Sample plugin deactivated");
 }
 
-
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+	rb_sample_plugin_register_type (G_TYPE_MODULE (module));
+	peas_object_module_register_extension_type (module,
+						    PEAS_TYPE_ACTIVATABLE,
+						    RB_TYPE_SAMPLE_PLUGIN);
+}
diff --git a/plugins/sample/sample.rb-plugin.in b/plugins/sample/sample.plugin.in
similarity index 91%
rename from plugins/sample/sample.rb-plugin.in
rename to plugins/sample/sample.plugin.in
index fd4ab53..ddb0236 100644
--- a/plugins/sample/sample.rb-plugin.in
+++ b/plugins/sample/sample.plugin.in
@@ -1,6 +1,6 @@
-[RB Plugin]
+[Plugin]
 Module=sample
-IAge=1
+IAge=2
 _Name=Sample Plugin
 _Description=A sample plugin in C with no features
 Authors=Paolo Maggi <paolo gnome org>
diff --git a/plugins/sendto/Makefile.am b/plugins/sendto/Makefile.am
index 7b9a1a7..4e81968 100644
--- a/plugins/sendto/Makefile.am
+++ b/plugins/sendto/Makefile.am
@@ -1,11 +1,11 @@
 plugindir = $(PLUGINDIR)/sendto
 
-plugin_in_files = sendto.rb-plugin.in
-%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_in_files = sendto.plugin.in
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
 
-plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
 
-plugin_PYTHON = __init__.py
+plugin_PYTHON = sendto.py
 
 EXTRA_DIST = $(plugin_in_files)
 
diff --git a/plugins/sendto/sendto.rb-plugin.in b/plugins/sendto/sendto.plugin.in
similarity index 87%
rename from plugins/sendto/sendto.rb-plugin.in
rename to plugins/sendto/sendto.plugin.in
index d501ef8..267b5f6 100644
--- a/plugins/sendto/sendto.rb-plugin.in
+++ b/plugins/sendto/sendto.plugin.in
@@ -1,7 +1,8 @@
-[RB Plugin]
+[Plugin]
 Loader=python
 Module=sendto
-IAge=1
+IAge=2
+Depends=rb
 _Name=Send tracks
 _Description=Send selected tracks by email or instant message
 Authors=Filipp Ivanov <feelout ut ee>
diff --git a/plugins/sendto/__init__.py b/plugins/sendto/sendto.py
similarity index 89%
rename from plugins/sendto/__init__.py
rename to plugins/sendto/sendto.py
index ac1431e..4c6ddea 100644
--- a/plugins/sendto/__init__.py
+++ b/plugins/sendto/sendto.py
@@ -26,7 +26,7 @@
 
 import glib
 import rb
-from gi.repository import Gtk
+from gi.repository import Gtk, GObject, Peas
 from gi.repository import RB
 
 ui_definition = """
@@ -44,14 +44,19 @@ ui_definition = """
     </popup>
 </ui>"""
 
-class SendToPlugin (RB.Plugin):
+class SendToPlugin (GObject.Object, Peas.Activatable):
+    __gtype_name__ = 'SendToPlugin'
+
+    object = GObject.property (type = GObject.Object)
+
     def __init__(self):
-        RB.Plugin.__init__(self)
+        GObject.Object.__init__(self)
 
-    def activate(self, shell):
+    def do_activate(self):
         self.__action = Gtk.Action(name='SendTo', label=_('Send to...'),
                                 tooltip=_('Send files by mail, instant message...'),
                                 stock_id='')
+	shell = self.object
         self.__action.connect('activate', self.send_to, shell)
 
         self.__action_group = Gtk.ActionGroup(name='SendToActionGroup')
@@ -60,7 +65,8 @@ class SendToPlugin (RB.Plugin):
 
         self.__ui_id = shell.get_ui_manager().add_ui_from_string(ui_definition)
 
-    def deactivate(self, shell):
+    def do_deactivate(self):
+	shell = self.object
         shell.get_ui_manager().remove_action_group(self.__action_group)
         shell.get_ui_manager().remove_ui(self.__ui_id)
         shell.get_ui_manager().ensure_update()
diff --git a/shell/rb-shell.c b/shell/rb-shell.c
index aaf5e97..78b6131 100644
--- a/shell/rb-shell.c
+++ b/shell/rb-shell.c
@@ -1608,7 +1608,7 @@ construct_plugins (RBShell *shell)
 	rb_debug ("plugin search path: %s / %s", plugindir, plugindatadir);
 	peas_engine_add_search_path (shell->priv->plugin_engine,
 				     plugindir,
-				     /*plugindatadir*/ plugindir);
+				     plugindatadir);
 	g_free (plugindir);
 	g_free (plugindatadir);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]