diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index b8cd421..2729adb 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -47,7 +47,6 @@ check_include_files(fstab.h       HAVE_FSTAB_H)                        # kio, kd
 check_include_files(limits.h      HAVE_LIMITS_H)                       # various
 check_include_files(mntent.h      HAVE_MNTENT_H)                       # solid, kio, kdecore
 check_include_files(sysent.h      HAVE_SYSENT_H)                       # kdecore
-check_include_files("sys/types.h;sys/mman.h" HAVE_SYS_MMAN_H)          # kdecore
 check_include_files(sys/stat.h    HAVE_SYS_STAT_H)                     # various
 check_include_files(sys/ucred.h   HAVE_SYS_UCRED_H)                    # kio
 check_include_files(sys/types.h   HAVE_SYS_TYPES_H)                    # various
@@ -58,7 +57,6 @@ check_include_files(sys/mntent.h  HAVE_SYS_MNTENT_H)                   # solid,
 check_include_files("sys/param.h;sys/mount.h"  HAVE_SYS_MOUNT_H)       # kio, kdecore
 check_include_files(unistd.h      HAVE_UNISTD_H)                       # various
 check_include_files(stdint.h      HAVE_STDINT_H)                       # various
-check_include_files("sys/types.h;netinet/in.h"  HAVE_NETINET_IN_H)     # kio
 check_include_files(paths.h       HAVE_PATHS_H)                        # kdecore, kio
 
 check_include_files(errno.h       HAVE_ERRNO_H)                        # kjs, errno.h is used in many places, but only guarded in kjs/
@@ -67,9 +65,6 @@ check_include_files(valgrind/memcheck.h   HAVE_VALGRIND_MEMCHECK_H)    # khtml
 check_include_files(crtdbg.h      HAVE_CRTDBG_H)                       # kjs
 check_include_files(langinfo.h    HAVE_LANGINFO_H)                     # kdecore
 
-check_include_files(arpa/nameser_compat.h HAVE_ARPA_NAMESER_COMPAT_H) # kio
-check_include_files(arpa/nameser8_compat.h HAVE_ARPA_NAMESER8_COMPAT_H) # kio
-
 macro_bool_to_01(X11_XTest_FOUND HAVE_XTEST)                                                   # kdecore
 macro_bool_to_01(X11_Xcursor_FOUND HAVE_XCURSOR)                                               # kdeui
 macro_bool_to_01(X11_Xfixes_FOUND HAVE_XFIXES)                                                 # kdeui
@@ -99,11 +94,6 @@ if(NOT APPLE)
 endif(NOT APPLE)
 check_function_exists(mmap             HAVE_MMAP)                     # kdecore, khtml
 
-if(NOT WIN32)
-  # we don't have it on windows but need to export it to be backward compatible
-  # can be removed when 4.1 is out
-  check_function_exists(readdir_r     HAVE_READDIR_R)                 # kio
-endif(NOT WIN32)
 check_function_exists(sendfile        HAVE_SENDFILE)                  # kioslave
 check_function_exists(srandom         HAVE_SRANDOM)                   # config.h
 check_function_exists(_NSGetEnviron   HAVE_NSGETENVIRON)              # kinit, config.h
@@ -254,7 +244,6 @@ check_prototype_exists(unsetenv stdlib.h            HAVE_UNSETENV_PROTO)
 check_prototype_exists(usleep unistd.h              HAVE_USLEEP_PROTO)
 check_prototype_exists(initgroups "unistd.h;sys/types.h;unistd.h;grp.h" HAVE_INITGROUPS_PROTO)
 check_prototype_exists(setreuid unistd.h            HAVE_SETREUID_PROTO)
-check_prototype_exists(seteuid unistd.h             HAVE_SETEUID_PROTO)
 check_prototype_exists(trunc math.h                 HAVE_TRUNC)
 
 # check for existing datatypes
diff --git a/cmake/modules/FindNepomuk.cmake b/cmake/modules/FindNepomuk.cmake
index 10c995c..b822aee 100644
--- a/cmake/modules/FindNepomuk.cmake
+++ b/cmake/modules/FindNepomuk.cmake
@@ -79,7 +79,7 @@ include(FindPackageHandleStandardArgs)
 if(NOT WINCE)
 find_package_handle_standard_args(Nepomuk  DEFAULT_MSG
                                   NEPOMUK_LIBRARIES NEPOMUK_INCLUDE_DIR NEPOMUK_ADDONTOLOGYCLASSES_FILE
-                                  Soprano_FOUND SOPRANO_PLUGIN_RAPTORPARSER_FOUND SOPRANO_PLUGIN_REDLANDBACKEND_FOUND
+                                  Soprano_FOUND
                                   SHAREDDESKTOPONTOLOGIES_FOUND
                                   )
 else(NOT WINCE)
diff --git a/config.h.cmake b/config.h.cmake
index d5708aa..86ca906 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -50,12 +50,8 @@
 #cmakedefine HAVE_FSTAB_H 1
 #cmakedefine HAVE_LIMITS_H 1
 #cmakedefine HAVE_MNTENT_H 1
-#cmakedefine HAVE_NETINET_IN_H 1
 #cmakedefine HAVE_PATHS_H 1
-#cmakedefine HAVE_SYS_MMAN_H 1
 #cmakedefine HAVE_UNISTD_H 1
-#cmakedefine HAVE_ARPA_NAMESER_COMPAT_H
-#cmakedefine HAVE_ARPA_NAMESER8_COMPAT_H
 
 #cmakedefine HAVE_XTEST 1
 
@@ -79,7 +75,6 @@
 #cmakedefine   HAVE_MKSTEMP 1
 #cmakedefine   HAVE_MKDTEMP 1
 #cmakedefine   HAVE_RANDOM 1
-#cmakedefine   HAVE_READDIR_R 1
 #cmakedefine   HAVE_SENDFILE 1
 #cmakedefine   HAVE_SETENV 1
 #cmakedefine   HAVE_SETEUID 1
diff --git a/kdecore/CMakeLists.txt b/kdecore/CMakeLists.txt
index 550ec30..5525901 100644
--- a/kdecore/CMakeLists.txt
+++ b/kdecore/CMakeLists.txt
@@ -44,6 +44,11 @@ configure_file(auth/BackendsConfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/BackendsC
 # Configure checks for localization
 configure_file(localization/config-localization.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-localization.h)
 
+# Configure checks for util
+include(util/ConfigureChecks.cmake)
+configure_file(util/config-util.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-util.h)
+
+
 include_directories( ${KDE4_KDECORE_INCLUDES} )
 include_directories( ${ZLIB_INCLUDE_DIR} )
 include_directories( ${QT_INCLUDES} )
diff --git a/kdecore/io/kmountpoint.cpp b/kdecore/io/kmountpoint.cpp
index aa7a6b1..e5df5dc 100644
--- a/kdecore/io/kmountpoint.cpp
+++ b/kdecore/io/kmountpoint.cpp
@@ -513,14 +513,15 @@ KMountPoint::Ptr KMountPoint::List::findByDevice(const QString& device) const
 
 bool KMountPoint::probablySlow() const
 {
-    bool nfs = d->mountType == QLatin1String("nfs");
+    bool nfs    = d->mountType == QLatin1String("nfs");
     bool autofs = d->mountType == QLatin1String("autofs") || d->mountType == QLatin1String("subfs");
+    bool fuse   = d->mountType.startsWith(QLatin1String("fuse."));
     //bool pid = d->mountPoint.contains(":(pid");
     // The "pid" thing was in kde3's KIO::probably_slow_mounted, with obscure logic
     // (looks like it used state from the previous line or something...)
     // This needs to be revised once we have a testcase or explanation about it.
     // But autofs works already, it shows nfs as mountType in mtab.
-    if (nfs || autofs) {
+    if (nfs || autofs || fuse) {
         return true;
     }
     return false;
diff --git a/kdecore/sonnet/globals.cpp b/kdecore/sonnet/globals.cpp
index ef57aa7..bf4f504 100644
--- a/kdecore/sonnet/globals.cpp
+++ b/kdecore/sonnet/globals.cpp
@@ -83,6 +83,9 @@ QString detectLanguage(const QString &sentence)
     return max.key();
 }
 
+// SLOW!!!
+// TODO: cache this value! And then use some dbus signal to notify all apps when
+// changing the default language changes.
 QString defaultLanguageName()
 {
   Loader *loader = Loader::openLoader();
diff --git a/kdecore/util/ConfigureChecks.cmake b/kdecore/util/ConfigureChecks.cmake
new file mode 100644
index 0000000..fe9f47e
--- /dev/null
+++ b/kdecore/util/ConfigureChecks.cmake
@@ -0,0 +1,4 @@
+include(CheckIncludeFiles)
+check_include_files("sys/types.h;sys/mman.h" HAVE_SYS_MMAN_H)
+
+
diff --git a/kdecore/util/config-util.h.cmake b/kdecore/util/config-util.h.cmake
new file mode 100644
index 0000000..83ccdf7
--- /dev/null
+++ b/kdecore/util/config-util.h.cmake
@@ -0,0 +1,2 @@
+#cmakedefine01 HAVE_SYS_MMAN_H
+
diff --git a/kdecore/util/kshareddatacache_p.h b/kdecore/util/kshareddatacache_p.h
index 8bf9cf6..931de4d 100644
--- a/kdecore/util/kshareddatacache_p.h
+++ b/kdecore/util/kshareddatacache_p.h
@@ -20,7 +20,7 @@
 #ifndef KSHAREDDATACACHE_P_H
 #define KSHAREDDATACACHE_P_H
 
-#include <config.h> // HAVE_SYS_MMAN_H
+#include <config-util.h> // HAVE_SYS_MMAN_H
 
 #include <QtCore/QSharedPointer>
 #include <QtCore/QBasicAtomicInt>
@@ -82,7 +82,7 @@ int ksdcArea();
 #endif
 
 // BSD/Mac OS X compat
-#ifdef HAVE_SYS_MMAN_H
+#if HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif
 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
diff --git a/kdeui/actions/kstandardaction.cpp b/kdeui/actions/kstandardaction.cpp
index 2b20078..7de0c6f 100644
--- a/kdeui/actions/kstandardaction.cpp
+++ b/kdeui/actions/kstandardaction.cpp
@@ -544,8 +544,8 @@ KToggleAction *showStatusbar(const QObject *recvr, const char *slot, QObject *pa
   KToggleAction *ret = new KToggleAction(i18n( "Show St&atusbar" ), parent);
   ret->setObjectName(name(ShowStatusbar));
 
-  ret->setWhatsThis( i18n( "Show Statusbar<br /><br />"
-                           "Shows the statusbar, which is the bar at the bottom of the window used for status information." ) );
+  ret->setWhatsThis( i18n( "Show Statusbar<p>"
+                           "Shows the statusbar, which is the bar at the bottom of the window used for status information.</p>" ) );
 
   ret->setChecked( true );
 
diff --git a/kdeui/fonts/kfontchooser.cpp b/kdeui/fonts/kfontchooser.cpp
index 819dc1d..d243574 100644
--- a/kdeui/fonts/kfontchooser.cpp
+++ b/kdeui/fonts/kfontchooser.cpp
@@ -295,7 +295,7 @@ KFontChooser::KFontChooser( QWidget *parent,
     }
     // Populate usual styles, to determine minimum list width;
     // will be replaced later with correct styles.
-    d->styleListBox->addItem(i18nc("@item font","Regular"));
+    d->styleListBox->addItem(I18NC_NOX("QFontDatabase", "Normal"));
     d->styleListBox->addItem(i18nc("@item font","Italic"));
     d->styleListBox->addItem(i18nc("@item font","Oblique"));
     d->styleListBox->addItem(i18nc("@item font","Bold"));
@@ -628,12 +628,13 @@ void KFontChooser::Private::_k_family_chosen_slot(const QString& family)
         if (style == I18NC_NOX("QFontDatabase", "Normal"))
             styleMod = i18nc("@item font", "Regular");
 
+
         // i18n: Filtering message, so that translators can script the
         // style string according to the font family name (e.g. may need
         // noun-adjective congruence wrt. gender of the family name).
         // The message provides the dynamic context 'family', which is
         // the family name to which the style string corresponds.
-        QString fstyle = ki18nc("@item Font style", "%1").subs(styleMod).inContext("family", pureFamily).toString();
+        QString fstyle = ki18nc("@item Font style", "%1").subs(style).inContext("family", pureFamily).toString();
         if (!filteredStyles.contains(fstyle)) {
             filteredStyles.append(fstyle);
             qtStyles.insert(fstyle, style);
@@ -644,7 +645,7 @@ void KFontChooser::Private::_k_family_chosen_slot(const QString& family)
     styleListBox->addItems(filteredStyles);
 
     // Try to set the current style in the listbox to that previous.
-    int listPos = filteredStyles.indexOf(selectedStyle.isEmpty() ?  i18nc("@item font", "Regular") : selectedStyle);
+    int listPos = filteredStyles.indexOf(selectedStyle.isEmpty() ?  I18NC_NOX("QFontDatabase", "Normal") : selectedStyle);
     if (listPos < 0) {
         // Make extra effort to have Italic selected when Oblique was chosen,
         // and vice versa, as that is what the user would probably want.
diff --git a/kdeui/kernel/kstartupinfo.cpp b/kdeui/kernel/kstartupinfo.cpp
index bdc8972..87548c2 100644
--- a/kdeui/kernel/kstartupinfo.cpp
+++ b/kdeui/kernel/kstartupinfo.cpp
@@ -1140,6 +1140,7 @@ bool KStartupInfoId::operator<( const KStartupInfoId& id_P ) const
     return id() < id_P.id();
     }
 
+// KDE5 TODO: rename to isNull ?
 bool KStartupInfoId::none() const
     {
     return d->id.isEmpty() || d->id == "0";
diff --git a/kdeui/widgets/klineedit.cpp b/kdeui/widgets/klineedit.cpp
index 9756ef7..d96c1c4 100644
--- a/kdeui/widgets/klineedit.cpp
+++ b/kdeui/widgets/klineedit.cpp
@@ -336,25 +336,22 @@ void KLineEdit::updateClearButtonIcon(const QString& text)
         return;
     }
 
-    int clearButtonState = KIconLoader::DefaultState;
+    // set proper icon if necessary
+    if (d->clearButton->pixmap().isNull()) {
+        const int clearButtonState = KIconLoader::DefaultState;
+        if (layoutDirection() == Qt::LeftToRight) {
+            d->clearButton->setPixmap(SmallIcon("edit-clear-locationbar-rtl", 0, clearButtonState));
+        } else {
+            d->clearButton->setPixmap(SmallIcon("edit-clear-locationbar-ltr", 0, clearButtonState));
+        }
+    }
 
+    // trigger animation
     if (d->wideEnoughForClear && text.length() > 0) {
         d->clearButton->animateVisible(true);
     } else {
         d->clearButton->animateVisible(false);
     }
-
-    if (!d->clearButton->pixmap().isNull()) {
-        return;
-    }
-
-    if (layoutDirection() == Qt::LeftToRight) {
-        d->clearButton->setPixmap(SmallIcon("edit-clear-locationbar-rtl", 0, clearButtonState));
-    } else {
-        d->clearButton->setPixmap(SmallIcon("edit-clear-locationbar-ltr", 0, clearButtonState));
-    }
-
-    d->clearButton->setVisible(text.length() > 0);
 }
 
 // Determine geometry of clear button. Called initially, and on resizeEvent.
diff --git a/kdeui/widgets/klineedit_p.h b/kdeui/widgets/klineedit_p.h
index 95016bd..f7df463 100644
--- a/kdeui/widgets/klineedit_p.h
+++ b/kdeui/widgets/klineedit_p.h
@@ -56,7 +56,7 @@ public:
     void animateVisible(bool visible)
     {
         if (visible) {
-            if (m_animation->direction() == QPropertyAnimation::Forward) {
+            if (m_animation->direction() == QPropertyAnimation::Forward && m_opacity == 255) {
                 return;
             }
 
@@ -64,7 +64,7 @@ public:
             m_animation->setDuration(150);
             show();
         } else {
-            if (m_animation->direction() == QPropertyAnimation::Backward) {
+            if (m_animation->direction() == QPropertyAnimation::Backward && m_opacity == 0) {
                 return;
             }
 
diff --git a/kio/kfile/kpropertiesdialog.cpp b/kio/kfile/kpropertiesdialog.cpp
index feb0c9e..223ac7c 100644
--- a/kio/kfile/kpropertiesdialog.cpp
+++ b/kio/kfile/kpropertiesdialog.cpp
@@ -945,29 +945,26 @@ KFilePropsPlugin::KFilePropsPlugin( KPropertiesDialog *_props )
     QLabel *l;
     if (!mimeComment.isEmpty() && !isTrash) {
         l = new QLabel(i18n("Type:"), d->m_frame );
+        grid->addWidget(l, curRow, 0, Qt::AlignRight | Qt::AlignTop);
 
-        grid->addWidget(l, curRow, 0, Qt::AlignRight);
-
-        KHBox *box = new KHBox(d->m_frame);
-        box->setSpacing(20); // ### why 20?
+        KVBox *box = new KVBox(d->m_frame);
+        box->setSpacing(2); // without that spacing the button literally “sticks” to the label ;)
         l = new QLabel(mimeComment, box );
+        grid->addWidget(box, curRow++, 2);
 
         QPushButton *button = new QPushButton(box);
-
+        button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);  // Minimum still makes the button grow to the entire layout width
         button->setIcon( KIcon(QString::fromLatin1("configure")) );
-        const int pixmapSize = button->style()->pixelMetric(QStyle::PM_SmallIconSize);
-        button->setFixedSize( pixmapSize+8, pixmapSize+8 );
+
         if ( d->mimeType == KMimeType::defaultMimeType() )
-            button->setToolTip(i18n("Create new file type"));
+            button->setText(i18n("Create New File Type"));
         else
-            button->setToolTip(i18n("Edit file type"));
+            button->setText(i18n("File Type Options"));
 
         connect( button, SIGNAL(clicked()), SLOT(slotEditFileType()));
 
         if (!KAuthorized::authorizeKAction("editfiletype"))
             button->hide();
-
-        grid->addWidget(box, curRow++, 2);
     }
 
     if ( !magicMimeComment.isEmpty() && magicMimeComment != mimeComment )
diff --git a/kio/misc/kpac/CMakeLists.txt b/kio/misc/kpac/CMakeLists.txt
index 3c21e13..81fa79a 100644
--- a/kio/misc/kpac/CMakeLists.txt
+++ b/kio/misc/kpac/CMakeLists.txt
@@ -12,7 +12,7 @@ if(NOT KPAC_NO_SOLID)
 endif(NOT KPAC_NO_SOLID)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}")
-
+include(ConfigureChecks.cmake)
 configure_file(config-kpac.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kpac.h)
 
 ########### next target ###############
diff --git a/kio/misc/kpac/ConfigureChecks.cmake b/kio/misc/kpac/ConfigureChecks.cmake
new file mode 100644
index 0000000..47994b4
--- /dev/null
+++ b/kio/misc/kpac/ConfigureChecks.cmake
@@ -0,0 +1,4 @@
+include(CheckIncludeFiles)
+check_include_files(arpa/nameser_compat.h HAVE_ARPA_NAMESER_COMPAT_H)
+check_include_files(arpa/nameser8_compat.h HAVE_ARPA_NAMESER8_COMPAT_H)
+check_include_files("sys/types.h;netinet/in.h"  HAVE_NETINET_IN_H) 
diff --git a/kio/misc/kpac/config-kpac.h.cmake b/kio/misc/kpac/config-kpac.h.cmake
index 58356e6..5a53614 100644
--- a/kio/misc/kpac/config-kpac.h.cmake
+++ b/kio/misc/kpac/config-kpac.h.cmake
@@ -1 +1,4 @@
 #cmakedefine KPAC_NO_SOLID
+#cmakedefine HAVE_ARPA_NAMESER_COMPAT_H
+#cmakedefine HAVE_ARPA_NAMESER8_COMPAT_H
+#cmakedefine HAVE_NETINET_IN_H 1
diff --git a/kio/misc/kpac/discovery.cpp b/kio/misc/kpac/discovery.cpp
index a196879..b2266f8 100644
--- a/kio/misc/kpac/discovery.cpp
+++ b/kio/misc/kpac/discovery.cpp
@@ -19,7 +19,7 @@
 
 
 #include <config.h>
-
+#include <config-kpac.h>
 #include <netdb.h>
 #include <unistd.h>
 
diff --git a/kparts/CMakeLists.txt b/kparts/CMakeLists.txt
index 2eab2e8..60f17ef 100644
--- a/kparts/CMakeLists.txt
+++ b/kparts/CMakeLists.txt
@@ -30,9 +30,23 @@ set(kparts_LIB_SRCS
    textextension.cpp
    htmlextension.cpp
    fileinfoextension.cpp
+
+   # Private classes from libkactivities
+   private/libkactivities/manager_p.cpp
+   private/libkactivities/resourceinstance.cpp
+
    listingextension.cpp
    )
 
+
+# D-Bus connection to the activity manager
+qt4_add_dbus_interface(
+   kparts_LIB_SRCS
+   private/libkactivities/org.kde.ActivityManager.xml
+   activitymanager_interface
+)
+
+
 kde4_add_library(kparts ${LIBRARY_TYPE} ${kparts_LIB_SRCS})
 
 target_link_libraries(kparts  ${KDE4_KDECORE_LIBS} kdeui kio)
@@ -42,8 +56,8 @@ if(HAVE_NEPOMUK)
   target_link_libraries(kparts  LINK_INTERFACE_LIBRARIES nepomuk nepomukutils )
 endif(HAVE_NEPOMUK)
 
-set_target_properties(kparts PROPERTIES VERSION ${GENERIC_LIB_VERSION} 
-                                        SOVERSION ${GENERIC_LIB_SOVERSION} 
+set_target_properties(kparts PROPERTIES VERSION ${GENERIC_LIB_VERSION}
+                                        SOVERSION ${GENERIC_LIB_SOVERSION}
                      )
 
 
diff --git a/kparts/part.cpp b/kparts/part.cpp
index f74bd78..a5769f5 100644
--- a/kparts/part.cpp
+++ b/kparts/part.cpp
@@ -26,6 +26,9 @@
 #include "partmanager.h"
 #include "browserextension.h"
 
+// the activity manager feeder (kamd)
+#include "private/libkactivities/resourceinstance.h"
+
 #include <QtGui/QApplication>
 #include <QtCore/QFile>
 #include <QtCore/QFileInfo>
@@ -380,6 +383,7 @@ public:
         m_duringSaveAs = false;
         m_bTemp = false;
         m_bAutoDetectedMime = false;
+        m_resourceInstance = 0;
     }
 
     ~ReadOnlyPartPrivate()
@@ -389,6 +393,8 @@ public:
     void _k_slotJobFinished( KJob * job );
     void _k_slotStatJobFinished(KJob * job);
     void _k_slotGotMimeType(KIO::Job *job, const QString &mime);
+    void _k_slotOpeningCompleted();
+    void _k_slotWindowCaptionChanged(const QString & caption);
     bool openLocalFile();
     void openRemoteFile();
 
@@ -421,6 +427,13 @@ public:
     QString m_file;
 
     OpenUrlArguments m_arguments;
+
+    /**
+     * Class for talking to the activity manager (kamd)
+     */
+    KActivities::ResourceInstance * m_resourceInstance;
+    QString m_resourceCaption;
+
 };
 
 class ReadWritePartPrivate: public ReadOnlyPartPrivate
@@ -450,11 +463,23 @@ public:
 ReadOnlyPart::ReadOnlyPart( QObject *parent )
     : Part( *new ReadOnlyPartPrivate(this), parent )
 {
+    QObject::connect(
+            this, SIGNAL(completed()),
+            this, SLOT(_k_slotOpeningCompleted())
+        );
+    QObject::connect(
+            this, SIGNAL(setWindowCaption(QString)),
+            this, SLOT(_k_slotWindowCaptionChanged(QString))
+        );
 }
 
 ReadOnlyPart::ReadOnlyPart( ReadOnlyPartPrivate &dd, QObject *parent )
     : Part( dd, parent )
 {
+    QObject::connect(
+            this, SIGNAL(completed()),
+            this, SLOT(_k_slotOpeningCompleted())
+        );
 }
 
 ReadOnlyPart::~ReadOnlyPart()
@@ -473,6 +498,10 @@ void ReadOnlyPart::setUrl(const KUrl &url)
 {
     Q_D(ReadOnlyPart);
 
+    if (d->m_resourceInstance) {
+        d->m_resourceInstance->setUri(url);
+    }
+
     d->m_url = url;
 }
 
@@ -658,6 +687,17 @@ bool ReadOnlyPart::closeUrl()
     // It always succeeds for a read-only part,
     // but the return value exists for reimplementations
     // (e.g. pressing cancel for a modified read-write part)
+
+    // Feeding the data to the activity manager (kamd)
+    kDebug(1000)
+        << "A component named"
+        << KGlobal::mainComponent().componentName()
+        << "has closed the"
+        << url();
+    delete d->m_resourceInstance;
+    d->m_resourceInstance = 0; // just in case
+    // Finished with the activity manager
+
     return true;
 }
 
@@ -697,9 +737,53 @@ void ReadOnlyPartPrivate::_k_slotJobFinished( KJob * job )
     }
 }
 
+void ReadOnlyPartPrivate::_k_slotOpeningCompleted()
+{
+    Q_Q(ReadOnlyPart);
+
+    // Feeding the data to the activity manager (kamd)
+    kDebug(1000)
+        << "A component named"
+        << KGlobal::mainComponent().componentName()
+        << "is opening the"
+        << q->url()
+        << ( q->widget() ? q->widget()->topLevelWidget()->winId() : 0 )
+        << "mime"
+        << m_arguments.mimeType()
+        << "title"
+        << m_resourceCaption;
+
+    // deleting the previous one
+    delete m_resourceInstance;
+
+    m_resourceInstance = new KActivities::ResourceInstance(
+            ( q->widget() ? q->widget()->topLevelWidget()->winId() : 0 ), // wid
+            q->url(),                                               // resourceUri
+            m_arguments.mimeType(),                                 // mimetype
+            m_resourceCaption,                                      // title
+            KActivities::ResourceInstance::User,                    // accessReason
+            KGlobal::mainComponent().componentName(),               // application
+            q                                                       // parent
+            );
+    // Finished with the activity manager
+}
+
+void ReadOnlyPartPrivate::_k_slotWindowCaptionChanged(const QString & caption)
+{
+    kDebug(1000) << "This is the new caption" << caption;
+
+    m_resourceCaption = caption;
+
+    if (m_resourceInstance) {
+        kDebug(1000) << "KAMD: resource caption" << caption;
+        m_resourceInstance->setTitle(caption);
+    }
+}
+
 void ReadOnlyPartPrivate::_k_slotGotMimeType(KIO::Job *job, const QString &mime)
 {
-    kDebug(1000) << mime;
+    kDebug(1000) << "This is the mime type we got" << mime;
+
     Q_ASSERT(job == m_job); Q_UNUSED(job)
     // set the mimetype only if it was not already set (for example, by the host application)
     if (m_arguments.mimeType().isEmpty()) {
@@ -731,6 +815,13 @@ bool ReadOnlyPart::openStream( const QString& mimeType, const KUrl& url )
         return false;
     d->m_arguments = args;
     d->m_url = url;
+
+    kDebug(1000)
+        << "A component named"
+        << KGlobal::mainComponent().componentName()
+        << "is opening the stream"
+        << url << mimeType;
+
     return doOpenStream( mimeType );
 }
 
@@ -796,6 +887,12 @@ void ReadWritePart::setModified( bool modified )
         kError(1000) << "Can't set a read-only document to 'modified' !" << endl;
         return;
     }
+
+    if ( modified && d->m_resourceInstance ) {
+        kDebug(1000) << "Notifying kamd of the change";
+        d->m_resourceInstance->notifyModified();
+    }
+
     d->m_bModified = modified;
 }
 
diff --git a/kparts/part.h b/kparts/part.h
index 56b64da..f62f2d7 100644
--- a/kparts/part.h
+++ b/kparts/part.h
@@ -717,6 +717,9 @@ private:
     Q_PRIVATE_SLOT(d_func(), void _k_slotStatJobFinished(KJob*))
     Q_PRIVATE_SLOT(d_func(), void _k_slotGotMimeType(KIO::Job *job, const QString &mime))
 
+    Q_PRIVATE_SLOT(d_func(), void _k_slotOpeningCompleted())
+    Q_PRIVATE_SLOT(d_func(), void _k_slotWindowCaptionChanged(const QString & caption))
+
     Q_DISABLE_COPY(ReadOnlyPart)
 };
 class ReadWritePartPrivate;
diff --git a/kparts/private/libkactivities/CMakeLists.txt b/kparts/private/libkactivities/CMakeLists.txt
new file mode 100644
index 0000000..e164126
--- /dev/null
+++ b/kparts/private/libkactivities/CMakeLists.txt
@@ -0,0 +1,152 @@
+project(kactivities)
+
+cmake_minimum_required(VERSION 2.8)
+
+FIND_PACKAGE(KDE4 REQUIRED)
+INCLUDE(KDE4Defaults)
+INCLUDE(MacroLibrary)
+INCLUDE(MacroOptionalAddSubdirectory)
+INCLUDE(FindPackageHandleStandardArgs)
+
+# =======================================================
+# Information to update before to release this library.
+
+# Library version history:
+# API      ABI
+# 0.1.0 => 0.1.0
+# 0.1.1 => 0.1.1
+# 0.2.0 => 0.2.0
+
+# Library API version
+SET(KACTIVITIES_LIB_MAJOR_VERSION "6")
+SET(KACTIVITIES_LIB_MINOR_VERSION "0")
+SET(KACTIVITIES_LIB_PATCH_VERSION "0")
+
+# Suffix to add at end of version string. Usual values are:
+# "-git"   : alpha code unstable from git. Do not use in production
+# "-beta1" : beta1 release.
+# "-beta2" : beta2 release.
+# "-beta3" : beta3 release.
+# "-rc"    : release candidate.
+# ""       : final relase. Can be used in production.
+SET(KACTIVITIES_LIB_SUFFIX_VERSION "")
+
+# Library ABI version used by linker.
+# For details : http://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
+SET(KACTIVITIES_LIB_SO_CUR_VERSION "6")
+SET(KACTIVITIES_LIB_SO_REV_VERSION "0")
+SET(KACTIVITIES_LIB_SO_AGE_VERSION "0")
+
+# =======================================================
+# Set env. variables accordinly.
+
+set(KACTIVITIES_INCLUDE_DIR
+    "${CMAKE_CURRENT_SOURCE_DIR}/.."
+    "${CMAKE_CURRENT_SOURCE_DIR}/"
+    CACHE STRING
+    "Location of libkactivities headers" FORCE)
+set(KACTIVITIES_LIBS
+    "kactivities"
+    CACHE STRING
+    "Location of libkactivities binary" FORCE)
+
+SET(KACTIVITIES_LIB_VERSION_STRING "${KACTIVITIES_LIB_MAJOR_VERSION}.${KACTIVITIES_LIB_MINOR_VERSION}.${KACTIVITIES_LIB_PATCH_VERSION}${KACTIVITIES_LIB_SUFFIX_VERSION}")
+SET(KACTIVITIES_LIB_VERSION_ID "0x0${KACTIVITIES_LIB_MAJOR_VERSION}0${KACTIVITIES_LIB_MINOR_VERSION}0${KACTIVITIES_LIB_PATCH_VERSION}")
+SET(KACTIVITIES_LIB_SO_VERSION_STRING "${KACTIVITIES_LIB_SO_CUR_VERSION}.${KACTIVITIES_LIB_SO_REV_VERSION}.${KACTIVITIES_LIB_SO_AGE_VERSION}")
+
+ADD_DEFINITIONS (${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS} ${KDE4_DEFINITIONS})
+INCLUDE_DIRECTORIES (${QDBUS_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
+
+include_directories(
+   ${CMAKE_SOURCE_DIR}
+   ${CMAKE_BINARY_DIR}
+   ${KDE4_INCLUDES}
+   ${KDE4_KIO_INCLUDES}
+   )
+
+set(
+   kactivities_LIB_SRCS
+
+   consumer.cpp
+   controller.cpp
+   info.cpp
+   manager_p.cpp
+   resourceinstance.cpp
+   )
+
+qt4_add_dbus_interface(
+   kactivities_LIB_SRCS
+
+   org.kde.ActivityManager.xml
+   activitymanager_interface
+)
+
+
+kde4_add_library(
+   kactivities SHARED
+   ${kactivities_LIB_SRCS}
+   )
+
+
+set_target_properties(
+   kactivities
+   PROPERTIES
+   VERSION ${KACTIVITIES_LIB_SO_VERSION_STRING}
+   SOVERSION ${KACTIVITIES_LIB_SO_CUR_VERSION}
+   )
+
+target_link_libraries(
+   kactivities
+   ${KDE4_KDECORE_LIBS}
+   )
+
+## install
+
+set(
+   kactivities_LIB_HEADERS
+   consumer.h
+   controller.h
+   info.h
+   resourceinstance.h
+   )
+
+set(
+   kactivities_LIB_PRETTY_HEADERS
+   includes/KActivities/Consumer
+   includes/KActivities/Controller
+   includes/KActivities/Info
+   includes/KActivities/ResourceInstance
+   )
+
+install(
+   FILES ${kactivities_LIB_HEADERS}
+   DESTINATION ${INCLUDE_INSTALL_DIR}/kactivities
+   COMPONENT Devel
+   )
+
+install(
+   FILES ${kactivities_LIB_PRETTY_HEADERS}
+   DESTINATION ${INCLUDE_INSTALL_DIR}/KDE/KActivities
+   COMPONENT Devel
+   )
+
+install(
+   TARGETS kactivities
+   EXPORT kdelibsLibraryTargets
+   ${INSTALL_TARGETS_DEFAULT_ARGS}
+   )
+
+IF(NOT WIN32)
+  CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libkactivities.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libkactivities.pc)
+  INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libkactivities.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
+ENDIF(NOT WIN32)
+
+CONFIGURE_FILE(
+    KActivitiesConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/KActivitiesConfig.cmake @ONLY
+)
+
+INSTALL(
+    FILES ${CMAKE_CURRENT_BINARY_DIR}/KActivitiesConfig.cmake
+    DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/cmake/KActivities
+)
+
diff --git a/kparts/private/libkactivities/manager_p.cpp b/kparts/private/libkactivities/manager_p.cpp
new file mode 100644
index 0000000..e71aec8
--- /dev/null
+++ b/kparts/private/libkactivities/manager_p.cpp
@@ -0,0 +1,89 @@
+/*
+ *   Copyright (C) 2010 Ivan Cukic <ivan.cukic(at)kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "manager_p.h"
+
+#include <QDBusConnection>
+
+#include <ktoolinvocation.h>
+#include <kdebug.h>
+
+namespace KActivities {
+
+Manager * Manager::s_instance = NULL;
+
+// #define ACTIVITY_MANAGER_DBUS_PATH   "org.kde.ActivityManager"
+#define ACTIVITY_MANAGER_DBUS_PATH   "org.kde.kactivitymanagerd"
+#define ACTIVITY_MANAGER_DBUS_OBJECT "/ActivityManager"
+
+Manager::Manager()
+    : org::kde::ActivityManager(
+            ACTIVITY_MANAGER_DBUS_PATH,
+            ACTIVITY_MANAGER_DBUS_OBJECT,
+            QDBusConnection::sessionBus()
+            )
+{
+    connect(&m_watcher, SIGNAL(serviceOwnerChanged(const QString &, const QString &, const QString &)),
+            this, SLOT(serviceOwnerChanged(const QString &, const QString &, const QString &)));
+}
+
+Manager * Manager::self()
+{
+    if (!s_instance) {
+        // check if the activity manager is already running
+        if (!isActivityServiceRunning()) {
+
+            // not running, trying to launch it
+            QString error;
+
+            int ret = KToolInvocation::startServiceByDesktopPath("kactivitymanagerd.desktop", QStringList(), &error);
+            if (ret > 0) {
+                kDebug() << "Activity: Couldn't start kactivitymanagerd: " << error << endl;
+            }
+
+            if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(ACTIVITY_MANAGER_DBUS_PATH)) {
+                kDebug() << "Activity: The kactivitymanagerd service is still not registered";
+            } else {
+                kDebug() << "Activity: The kactivitymanagerd service has been registered";
+            }
+        }
+
+        // creating a new instance of the class
+        s_instance = new Manager();
+    }
+
+    return s_instance;
+}
+
+bool Manager::isActivityServiceRunning()
+{
+    return QDBusConnection::sessionBus().interface()->isServiceRegistered(ACTIVITY_MANAGER_DBUS_PATH);
+}
+
+void Manager::serviceOwnerChanged(const QString & serviceName, const QString & oldOwner, const QString & newOwner)
+{
+    Q_UNUSED(oldOwner)
+
+    if (serviceName == ACTIVITY_MANAGER_DBUS_PATH) {
+        emit presenceChanged(!newOwner.isEmpty());
+    }
+}
+
+} // namespace KActivities
+
diff --git a/kparts/private/libkactivities/manager_p.h b/kparts/private/libkactivities/manager_p.h
new file mode 100644
index 0000000..b92a94f
--- /dev/null
+++ b/kparts/private/libkactivities/manager_p.h
@@ -0,0 +1,52 @@
+/*
+ *   Copyright (C) 2010 Ivan Cukic <ivan.cukic(at)kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef ACTIVITIES_MANAGER_P_
+#define ACTIVITIES_MANAGER_P_
+
+#include "activitymanager_interface.h"
+
+#include <QDBusServiceWatcher>
+
+namespace KActivities {
+
+class Manager: public org::kde::ActivityManager {
+    Q_OBJECT
+public:
+    static Manager * self();
+
+    static bool isActivityServiceRunning();
+
+public Q_SLOTS:
+    void serviceOwnerChanged(const QString & serviceName, const QString & oldOwner, const QString & newOwner);
+
+Q_SIGNALS:
+    void presenceChanged(bool present);
+
+private:
+    Manager();
+
+    QDBusServiceWatcher m_watcher;
+
+    static Manager * s_instance;
+};
+
+} // namespace KActivities
+
+#endif // ACTIVITIES_MANAGER_P_
diff --git a/kparts/private/libkactivities/org.kde.ActivityManager.xml b/kparts/private/libkactivities/org.kde.ActivityManager.xml
new file mode 100644
index 0000000..07a5b34
--- /dev/null
+++ b/kparts/private/libkactivities/org.kde.ActivityManager.xml
@@ -0,0 +1,118 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+  <interface name="org.kde.ActivityManager">
+    <signal name="CurrentActivityChanged">
+      <arg name="id" type="s" direction="out"/>
+    </signal>
+    <signal name="ActivityAdded">
+      <arg name="id" type="s" direction="out"/>
+    </signal>
+    <signal name="ActivityStarted">
+      <arg name="id" type="s" direction="out"/>
+    </signal>
+    <signal name="ActivityStopped">
+      <arg name="id" type="s" direction="out"/>
+    </signal>
+    <signal name="ActivityRemoved">
+      <arg name="id" type="s" direction="out"/>
+    </signal>
+    <signal name="ActivityChanged">
+      <arg name="id" type="s" direction="out"/>
+    </signal>
+    <signal name="ActivityStateChanged">
+      <arg name="id" type="s" direction="out"/>
+      <arg name="state" type="i" direction="out"/>
+    </signal>
+    <method name="Start">
+    </method>
+    <method name="Stop">
+    </method>
+    <method name="CurrentActivity">
+      <arg type="s" direction="out"/>
+    </method>
+    <method name="SetCurrentActivity">
+      <arg type="b" direction="out"/>
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="AddActivity">
+      <arg type="s" direction="out"/>
+      <arg name="name" type="s" direction="in"/>
+    </method>
+    <method name="StartActivity">
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="StopActivity">
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="ActivityState">
+      <arg type="i" direction="out"/>
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="RemoveActivity">
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="ListActivities">
+      <arg type="as" direction="out"/>
+    </method>
+    <method name="ListActivities">
+      <arg type="as" direction="out"/>
+      <arg name="state" type="i" direction="in"/>
+    </method>
+    <method name="ActivityName">
+      <arg type="s" direction="out"/>
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="SetActivityName">
+      <arg name="id" type="s" direction="in"/>
+      <arg name="name" type="s" direction="in"/>
+    </method>
+    <method name="ActivityDescription">
+      <arg type="s" direction="out"/>
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="SetActivityDescription">
+      <arg name="id" type="s" direction="in"/>
+      <arg name="description" type="s" direction="in"/>
+    </method>
+    <method name="ActivityIcon">
+      <arg type="s" direction="out"/>
+      <arg name="id" type="s" direction="in"/>
+    </method>
+    <method name="SetActivityIcon">
+      <arg name="id" type="s" direction="in"/>
+      <arg name="icon" type="s" direction="in"/>
+    </method>
+    <method name="IsBackstoreAvailable">
+      <arg type="b" direction="out"/>
+    </method>
+    <method name="RegisterResourceEvent">
+      <arg name="application" type="s" direction="in"/>
+      <arg name="windowId" type="u" direction="in"/>
+      <arg name="uri" type="s" direction="in"/>
+      <arg name="event" type="u" direction="in"/>
+      <arg name="reason" type="u" direction="in"/>
+    </method>
+    <method name="RegisterResourceMimeType">
+      <arg name="uri" type="s" direction="in"/>
+      <arg name="mimetype" type="s" direction="in"/>
+    </method>
+    <method name="RegisterResourceTitle">
+      <arg name="uri" type="s" direction="in"/>
+      <arg name="title" type="s" direction="in"/>
+    </method>
+    <method name="LinkResourceToActivity">
+      <arg name="uri" type="s" direction="in"/>
+      <arg name="activity" type="s" direction="in"/>
+    </method>
+    <method name="LinkResourceToActivity">
+      <arg name="uri" type="s" direction="in"/>
+    </method>
+    <!-- <method name="UnlinkResourceFromActivity"> -->
+    <!--   <arg name="uri" type="s" direction="in"/> -->
+    <!--   <arg name="activity" type="s" direction="in"/> -->
+    <!-- </method> -->
+    <!-- <method name="UnlinkResourceFromActivity"> -->
+    <!--   <arg name="uri" type="s" direction="in"/> -->
+    <!-- </method> -->
+  </interface>
+</node>
diff --git a/kparts/private/libkactivities/resourceinstance.cpp b/kparts/private/libkactivities/resourceinstance.cpp
new file mode 100644
index 0000000..6bf3925
--- /dev/null
+++ b/kparts/private/libkactivities/resourceinstance.cpp
@@ -0,0 +1,180 @@
+/*
+ *   Copyright (C) 2011 Ivan Cukic <ivan.cukic(at)kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "resourceinstance.h"
+#include "manager_p.h"
+
+#include <QCoreApplication>
+
+namespace KActivities {
+
+#ifdef Q_OS_WIN64
+__inline int toInt(WId wid)
+{
+	return (int)((__int64)wid);
+}
+
+#else
+__inline int toInt(WId wid)
+{
+	return (int)wid;
+}
+#endif
+
+class ResourceInstancePrivate {
+public:
+    WId wid;
+    ResourceInstance::AccessReason reason;
+    QUrl uri;
+    QString mimetype;
+    QString title;
+    QString application;
+
+    void closeResource();
+    void openResource();
+
+    enum Type {
+        Accessed = 0,
+        Opened = 1,
+        Modified = 2,
+        Closed = 3,
+        FocusedIn = 4,
+        FocusedOut = 5
+    };
+
+    static void registerResourceEvent(const QString &application, WId wid, const QUrl &uri, Type event, ResourceInstance::AccessReason reason)
+    {
+        Manager::self()->RegisterResourceEvent(application, toInt(wid), uri.toString(), uint(event), uint(reason));
+    }
+};
+
+void ResourceInstancePrivate::closeResource()
+{
+    registerResourceEvent(application, wid, uri, Closed, reason);
+}
+
+void ResourceInstancePrivate::openResource()
+{
+    registerResourceEvent(application, wid, uri, Opened, reason);
+}
+
+ResourceInstance::ResourceInstance(WId wid, AccessReason reason, const QString &application, QObject *parent)
+    : QObject(parent), d(new ResourceInstancePrivate())
+{
+    d->wid = wid;
+    d->reason = reason;
+    d->application = application.isEmpty() ? QCoreApplication::instance()->applicationName() : application;
+
+}
+
+ResourceInstance::ResourceInstance(WId wid, QUrl resourceUri, const QString &mimetype, const QString &title, AccessReason reason, const QString &application, QObject *parent)
+    : QObject(parent), d(new ResourceInstancePrivate())
+{
+    d->wid = wid;
+    d->reason = reason;
+    d->uri = resourceUri;
+    d->mimetype = mimetype;
+    d->title = title;
+    d->application = application.isEmpty() ? QCoreApplication::instance()->applicationName() : application;
+
+    d->openResource();
+}
+
+ResourceInstance::~ResourceInstance()
+{
+    d->closeResource();
+    delete d;
+}
+
+void ResourceInstance::notifyModified()
+{
+    d->registerResourceEvent(d->application, d->wid, d->uri, ResourceInstancePrivate::Modified, d->reason);
+}
+
+void ResourceInstance::notifyFocusedIn()
+{
+    d->registerResourceEvent(d->application, d->wid, d->uri, ResourceInstancePrivate::FocusedIn, d->reason);
+}
+
+void ResourceInstance::notifyFocusedOut()
+{
+    d->registerResourceEvent(d->application, d->wid, d->uri, ResourceInstancePrivate::FocusedOut, d->reason);
+}
+
+void ResourceInstance::setUri(const QUrl &newUri)
+{
+    if (d->uri == newUri)
+        return;
+
+    if (!d->uri.isEmpty()) {
+        d->closeResource();
+    }
+
+    d->uri = newUri;
+
+    d->openResource();
+}
+
+void ResourceInstance::setMimetype(const QString &mimetype)
+{
+    d->mimetype = mimetype;
+    // TODO: update the service info
+    Manager::self()->RegisterResourceMimeType(d->uri.toString(), mimetype);
+}
+
+void ResourceInstance::setTitle(const QString &title)
+{
+    d->title = title;
+    // TODO: update the service info
+    Manager::self()->RegisterResourceTitle(d->uri.toString(), title);
+}
+
+QUrl ResourceInstance::uri() const
+{
+    return d->uri;
+}
+
+QString ResourceInstance::mimetype() const
+{
+    return d->mimetype;
+}
+
+QString ResourceInstance::title() const
+{
+    return d->title;
+}
+
+WId ResourceInstance::winId() const
+{
+    return d->wid;
+}
+
+ResourceInstance::AccessReason ResourceInstance::accessReason() const
+{
+    return d->reason;
+}
+
+void ResourceInstance::notifyAccessed(const QUrl &uri, const QString &application)
+{
+    ResourceInstancePrivate::registerResourceEvent(
+            application.isEmpty() ? QCoreApplication::instance()->applicationName() : application,
+            0, uri, ResourceInstancePrivate::Accessed, User);
+}
+
+} // namespace KActivities
diff --git a/kparts/private/libkactivities/resourceinstance.h b/kparts/private/libkactivities/resourceinstance.h
new file mode 100644
index 0000000..d1cbab4
--- /dev/null
+++ b/kparts/private/libkactivities/resourceinstance.h
@@ -0,0 +1,214 @@
+/*
+ *   Copyright (C) 2011 Ivan Cukic <ivan.cukic(at)kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef ACTIVITIES_RESOURCEINSTANCE_H_
+#define ACTIVITIES_RESOURCEINSTANCE_H_
+
+#include <QObject>
+#include <QWidget>
+#include <QUrl>
+
+#include <kdemacros.h>
+
+namespace KActivities {
+
+class ResourceInstancePrivate;
+
+/**
+ * This class is used to notify the system that a file, web page
+ * or some other resource has been accessed.
+ *
+ * It provides methods to notify the system when the resource was
+ * opened, modified and closed, along with in what window the
+ * resource is shown.
+ *
+ * You should create an instance of this class for every resource
+ * you open.
+ *
+ * "The system" in this case can be the backend for tracking
+ * and automatically scoring files that are being accessed, the
+ * system to show the open files per window in the taskbar,
+ * the share-like-connect, etc.
+ *
+ * The user of this class shouldn't care about the backend
+ * systems - everything is done under-the-hood automatically.
+ *
+ */
+class KDE_EXPORT ResourceInstance: public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QUrl uri READ uri WRITE setUri)
+    Q_PROPERTY(QString mimetype READ mimetype WRITE setMimetype)
+    Q_PROPERTY(QString title READ title WRITE setTitle)
+    Q_PROPERTY(WId winId READ winId)
+    Q_PROPERTY(AccessReason accessReason READ accessReason)
+
+public:
+    /***
+     * The reason for opening the resource
+     */
+    enum AccessReason {
+         User = 0,      ///< Due to an explicit user request
+         Scheduled = 1, ///< As a result of a user-scheduled action
+         Heuristic = 2, ///< Deduced from user's activity, or indirectly requested
+         System = 3,    ///< Due to a system event
+         World = 4      ///< Due to an action performed by an external entity
+    };
+    Q_ENUMS(AccessReason)
+
+    /**
+     * Creates a new resource instance
+     * @param wid id of the window that will show the resource
+     * @param reason reason for opening the resource
+     * @param application application's name (the name used for the .desktop file).
+     *        If not specified, QCoreApplication::applicationName is used
+     * @param parent pointer to the parent object
+     */
+    ResourceInstance(WId wid, AccessReason reason = User, const QString &application = QString(), QObject *parent = 0);
+
+    /**
+     * Creates a new resource instance and automatically
+     * notifies the system that it was opened.
+     *
+     * In some special cases, where the URI of the resource is
+     * being constantly changed (for example, in the world globe,
+     * street map applications) you have two options:
+     *  - to pass an empty resourceUri while passing the mimetype
+     *  - to update the uri from time to time (in the example of
+     *    the world map - to send URIs for major objects - cities
+     *    or main streets.
+     * and in both cases reimplementing the currentUri() method
+     * which will return the exact URI shown at that specific moment.
+     *
+     * @param wid window id in which the resource is shown
+     * @param resourceUri URI of the resource that is shown
+     * @param mimetype the mime type of the resource
+     * @param title the title of the resource
+     * @param reason reason for opening the resource
+     * @param application application's name (the name used for the .desktop file).
+     *        If not specified, QCoreApplication::applicationName is used
+     * @param parent pointer to the parent object
+     */
+    ResourceInstance(WId wid, QUrl resourceUri, const QString &mimetype = QString(), const QString &title = QString(), AccessReason reason = User, const QString &application = QString(), QObject *parent = 0);
+
+    /**
+     * Destroys the ResourceInstance and notifies the system
+     * that the resource has been closed
+     */
+    ~ResourceInstance();
+
+public Q_SLOTS:
+    /**
+     * Call this method to notify the system that you modified
+     * (the contents of) the resource
+     */
+    void notifyModified();
+
+    /**
+     * Call this method to notify the system that the resource
+     * has the focus in your application
+     * @note You only need to call this in MDI applications
+     */
+    void notifyFocusedIn();
+
+    /**
+     * Call this method to notify the system that the resource
+     * lost the focus in your application
+     * @note You only need to call this in MDI applications
+     */
+    void notifyFocusedOut();
+
+    /**
+     * This is a convenience method that sets the new URI.
+     * This is usually handled by sending the close event for
+     * the previous URI, and an open event for the new one.
+     */
+    void setUri(const QUrl &newUri);
+
+    /**
+     * Sets the mimetype for this resource
+     */
+    void setMimetype(const QString &mimetype);
+
+    /**
+     * Sets the title for this resource
+     */
+    void setTitle(const QString &title);
+
+Q_SIGNALS:
+    /**
+     * Emitted when the system wants to show the resource
+     * represented by this ResourceInstance.
+     *
+     * You should listen to this signal if you have multiple
+     * resources shown in one window (MDI). On catching it, show
+     * the resource and give it focus.
+     */
+    void requestsFocus();
+
+public:
+    /**
+     * @returns the current uri
+     * The default implementation returns the URI that was passed
+     * to the constructor.
+     * You need to reimplement it only for the applications with
+     * frequently updated URIs.
+     */
+    virtual QUrl uri() const;
+
+    /**
+     * @returns mimetype of the resource
+     */
+    QString mimetype() const;
+
+    /**
+     * @returns title of the resource
+     */
+    QString title() const;
+
+    /**
+     * @returns the window id
+     */
+    WId winId() const;
+
+    /**
+     * @returns the reason for accessing the resource
+     */
+    AccessReason accessReason() const;
+
+    /**
+     * If there's no way to tell for how long an application is keeping
+     * the resource open, you can just call this static method - it
+     * will notify the system that the application has accessed the
+     * resource
+     * @param uri URI of the resource
+     * @param application application's name (the name used for the .desktop file).
+     *        If not specified, QCoreApplication::applicationName is used
+     *
+     */
+    static void  notifyAccessed(const QUrl &uri, const QString &application = QString());
+
+private:
+    ResourceInstancePrivate * const d;
+};
+
+}
+
+#endif // ACTIVITIES_RESOURCEINSTANCE_H_
diff --git a/nepomuk/query/queryserviceclient.cpp b/nepomuk/query/queryserviceclient.cpp
index ddabff7..7d3ef0f 100644
--- a/nepomuk/query/queryserviceclient.cpp
+++ b/nepomuk/query/queryserviceclient.cpp
@@ -100,9 +100,12 @@ public:
     void _k_entriesRemoved( const QStringList& );
     void _k_finishedListing();
     void _k_handleQueryReply(QDBusPendingCallWatcher*);
+    void _k_serviceRegistered( const QString& );
+    void _k_serviceUnregistered( const QString& );
 
     org::kde::nepomuk::QueryService* queryServiceInterface;
     org::kde::nepomuk::Query* queryInterface;
+    QDBusServiceWatcher *queryServiceWatcher;
 
     QueryServiceClient* q;
 
@@ -169,6 +172,27 @@ void Nepomuk::Query::QueryServiceClient::Private::_k_handleQueryReply(QDBusPendi
 }
 
 
+void Nepomuk::Query::QueryServiceClient::Private::_k_serviceRegistered(const QString &service)
+{
+    if (service == "org.kde.nepomuk.services.nepomukqueryservice") {
+        delete queryServiceInterface;
+        queryServiceInterface = new org::kde::nepomuk::QueryService( "org.kde.nepomuk.services.nepomukqueryservice",
+                                                                        "/nepomukqueryservice",
+                                                                        dbusConnection );
+        emit q->serviceAvailabilityChanged(true);
+    }
+}
+
+
+void Nepomuk::Query::QueryServiceClient::Private::_k_serviceUnregistered(const QString &service)
+{
+    if (service == "org.kde.nepomuk.services.nepomukqueryservice") {
+        emit q->serviceAvailabilityChanged(false);
+    }
+}
+
+
+
 
 Nepomuk::Query::QueryServiceClient::QueryServiceClient( QObject* parent )
     : QObject( parent ),
@@ -182,6 +206,12 @@ Nepomuk::Query::QueryServiceClient::QueryServiceClient( QObject* parent )
     d->queryServiceInterface = new org::kde::nepomuk::QueryService( "org.kde.nepomuk.services.nepomukqueryservice",
                                                                     "/nepomukqueryservice",
                                                                     d->dbusConnection );
+    d->queryServiceWatcher = new QDBusServiceWatcher(QLatin1String("org.kde.nepomuk.services.nepomukqueryservice"),
+                                                     QDBusConnection::sessionBus(),
+                                                     QDBusServiceWatcher::WatchForOwnerChange,
+                                                     this);
+    connect(d->queryServiceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(_k_serviceRegistered(QString)));
+    connect(d->queryServiceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(_k_serviceUnregistered(QString)));
 }
 
 
diff --git a/nepomuk/query/queryserviceclient.h b/nepomuk/query/queryserviceclient.h
index 234d4b0..d41bfc0 100644
--- a/nepomuk/query/queryserviceclient.h
+++ b/nepomuk/query/queryserviceclient.h
@@ -320,6 +320,13 @@ namespace Nepomuk {
              */
             void error( const QString& errorMessage );
 
+            /**
+             * Emitted when the availability of the query service changes
+             *
+             * \since 4.8
+             */
+            void serviceAvailabilityChanged( bool running );
+
         private:
             class Private;
             Private* const d;
@@ -327,6 +334,8 @@ namespace Nepomuk {
             Q_PRIVATE_SLOT( d, void _k_entriesRemoved( const QStringList& ) )
             Q_PRIVATE_SLOT( d, void _k_finishedListing() )
             Q_PRIVATE_SLOT( d, void _k_handleQueryReply(QDBusPendingCallWatcher*) )
+            Q_PRIVATE_SLOT( d, void _k_serviceRegistered( const QString& ) )
+            Q_PRIVATE_SLOT( d, void _k_serviceUnregistered( const QString& ) )
         };
     }
 }
diff --git a/plasma/CMakeLists.txt b/plasma/CMakeLists.txt
index c179882..982c590 100644
--- a/plasma/CMakeLists.txt
+++ b/plasma/CMakeLists.txt
@@ -6,10 +6,15 @@ if(KDE_PLATFORM_FEATURE_BINARY_COMPATIBLE_FEATURE_REDUCTION)
     set(PLASMA_NO_KNEWSTUFF TRUE)
     set(PLASMA_NO_SOLID TRUE)
     set(PLASMA_NO_KIO TRUE)
+    set(PLASMA_NO_PACKAGEKIT TRUE)
     set(PLASMA_NO_KUTILS TRUE)
     set(PLASMA_NO_GLOBAL_SHORTCUTS TRUE)
 endif(KDE_PLATFORM_FEATURE_BINARY_COMPATIBLE_FEATURE_REDUCTION)
 
+if(NOT Q_WS_X11)
+    set(PLASMA_NO_PACKAGEKIT TRUE)
+endif(NOT Q_WS_X11)
+
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}
                     ${KDE4_KDECORE_INCLUDES}
                     ${KDE4_KDEUI_INCLUDES}
@@ -44,6 +49,11 @@ if(NOT PLASMA_NO_SOLID)
     set(PLASMA_EXTRA_LIBS ${PLASMA_EXTRA_LIBS} ${KDE4_SOLID_LIBS})
 endif(NOT PLASMA_NO_SOLID)
 
+if(NOT PLASMA_NO_PACKAGEKIT)
+    add_definitions(-DPLASMA_ENABLE_PACKAGEKIT_SUPPORT=1)
+    set(PLASMA_EXTRA_LIBS ${PLASMA_EXTRA_LIBS} ${QT_QTDBUS_LIBRARY})
+endif(NOT PLASMA_NO_PACKAGEKIT)
+
 if (NOT PLASMA_NO_KUTILS)
     include_directories(${CMAKE_SOURCE_DIR}/kutils)
     set(PLASMA_EXTRA_LIBS ${PLASMA_EXTRA_LIBS} ${KDE4_KUTILS_LIBS})
@@ -117,6 +127,7 @@ set(plasma_LIB_SRCS
     private/animablegraphicswebview.cpp
     private/applethandle.cpp
     private/associatedapplicationmanager.cpp
+    private/componentinstaller.cpp
     private/datacontainer_p.cpp
     private/dataenginebindings.cpp
     private/dataengineconsumer.cpp
diff --git a/plasma/dataenginemanager.cpp b/plasma/dataenginemanager.cpp
index f6dabf0..49df135 100644
--- a/plasma/dataenginemanager.cpp
+++ b/plasma/dataenginemanager.cpp
@@ -29,6 +29,7 @@
 
 #include "datacontainer.h"
 #include "pluginloader.h"
+#include "private/componentinstaller_p.h"
 #include "private/dataengine_p.h"
 #include "private/datacontainer_p.h"
 #include "scripting/scriptengine.h"
@@ -130,6 +131,9 @@ Plasma::DataEngine *DataEngineManager::loadEngine(const QString &name)
 
     DataEngine *engine = PluginLoader::pluginLoader()->loadDataEngine(name);
     if (!engine) {
+        // Try installing the engine. However, it's too late for this request.
+        ComponentInstaller::self()->installMissingComponent("dataengine", name);
+
         return d->nullEngine();
     }
 
diff --git a/plasma/private/componentinstaller.cpp b/plasma/private/componentinstaller.cpp
new file mode 100644
index 0000000..870667f
--- /dev/null
+++ b/plasma/private/componentinstaller.cpp
@@ -0,0 +1,103 @@
+/*
+ *   Copyright 2011 Kevin Kofler <kevin.kofler@chello.at>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "private/componentinstaller_p.h"
+
+#include <kglobal.h>
+
+#ifdef PLASMA_ENABLE_PACKAGEKIT_SUPPORT
+#include <QSet>
+#include <QDBusInterface>
+#include <QDBusPendingCall>
+#include <QWidget>
+#include <QLatin1String>
+#include <QStringList>
+#endif
+
+namespace Plasma
+{
+
+class ComponentInstallerPrivate
+{
+    public:
+#ifdef PLASMA_ENABLE_PACKAGEKIT_SUPPORT
+        QSet<QString> alreadyPrompted;
+#endif
+};
+
+class ComponentInstallerSingleton
+{
+    public:
+        ComponentInstaller self;
+};
+
+K_GLOBAL_STATIC(ComponentInstallerSingleton, privateComponentInstallerSelf)
+
+ComponentInstaller *ComponentInstaller::self()
+{
+    return &privateComponentInstallerSelf->self;
+}
+
+ComponentInstaller::ComponentInstaller()
+    : d(new ComponentInstallerPrivate)
+{
+}
+
+ComponentInstaller::~ComponentInstaller()
+{
+    delete d;
+}
+
+void ComponentInstaller::installMissingComponent(const QString &type,
+                                                 const QString &name,
+                                                 QWidget *parent, bool force)
+{
+#ifdef PLASMA_ENABLE_PACKAGEKIT_SUPPORT
+    QString searchString = type + '-' + name;
+
+    if (!force) {
+        if (d->alreadyPrompted.contains(searchString)) {
+            return;
+        }
+    }
+
+    d->alreadyPrompted.insert(searchString);
+
+    QDBusInterface packageKit(QLatin1String("org.freedesktop.PackageKit"),
+                              QLatin1String("/org/freedesktop/PackageKit"),
+                              QLatin1String("org.freedesktop.PackageKit.Modify"));
+    // We don't check packageKit.isValid() because the service is activated on
+    // demand, so it will show up as "not valid".
+    WId wid = 0;
+    if (parent) {
+        wid = parent->winId();
+    }
+    QStringList resources;
+    resources.append(searchString);
+    packageKit.asyncCall(QLatin1String("InstallResources"), (unsigned int) wid,
+                         QLatin1String("plasma-service"), resources, QString());
+#else
+    Q_UNUSED(type);
+    Q_UNUSED(name);
+    Q_UNUSED(parent);
+    Q_UNUSED(force);
+#endif
+}
+
+} // namespace Plasma
diff --git a/plasma/private/componentinstaller_p.h b/plasma/private/componentinstaller_p.h
new file mode 100644
index 0000000..f85cbb6
--- /dev/null
+++ b/plasma/private/componentinstaller_p.h
@@ -0,0 +1,94 @@
+/*
+ *   Copyright 2011 Kevin Kofler <kevin.kofler@chello.at>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef PLASMA_COMPONENTINSTALLER_H
+#define PLASMA_COMPONENTINSTALLER_H
+
+class QString;
+class QWidget;
+
+namespace Plasma
+{
+
+class ComponentInstallerPrivate;
+
+/**
+ * @class ComponentInstaller plasma/private/componentinstaller_p.h
+ *
+ * @short This class provides a generic API for installation of components.
+ *
+ * @internal
+ *
+ * Plasma::ComponentInstaller allows searching for a missing data or script
+ * engine by name, and allowing the user to install the missing service.
+ * Currently, PackageKit is supported as the mechanism to install components,
+ * but more mechanisms could be supported in the future through the same API.
+ *
+ * @since 4.8
+ */
+class ComponentInstaller
+{
+    public:
+        /**
+         * Singleton pattern accessor.
+         */
+        static ComponentInstaller *self();
+
+        /**
+         * Installs a missing component asynchronously.
+         *
+         * By default, this method will cache requested components and not
+         * prompt again for the same engine in the same session. The force
+         * parameter can be used to disable this mechanism, e.g. when the user
+         * just installed a new widget written in a scripting language, and so
+         * is likely to want the script engine installed after all.
+         *
+         * In the case of on-demand installation, this will unfortunately not
+         * allow the call which triggered the missing component lookup to
+         * succeed, but we cannot afford to block all of Plasma until the
+         * mechanism is done installing the service.
+         *
+         * This function does nothing if PackageKit integration was disabled at
+         * compile time.
+         *
+         * @param type the type of the component, should be "scriptengine" or
+         *             "dataengine"
+         * @param name the name of the component
+         * @param parent a parent widget, used to set the wid for PackageKit
+         * @param force whether to always prompt, even if recently prompted
+         */
+        void installMissingComponent(const QString &type, const QString &name,
+                                     QWidget *parent = 0, bool force = false);
+
+    private:
+        /**
+         * Default constructor. The singleton method self() is the
+         * preferred access mechanism.
+         */
+        ComponentInstaller();
+        ~ComponentInstaller();
+
+        ComponentInstallerPrivate *const d;
+
+        friend class ComponentInstallerSingleton;
+};
+
+} // namespace Plasma
+
+#endif // multiple inclusion guard
diff --git a/plasma/scripting/scriptengine.cpp b/plasma/scripting/scriptengine.cpp
index fb8cd1a..21f8a9a 100644
--- a/plasma/scripting/scriptengine.cpp
+++ b/plasma/scripting/scriptengine.cpp
@@ -27,6 +27,7 @@
 #include "applet.h"
 #include "dataengine.h"
 #include "package.h"
+#include "private/componentinstaller_p.h"
 #include "scripting/appletscript.h"
 #include "scripting/dataenginescript.h"
 #include "scripting/runnerscript.h"
@@ -196,6 +197,9 @@ ScriptEngine *loadEngine(const QString &language, ComponentType type, QObject *p
                  << "! error reported: " << error;
     }
 
+    // Try installing the engine. However, it's too late for this request.
+    ComponentInstaller::self()->installMissingComponent("scriptengine", language);
+
     return 0;
 }
 
diff --git a/solid/solid/CMakeLists.txt b/solid/solid/CMakeLists.txt
index 0aa7a43..623dd0a 100644
--- a/solid/solid/CMakeLists.txt
+++ b/solid/solid/CMakeLists.txt
@@ -42,6 +42,7 @@ file(MAKE_DIRECTORY
    ${CMAKE_CURRENT_BINARY_DIR}/backends/hal
    ${CMAKE_CURRENT_BINARY_DIR}/backends/udev
    ${CMAKE_CURRENT_BINARY_DIR}/backends/wmi
+   ${CMAKE_CURRENT_BINARY_DIR}/backends/fuse
 )
 
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${KDE4_C_FLAGS}") # enable -fvisibility=hidden for C sources
@@ -289,6 +290,17 @@ if(NOT WIN32 AND NOT APPLE)
    backends/fstab/fstabwatcher.cpp
    )
 
+   message(STATUS "Building Solid Fuse backend." )
+   set(solid_LIB_SRCS ${solid_LIB_SRCS}
+   backends/fuse/fusemanager.cpp
+   backends/fuse/fusedevice.cpp
+   backends/fuse/fusestorageaccess.cpp
+   backends/fuse/fusestoragedrive.cpp
+   backends/fuse/fusestoragevolume.cpp
+   backends/fuse/fusehandling.cpp
+   backends/fuse/fusewatcher.cpp
+   )
+
 endif(NOT WIN32 AND NOT APPLE)
 
 if(APPLE)
diff --git a/solid/solid/backends/fuse/fusedevice.cpp b/solid/solid/backends/fuse/fusedevice.cpp
new file mode 100644
index 0000000..20a9783
--- /dev/null
+++ b/solid/solid/backends/fuse/fusedevice.cpp
@@ -0,0 +1,138 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fusedevice.h"
+#include "fusehandling.h"
+#include "fusestorageaccess.h"
+#include "fusestoragedrive.h"
+#include "fusestoragevolume.h"
+#include "fuseservice.h"
+#include <QtCore/QStringList>
+#include <QDebug>
+
+using namespace Solid::Backends::Fuse;
+
+FuseDevice::FuseDevice(QString udi) :
+    Solid::Ifaces::Device(),
+    m_udi(udi)
+{
+    qDebug() << "UDI:" << udi;
+    m_device = m_udi.mid(QString::fromLatin1(FUSE_UDI_PREFIX).length(), -1);
+
+    if (m_device.endsWith(":media")) {
+        m_device.chop(6);
+    }
+
+    m_product = m_device;
+    m_vendor  = "FUSE";
+
+    m_description = m_vendor + " on " + m_product;
+    qDebug() << "Info:" << m_device << m_product << m_vendor << m_description;
+}
+
+FuseDevice::~FuseDevice()
+{
+}
+
+QString FuseDevice::udi() const
+{
+    return m_udi;
+}
+
+QString FuseDevice::parentUdi() const
+{
+    return udi();
+    // return QString::fromLatin1(FUSE_UDI_PREFIX);
+}
+
+QString FuseDevice::vendor() const
+{
+    return m_vendor;
+}
+
+QString FuseDevice::product() const
+{
+    return m_product;
+}
+
+QString FuseDevice::icon() const
+{
+    return QString::fromLatin1("drive-removable-media");
+}
+
+QStringList FuseDevice::emblems() const
+{
+    QStringList res;
+    const FuseStorageAccess accessIface(const_cast<FuseDevice *>(this));
+    if (accessIface.isAccessible()) {
+        res << "emblem-mounted";
+    } else {
+        res << "emblem-unmounted";
+    }
+
+    return res;
+}
+
+QString FuseDevice::description() const
+{
+    return m_description;
+}
+
+bool FuseDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const
+{
+    switch (type) {
+        case Solid::DeviceInterface::StorageAccess:
+        case Solid::DeviceInterface::StorageVolume:
+        case Solid::DeviceInterface::StorageDrive:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
+QObject* FuseDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type)
+{
+    switch (type) {
+        case Solid::DeviceInterface::StorageAccess:
+            return new FuseStorageAccess(this);
+
+        case Solid::DeviceInterface::StorageVolume:
+            return new FuseStorageVolume(this);
+
+        case Solid::DeviceInterface::StorageDrive:
+            return new FuseStorageDrive(this);
+
+        default:
+            return 0;
+    }
+}
+
+QString FuseDevice::device() const
+{
+    return m_device;
+}
+
+void FuseDevice::onMtabChanged(const QString& device)
+{
+    if (m_device == device)
+        emit mtabChanged(device);
+}
diff --git a/solid/solid/backends/fuse/fusedevice.h b/solid/solid/backends/fuse/fusedevice.h
new file mode 100644
index 0000000..913da39
--- /dev/null
+++ b/solid/solid/backends/fuse/fusedevice.h
@@ -0,0 +1,81 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_FUSE_FUSE_DEVICE_H
+#define SOLID_BACKENDS_FUSE_FUSE_DEVICE_H
+
+#include <solid/ifaces/device.h>
+#include <QtCore/QStringList>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+    class FuseDevice: public Solid::Ifaces::Device
+    {
+        Q_OBJECT
+
+        public:
+            FuseDevice(QString udi);
+
+            virtual ~FuseDevice();
+
+            virtual QString udi() const;
+
+            virtual QString parentUdi() const;
+
+            virtual QString vendor() const;
+
+            virtual QString product() const;
+
+            virtual QString icon() const;
+
+            virtual QStringList emblems() const;
+
+            virtual QString description() const;
+
+            virtual bool queryDeviceInterface(const Solid::DeviceInterface::Type &type) const;
+
+            virtual QObject *createDeviceInterface(const Solid::DeviceInterface::Type &type);
+
+            QString device() const;
+
+        Q_SIGNALS:
+            void mtabChanged(const QString& device);
+
+        private Q_SLOTS:
+            void onMtabChanged(const QString& device);
+
+        private:
+            QString m_udi;
+            QString m_device;
+            QString m_product;
+            QString m_vendor;
+            QString m_description;
+    };
+
+}
+}
+}
+#endif // SOLID_BACKENDS_UPNP_UPNP_DEVICE_H
diff --git a/solid/solid/backends/fuse/fusehandling.cpp b/solid/solid/backends/fuse/fusehandling.cpp
new file mode 100644
index 0000000..f2e57e3
--- /dev/null
+++ b/solid/solid/backends/fuse/fusehandling.cpp
@@ -0,0 +1,195 @@
+/*
+    Copyright 2006-2010 Kevin Ottens <ervin@kde.org>
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fusehandling.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QObject>
+#include <QtCore/QProcess>
+#include <QtCore/QTextStream>
+#include <QtCore/QTime>
+
+#include <solid/soliddefs_p.h>
+
+#include <config.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#endif
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#elif defined(HAVE_SYS_MNTENT_H)
+#include <sys/mntent.h>
+#endif
+
+// This is the *BSD branch
+#ifdef HAVE_SYS_MOUNT_H
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/mount.h>
+#endif
+
+#ifndef HAVE_GETMNTINFO
+# ifdef _PATH_MOUNTED
+// On some Linux, MNTTAB points to /etc/fstab !
+#  undef MNTTAB
+#  define MNTTAB _PATH_MOUNTED
+# else
+#  ifndef MNTTAB
+#   ifdef MTAB_FILE
+#    define MNTTAB MTAB_FILE
+#   else
+#    define MNTTAB "/etc/mnttab"
+#   endif
+#  endif
+# endif
+#endif
+
+// There are (at least) four kind of APIs:
+// setmntent + getmntent + struct mntent (linux...)
+//             getmntent + struct mnttab
+// mntctl                + struct vmount (AIX)
+// getmntinfo + struct statfs&flags (BSD 4.4 and friends)
+// getfsent + char* (BSD 4.3 and friends)
+
+#ifdef HAVE_SETMNTENT
+#define SETMNTENT setmntent
+#define ENDMNTENT endmntent
+#define STRUCT_MNTENT struct mntent *
+#define STRUCT_SETMNTENT FILE *
+#define GETMNTENT(file, var) ((var = getmntent(file)) != 0)
+#define MOUNTPOINT(var) var->mnt_dir
+#define MOUNTTYPE(var) var->mnt_type
+#define MOUNTOPTIONS(var) var->mnt_opts
+#define FSNAME(var) var->mnt_fsname
+#else
+#define SETMNTENT fopen
+#define ENDMNTENT fclose
+#define STRUCT_MNTENT struct mnttab
+#define STRUCT_SETMNTENT FILE *
+#define GETMNTENT(file, var) (getmntent(file, &var) == 0)
+#define MOUNTPOINT(var) var.mnt_mountp
+#define MOUNTTYPE(var) var.mnt_fstype
+#define MOUNTOPTIONS(var) var.mnt_mntopts
+#define FSNAME(var) var.mnt_special
+#endif
+
+#include <QDebug>
+
+SOLID_GLOBAL_STATIC(Solid::Backends::Fuse::FuseHandling, globalFuseCache)
+
+Solid::Backends::Fuse::FuseHandling::FuseHandling()
+    : m_mtabCacheValid(false)
+{ }
+
+bool _k_isFuseFileSystem(const QString &fstype, const QString &devName)
+{
+    return fstype.startsWith("fuse.");
+}
+
+QStringList Solid::Backends::Fuse::FuseHandling::deviceList()
+{
+    _k_updateMtabMountPointsCache();
+
+    QStringList devices = globalFuseCache->m_mtabCache.values();
+    return devices;
+}
+
+QStringList Solid::Backends::Fuse::FuseHandling::mountPoints(const QString &device)
+{
+    _k_updateMtabMountPointsCache();
+
+    return QStringList() << device;
+}
+
+QProcess *Solid::Backends::Fuse::FuseHandling::callSystemCommand(const QString &commandName,
+                                                                 const QStringList &args,
+                                                                 QObject *obj, const char *slot)
+{
+    QStringList env = QProcess::systemEnvironment();
+    env.replaceInStrings(QRegExp("^PATH=(.*)", Qt::CaseInsensitive), "PATH=/sbin:/bin:/usr/sbin/:/usr/bin");
+
+    QProcess *process = new QProcess(obj);
+
+    QObject::connect(process, SIGNAL(finished(int,QProcess::ExitStatus)),
+                     obj, slot);
+
+    process->setEnvironment(env);
+    process->start(commandName, args);
+
+    if (process->waitForStarted()) {
+        return process;
+    } else {
+        delete process;
+        return 0;
+    }
+}
+
+QProcess *Solid::Backends::Fuse::FuseHandling::callSystemCommand(const QString &commandName,
+                                                                 const QString &device,
+                                                                 QObject *obj, const char *slot)
+{
+    return callSystemCommand(commandName, QStringList() << device, obj, slot);
+}
+
+void Solid::Backends::Fuse::FuseHandling::_k_updateMtabMountPointsCache()
+{
+    if (globalFuseCache->m_mtabCacheValid)
+        return;
+
+    globalFuseCache->m_mtabCache.clear();
+
+    STRUCT_SETMNTENT mnttab;
+    if ((mnttab = SETMNTENT(MNTTAB, "r")) == 0)
+        return;
+
+    STRUCT_MNTENT fe;
+    while (GETMNTENT(mnttab, fe))
+    {
+        QString type = QFile::decodeName(MOUNTTYPE(fe));
+        if (_k_isFuseFileSystem(type, QString())) {
+            const QString device = QFile::decodeName(FSNAME(fe));
+            const QString mountpoint = QFile::decodeName(MOUNTPOINT(fe));
+            globalFuseCache->m_mtabCache << mountpoint;
+        }
+    }
+    ENDMNTENT(mnttab);
+
+    globalFuseCache->m_mtabCacheValid = true;
+}
+
+QStringList Solid::Backends::Fuse::FuseHandling::currentMountPoints(const QString &device)
+{
+    _k_updateMtabMountPointsCache();
+    return QStringList() << device;
+}
+
+void Solid::Backends::Fuse::FuseHandling::flushMtabCache()
+{
+    globalFuseCache->m_mtabCacheValid = false;
+}
+
diff --git a/solid/solid/backends/fuse/fusehandling.h b/solid/solid/backends/fuse/fusehandling.h
new file mode 100644
index 0000000..31662c8
--- /dev/null
+++ b/solid/solid/backends/fuse/fusehandling.h
@@ -0,0 +1,74 @@
+/*
+    Copyright 2006-2010 Kevin Ottens <ervin@kde.org>
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_FUSE_FUSEHANDLING_H
+#define SOLID_BACKENDS_FUSE_FUSEHANDLING_H
+
+#include <QtCore/QString>
+#include <QtCore/QMultiHash>
+
+#include <QString>
+#include <QSet>
+
+class QProcess;
+class QObject;
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+class FuseHandling
+{
+public:
+    FuseHandling();
+
+    static QStringList deviceList();
+    static QStringList currentMountPoints(const QString &device);
+    static QStringList mountPoints(const QString &device);
+    static QProcess *callSystemCommand(const QString &commandName,
+                                       const QStringList &args,
+                                       QObject *obj, const char *slot);
+    static QProcess *callSystemCommand(const QString &commandName,
+                                       const QString &device,
+                                       QObject *obj, const char *slot);
+    static void flushMtabCache();
+    static void flushFuseCache();
+
+private:
+    static void _k_updateMtabMountPointsCache();
+    static void _k_updateFuseMountPointsCache();
+
+    QSet<QString> m_mtabCache;
+    bool m_mtabCacheValid;
+
+};
+
+}
+}
+}
+
+#endif
+
+
diff --git a/solid/solid/backends/fuse/fusemanager.cpp b/solid/solid/backends/fuse/fusemanager.cpp
new file mode 100644
index 0000000..9011bd5
--- /dev/null
+++ b/solid/solid/backends/fuse/fusemanager.cpp
@@ -0,0 +1,155 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fusemanager.h"
+#include "fusedevice.h"
+#include "fusehandling.h"
+#include "../shared/rootdevice.h"
+#include "fuseservice.h"
+#include "fusewatcher.h"
+
+#include <QDebug>
+
+using namespace Solid::Backends::Fuse;
+using namespace Solid::Backends::Shared;
+
+FuseManager::FuseManager(QObject *parent)
+  : Solid::Ifaces::DeviceManager(parent)
+{
+    m_supportedInterfaces << Solid::DeviceInterface::StorageAccess;
+
+    m_deviceList = FuseHandling::deviceList();
+
+    connect(FuseWatcher::instance(), SIGNAL(mtabChanged()), this, SLOT(onMtabChanged()));
+}
+
+QString FuseManager::udiPrefix() const
+{
+    return QString::fromLatin1(FUSE_UDI_PREFIX);
+}
+
+QSet<Solid::DeviceInterface::Type> FuseManager::supportedInterfaces() const
+{
+    return m_supportedInterfaces;
+}
+
+QStringList FuseManager::allDevices()
+{
+    QStringList result;
+
+    result << udiPrefix();
+    foreach (const QString &device, m_deviceList) {
+        result << udiPrefix() + device;
+    }
+
+    return result;
+}
+
+QStringList FuseManager::devicesFromQuery( const QString &parentUdi,
+                                             Solid::DeviceInterface::Type type)
+{
+    qDebug() << "devicesFromQuery" << parentUdi << type;
+
+    if (type == Solid::DeviceInterface::StorageAccess
+            || type == Solid::DeviceInterface::StorageVolume
+            || type == Solid::DeviceInterface::StorageDrive) {
+
+        if (parentUdi.isEmpty() || parentUdi == udiPrefix()) {
+            QStringList list = allDevices();
+            list.removeFirst();
+            return list;
+
+        } else {
+            QStringList list;
+            list << parentUdi;
+            return list;
+        }
+    }
+    return QStringList();
+}
+
+QObject *FuseManager::createDevice(const QString &udi)
+{
+    qDebug() << "createDevice" << udi;
+
+    if (udi == udiPrefix()) {
+        qDebug() << "returning a root device";
+        RootDevice *root = new RootDevice(FUSE_UDI_PREFIX);
+
+        root->setProduct(tr("FUSE mounts"));
+        root->setDescription(tr("FUSE mounts in your system"));
+        root->setIcon("folder-remote");
+
+        return root;
+
+    } else {
+        // global device manager makes sure udi starts with udi prefix + '/'
+        QString internalName = udi.mid( udiPrefix().length(), -1 );
+        qDebug() << "internalName" << internalName;
+
+        if (!m_deviceList.contains(internalName))
+            return 0;
+
+        qDebug() << "Returning a FuseDevice for" << udi;
+        QObject* device = new FuseDevice(udi);
+        connect (this, SIGNAL(mtabChanged(QString)), device, SLOT(onMtabChanged(QString)));
+        return device;
+
+    }
+}
+
+void FuseManager::_k_updateDeviceList()
+{
+    QStringList deviceList = FuseHandling::deviceList();
+    QSet <QString> newlist = deviceList.toSet();
+    QSet <QString> oldlist = m_deviceList.toSet();
+
+    qDebug() << "old list" << oldlist << "new list" << newlist;
+    m_deviceList = deviceList;
+
+    foreach (const QString &device, newlist) {
+        if ( !oldlist.contains(device) ) {
+            emit deviceAdded(udiPrefix() + device);
+        }
+    }
+
+    foreach (const QString &device, oldlist) {
+        if ( !newlist.contains(device) ) {
+            emit deviceRemoved(udiPrefix() + device);
+        }
+    }
+}
+
+void FuseManager::onMtabChanged()
+{
+    FuseHandling::flushMtabCache();
+
+    _k_updateDeviceList();
+
+    foreach (const QString &device, m_deviceList) {
+        // notify storageaccess objects via device ...
+        emit mtabChanged(device);
+    }
+}
+
+FuseManager::~FuseManager()
+{
+}
diff --git a/solid/solid/backends/fuse/fusemanager.h b/solid/solid/backends/fuse/fusemanager.h
new file mode 100644
index 0000000..a0b3e57
--- /dev/null
+++ b/solid/solid/backends/fuse/fusemanager.h
@@ -0,0 +1,68 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_FUSE_FUSEMANAGER_H
+#define SOLID_BACKENDS_FUSE_FUSEMANAGER_H
+
+#include <solid/ifaces/devicemanager.h>
+#include <solid/deviceinterface.h>
+#include <QtCore/QStringList>
+#include <QtCore/QSet>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+class AbstractDeviceFactory;
+
+class FuseManager : public Solid::Ifaces::DeviceManager
+{
+    Q_OBJECT
+
+public:
+    explicit FuseManager(QObject *parent);
+    virtual ~FuseManager();
+
+    virtual QString udiPrefix() const ;
+    virtual QSet<Solid::DeviceInterface::Type> supportedInterfaces() const;
+    virtual QStringList allDevices();
+    virtual QStringList devicesFromQuery(const QString &parentUdi, Solid::DeviceInterface::Type type);
+    virtual QObject *createDevice(const QString &udi);
+
+Q_SIGNALS:
+    void mtabChanged(const QString& device);
+
+private Q_SLOTS:
+    void onMtabChanged();
+
+private:
+    QSet<Solid::DeviceInterface::Type> m_supportedInterfaces;
+    QStringList m_deviceList;
+    void _k_updateDeviceList();
+};
+
+}
+}
+}
+
+#endif
diff --git a/solid/solid/backends/fuse/fuseservice.h b/solid/solid/backends/fuse/fuseservice.h
new file mode 100644
index 0000000..22912dc
--- /dev/null
+++ b/solid/solid/backends/fuse/fuseservice.h
@@ -0,0 +1,28 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_FUSE_SERVICE_H
+#define SOLID_BACKENDS_FUSE_SERVICE_H
+
+#define FUSE_UDI_PREFIX             "/org/kde/fuse"
+
+#endif // SOLID_BACKENDS_FUSE_H
+
diff --git a/solid/solid/backends/fuse/fusestorageaccess.cpp b/solid/solid/backends/fuse/fusestorageaccess.cpp
new file mode 100644
index 0000000..cb68444
--- /dev/null
+++ b/solid/solid/backends/fuse/fusestorageaccess.cpp
@@ -0,0 +1,171 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fusewatcher.h"
+#include <solid/backends/fuse/fusedevice.h>
+#include <solid/backends/fuse/fusehandling.h>
+#include <solid/backends/fuse/fuseservice.h>
+#include <solid/backends/fuse/fusestorageaccess.h>
+#include <QtCore/QStringList>
+
+#include <QTimer>
+#include <QDebug>
+
+#define MTAB "/etc/mtab"
+
+using namespace Solid::Backends::Fuse;
+
+FuseStorageAccess::FuseStorageAccess(Solid::Backends::Fuse::FuseDevice *device) :
+    QObject(device),
+    m_fuseDevice(device)
+{
+    QStringList currentMountPoints = FuseHandling::currentMountPoints(device->device());
+    if (currentMountPoints.isEmpty()) {
+        m_filePath = FuseHandling::mountPoints(device->device()).first();
+        m_isAccessible = false;
+    } else {
+        m_filePath = currentMountPoints.first();
+        m_isAccessible = true;
+    }
+
+    connect(device, SIGNAL(mtabChanged(QString)), this, SLOT(onMtabChanged(QString)));
+    QTimer::singleShot(0, this, SLOT(connectDBusSignals()));
+
+    // qDebug() << "TEST:" <<
+    // QMetaObject::invokeMethod(this, "accessibilityChanged", Qt::QueuedConnection,
+    //         Q_ARG(bool, true), Q_ARG(QString, device->udi()));
+}
+
+FuseStorageAccess::~FuseStorageAccess()
+{
+}
+
+
+void FuseStorageAccess::connectDBusSignals()
+{
+    m_fuseDevice->registerAction("setup", this,
+                             SLOT(slotSetupRequested()),
+                             SLOT(slotSetupDone(int,QString)));
+
+    m_fuseDevice->registerAction("teardown", this,
+                             SLOT(slotTeardownRequested()),
+                             SLOT(slotTeardownDone(int,QString)));
+}
+
+const Solid::Backends::Fuse::FuseDevice *FuseStorageAccess::fuseDevice() const
+{
+    return m_fuseDevice;
+}
+
+bool FuseStorageAccess::isAccessible() const
+{
+    return m_isAccessible;
+}
+
+QString FuseStorageAccess::filePath() const
+{
+    return m_filePath;
+}
+
+bool FuseStorageAccess::isIgnored() const
+{
+    return false;
+}
+
+bool FuseStorageAccess::setup()
+{
+    if (filePath().isEmpty()) {
+        return false;
+    }
+    m_fuseDevice->broadcastActionRequested("setup");
+    m_process = FuseHandling::callSystemCommand("mount", filePath(),
+                                                 this, SLOT(slotSetupFinished(int,QProcess::ExitStatus)));
+
+    return m_process!=0;
+}
+
+void FuseStorageAccess::slotSetupRequested()
+{
+    emit setupRequested(m_fuseDevice->udi());
+}
+
+bool FuseStorageAccess::teardown()
+{
+    if (filePath().isEmpty()) {
+        return false;
+    }
+    m_fuseDevice->broadcastActionRequested("teardown");
+    m_process = FuseHandling::callSystemCommand("umount", filePath(),
+                                                 this, SLOT(slotTeardownFinished(int,QProcess::ExitStatus)));
+
+    return m_process!=0;
+}
+
+void FuseStorageAccess::slotTeardownRequested()
+{
+    emit teardownRequested(m_fuseDevice->udi());
+}
+
+void FuseStorageAccess::slotSetupFinished(int exitCode, QProcess::ExitStatus /*exitStatus*/)
+{
+    if (exitCode==0) {
+        m_fuseDevice->broadcastActionDone("setup", Solid::NoError, QString());
+    } else {
+        m_fuseDevice->broadcastActionDone("setup", Solid::UnauthorizedOperation, m_process->readAllStandardError());
+    }
+    delete m_process;
+}
+
+void FuseStorageAccess::slotSetupDone(int error, const QString &errorString)
+{
+    emit setupDone(static_cast<Solid::ErrorType>(error), errorString, m_fuseDevice->udi());
+}
+
+void FuseStorageAccess::slotTeardownFinished(int exitCode, QProcess::ExitStatus /*exitStatus*/)
+{
+    if (exitCode==0) {
+        m_fuseDevice->broadcastActionDone("teardown", Solid::NoError, QString());
+    } else {
+        m_fuseDevice->broadcastActionDone("teardown", Solid::UnauthorizedOperation, m_process->readAllStandardError());
+    }
+    delete m_process;
+}
+
+void FuseStorageAccess::slotTeardownDone(int error, const QString &errorString)
+{
+    emit teardownDone(static_cast<Solid::ErrorType>(error), errorString, m_fuseDevice->udi());
+}
+
+void FuseStorageAccess::onMtabChanged(const QString& device)
+{
+    QStringList currentMountPoints = FuseHandling::currentMountPoints(device);
+    if (currentMountPoints.isEmpty()) {
+        // device umounted
+        m_filePath = FuseHandling::mountPoints(device).first();
+        m_isAccessible = false;
+        emit accessibilityChanged(false, QString(FUSE_UDI_PREFIX) + device);
+    } else {
+        // device added
+        m_filePath = currentMountPoints.first();
+        m_isAccessible = true;
+        emit accessibilityChanged(true, QString(FUSE_UDI_PREFIX) + device);
+    }
+}
diff --git a/solid/solid/backends/fuse/fusestorageaccess.h b/solid/solid/backends/fuse/fusestorageaccess.h
new file mode 100644
index 0000000..bd5fee3
--- /dev/null
+++ b/solid/solid/backends/fuse/fusestorageaccess.h
@@ -0,0 +1,94 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_FUSE_STORAGEACCESS_H
+#define SOLID_BACKENDS_FUSE_STORAGEACCESS_H
+
+#include <solid/ifaces/storageaccess.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QProcess>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+    class FuseDevice;
+    class FuseStorageAccess : public QObject, public Solid::Ifaces::StorageAccess
+    {
+        Q_OBJECT
+        Q_INTERFACES(Solid::Ifaces::StorageAccess)
+        Q_INTERFACES(Solid::Ifaces::DeviceInterface)
+
+        public:
+            explicit FuseStorageAccess(Solid::Backends::Fuse::FuseDevice *device);
+
+            virtual ~FuseStorageAccess();
+
+            virtual bool isAccessible() const;
+
+            virtual QString filePath() const;
+
+            virtual bool isIgnored() const;
+
+            virtual bool setup();
+
+            virtual bool teardown();
+
+        public:
+            const Solid::Backends::Fuse::FuseDevice* fuseDevice() const;
+
+        Q_SIGNALS:
+            void accessibilityChanged(bool accessible, const QString &udi);
+
+            void setupDone(Solid::ErrorType error, QVariant data, const QString &udi);
+
+            void teardownDone(Solid::ErrorType error, QVariant data, const QString &udi);
+
+            void setupRequested(const QString &udi);
+
+            void teardownRequested(const QString &udi);
+
+        private Q_SLOTS:
+            void slotSetupFinished(int exitCode, QProcess::ExitStatus exitStatus);
+            void slotTeardownFinished(int exitCode, QProcess::ExitStatus exitStatus);
+            void onMtabChanged(const QString& device);
+            void connectDBusSignals();
+
+            void slotSetupRequested();
+            void slotSetupDone(int error, const QString &errorString);
+            void slotTeardownRequested();
+            void slotTeardownDone(int error, const QString &errorString);
+
+        private:
+            Solid::Backends::Fuse::FuseDevice *m_fuseDevice;
+            QProcess *m_process;
+            QString m_filePath;
+            bool m_isAccessible;
+    };
+
+}
+}
+}
+
+#endif // SOLID_BACKENDS_FUSE_DEVICE_INTERFACE_H
diff --git a/solid/solid/backends/fuse/fusestoragedrive.cpp b/solid/solid/backends/fuse/fusestoragedrive.cpp
new file mode 100644
index 0000000..4910349
--- /dev/null
+++ b/solid/solid/backends/fuse/fusestoragedrive.cpp
@@ -0,0 +1,70 @@
+/*
+ *   Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "fusestoragedrive.h"
+#include <QDebug>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+FuseStorageDrive::FuseStorageDrive(FuseDevice *device)
+    : QObject(device)
+{
+    qDebug() << "FuseStorageDrive constructor" << device->device();
+}
+
+FuseStorageDrive::~FuseStorageDrive()
+{
+}
+
+bool FuseStorageDrive::isHotpluggable() const
+{
+    qDebug() << "isHotpluggable true";
+    return true;
+}
+
+bool FuseStorageDrive::isRemovable() const
+{
+    qDebug() << "isRemovable true";
+    return true;
+}
+
+qulonglong FuseStorageDrive::size() const
+{
+    // TODO: make this real
+    return 1024;
+}
+
+Solid::StorageDrive::Bus FuseStorageDrive::bus() const
+{
+    return Solid::StorageDrive::Platform;
+}
+
+Solid::StorageDrive::DriveType FuseStorageDrive::driveType() const
+{
+    return Solid::StorageDrive::HardDisk;
+}
+
+}
+}
+}
diff --git a/solid/solid/backends/fuse/fusestoragedrive.h b/solid/solid/backends/fuse/fusestoragedrive.h
new file mode 100644
index 0000000..2047ca5
--- /dev/null
+++ b/solid/solid/backends/fuse/fusestoragedrive.h
@@ -0,0 +1,64 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2010 Lukas Tinkl <ltinkl@redhat.com>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef FUSESTORAGEDRIVE_H
+#define FUSESTORAGEDRIVE_H
+
+#include <ifaces/storagedrive.h>
+
+#include "fusedevice.h"
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+class FuseStorageDrive: public QObject, virtual public Solid::Ifaces::StorageDrive
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::StorageDrive)
+    Q_INTERFACES(Solid::Ifaces::DeviceInterface)
+
+public:
+    FuseStorageDrive(FuseDevice *device);
+    virtual ~FuseStorageDrive();
+
+    virtual qulonglong size() const;
+    virtual bool isHotpluggable() const;
+    virtual bool isRemovable() const;
+    virtual Solid::StorageDrive::DriveType driveType() const;
+    virtual Solid::StorageDrive::Bus bus() const;
+
+    virtual QString device() const { return QString::fromLatin1("/dev/fuse"); }
+    virtual int deviceMajor() const { return 0; };
+    virtual int deviceMinor() const { return 0; };
+
+
+};
+
+}
+}
+}
+
+#endif // FUSESTORAGEDRIVE_H
diff --git a/solid/solid/backends/fuse/fusestoragevolume.cpp b/solid/solid/backends/fuse/fusestoragevolume.cpp
new file mode 100644
index 0000000..d7a1216
--- /dev/null
+++ b/solid/solid/backends/fuse/fusestoragevolume.cpp
@@ -0,0 +1,104 @@
+/*
+ *   Copyright (C) 2012 Ivan Cukic <ivan.cukic(at)kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   or (at your option) any later version, as published by the Free
+ *   Software Foundation
+ *
+ *   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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "fusestoragevolume.h"
+#include "fusedevice.h"
+
+#include <QByteArray>
+#include <QCryptographicHash>
+#include <QDebug>
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+FuseStorageVolume::FuseStorageVolume(FuseDevice * device)
+    : QObject(), m_device(device)
+{
+}
+
+FuseStorageVolume::~FuseStorageVolume()
+{
+}
+
+bool FuseStorageVolume::isIgnored() const
+{
+    return false;
+}
+
+QString FuseStorageVolume::encryptedContainerUdi() const
+{
+    return QString();
+}
+
+QString FuseStorageVolume::fsType() const
+{
+    return QString::fromLatin1("fuse");
+}
+
+QString FuseStorageVolume::label() const
+{
+    return QString();
+}
+
+QString FuseStorageVolume::uuid() const
+{
+    if (!m_device) {
+        qDebug() << "DEVICE IS NULL!?";
+        return QString();
+    }
+    // We are using the mount path to generate the UUID
+    // it would be better if we could get the source URI, but
+    // fuse doesn't save that in mtab
+    //
+    // UUID will be version 3 - MD5 based instead of SHA1 (v 5)
+
+    QByteArray hash = QCryptographicHash::hash(
+            m_device->udi().toUtf8(),
+            QCryptographicHash::Md5);
+
+    // "90015098-3cd2-4fb0-d696-3f7d28e17f72"
+    // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+    // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
+    //           8    12   16
+
+    QString result(hash.toHex().insert(20, '-').insert(16, '-').insert(12, '-').insert(8, '-'));
+
+    qDebug() << "UUID is " << result;
+
+    return result;
+}
+
+qulonglong FuseStorageVolume::size() const
+{
+    return 1024;
+}
+
+Solid::StorageVolume::UsageType FuseStorageVolume::usage() const
+{
+    return Solid::StorageVolume::FileSystem;
+}
+
+
+}
+}
+}
diff --git a/solid/solid/backends/fuse/fusestoragevolume.h b/solid/solid/backends/fuse/fusestoragevolume.h
new file mode 100644
index 0000000..7a79a7d
--- /dev/null
+++ b/solid/solid/backends/fuse/fusestoragevolume.h
@@ -0,0 +1,67 @@
+/*
+    Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef FUSESTORAGEVOLUME_H
+#define FUSESTORAGEVOLUME_H
+
+#include <ifaces/storagevolume.h>
+
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+class FuseDevice;
+
+class FuseStorageVolume: public QObject, public Solid::Ifaces::StorageVolume
+{
+    Q_OBJECT
+    Q_INTERFACES(Solid::Ifaces::StorageVolume)
+    Q_INTERFACES(Solid::Ifaces::DeviceInterface)
+
+public:
+    FuseStorageVolume(FuseDevice *device);
+    virtual ~FuseStorageVolume();
+
+    virtual QString encryptedContainerUdi() const;
+    virtual qulonglong size() const;
+    virtual QString uuid() const;
+    virtual QString label() const;
+    virtual QString fsType() const;
+    virtual Solid::StorageVolume::UsageType usage() const;
+    virtual bool isIgnored() const;
+
+    virtual QString device() const { return QString::fromLatin1("/dev/fuse"); }
+    virtual int deviceMajor() const { return 0; };
+    virtual int deviceMinor() const { return 0; };
+
+private:
+    FuseDevice * m_device;
+};
+
+}
+}
+}
+
+#endif // FUSESTORAGEVOLUME_H
diff --git a/solid/solid/backends/fuse/fusewatcher.cpp b/solid/solid/backends/fuse/fusewatcher.cpp
new file mode 100644
index 0000000..902a41e
--- /dev/null
+++ b/solid/solid/backends/fuse/fusewatcher.cpp
@@ -0,0 +1,112 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "fusewatcher.h"
+#include "soliddefs_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFileSystemWatcher>
+#include <QtCore/QSocketNotifier>
+#include <QtCore/QFile>
+#include <QtCore/QStringList>
+
+using namespace Solid::Backends::Fuse;
+
+SOLID_GLOBAL_STATIC(FuseWatcher, globalFuseWatcher)
+
+#define MTAB "/etc/mtab"
+#ifdef Q_OS_SOLARIS
+#define FSTAB "/etc/vfstab"
+#else
+#define FSTAB "/etc/fstab"
+#endif
+
+FuseWatcher::FuseWatcher()
+    : m_isRoutineInstalled(false)
+    , m_fileSystemWatcher(new QFileSystemWatcher(this))
+{
+    if (qApp) {
+        connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(orphanFileSystemWatcher()));
+    }
+
+    m_mtabFile = new QFile(MTAB, this);
+    if (m_mtabFile && m_mtabFile->symLinkTarget().startsWith("/proc/")
+        && m_mtabFile->open(QIODevice::ReadOnly) ) {
+
+        m_mtabSocketNotifier = new QSocketNotifier(m_mtabFile->handle(),
+                QSocketNotifier::Exception, this);
+        connect(m_mtabSocketNotifier,
+                SIGNAL(activated(int)), this, SIGNAL(mtabChanged()) );
+    } else {
+        m_fileSystemWatcher->addPath(MTAB);
+    }
+
+    m_fileSystemWatcher->addPath(FSTAB);
+    connect(m_fileSystemWatcher, SIGNAL(fileChanged(QString)), this, SLOT(onFileChanged(QString)));
+}
+
+FuseWatcher::~FuseWatcher()
+{
+    // The QFileSystemWatcher doesn't work correctly in a singleton
+    // The solution so far was to destroy the QFileSystemWatcher when the application quits
+    // But we have some crash with this solution.
+    // For the moment to workaround the problem, we detach the QFileSystemWatcher from the parent
+    // effectively leaking it on purpose.
+
+#if 0
+    //qRemovePostRoutine(globalFuseWatcher.destroy);
+#else
+    m_fileSystemWatcher->setParent(0);
+#endif
+}
+
+void FuseWatcher::orphanFileSystemWatcher()
+{
+    m_fileSystemWatcher->setParent(0);
+}
+
+FuseWatcher *FuseWatcher::instance()
+{
+#if 0
+    FuseWatcher *fstabWatcher = globalFuseWatcher;
+
+    if (fstabWatcher && !fstabWatcher->m_isRoutineInstalled) {
+        qAddPostRoutine(globalFuseWatcher.destroy);
+        fstabWatcher->m_isRoutineInstalled = true;
+    }
+    return fstabWatcher;
+#else
+    return globalFuseWatcher;
+#endif
+}
+
+
+void FuseWatcher::onFileChanged(const QString &path)
+{
+    if (path == MTAB) {
+        emit mtabChanged();
+        if (!m_fileSystemWatcher->files().contains(MTAB)) {
+            m_fileSystemWatcher->addPath(MTAB);
+        }
+    }
+}
+
+
diff --git a/solid/solid/backends/fuse/fusewatcher.h b/solid/solid/backends/fuse/fusewatcher.h
new file mode 100644
index 0000000..7aa742f
--- /dev/null
+++ b/solid/solid/backends/fuse/fusewatcher.h
@@ -0,0 +1,63 @@
+/*
+    Copyright 2010 Mario Bensi <mbensi@ipsquad.net>
+    Copyright 2012 Ivan Cukic <ivan.cukic@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SOLID_BACKENDS_FUSE_WATCHER_H
+#define SOLID_BACKENDS_FUSE_WATCHER_H
+
+#include <QObject>
+
+class QFileSystemWatcher;
+class QFile;
+class QSocketNotifier;
+
+namespace Solid
+{
+namespace Backends
+{
+namespace Fuse
+{
+
+    class FuseWatcher : public QObject {
+        Q_OBJECT
+    public:
+        FuseWatcher();
+        virtual ~FuseWatcher();
+
+        static FuseWatcher *instance();
+
+    Q_SIGNALS:
+        void mtabChanged();
+
+    private Q_SLOTS:
+        void onFileChanged(const QString &path);
+        void orphanFileSystemWatcher();
+
+    private:
+        bool m_isRoutineInstalled;
+        QFileSystemWatcher *m_fileSystemWatcher;
+        QSocketNotifier *m_mtabSocketNotifier;
+        QFile *m_mtabFile;
+    };
+}
+}
+}
+#endif // SOLID_BACKENDS_FUSE_WATCHER_H
+
diff --git a/solid/solid/managerbase.cpp b/solid/solid/managerbase.cpp
index fb5a67c..ee189df 100644
--- a/solid/solid/managerbase.cpp
+++ b/solid/solid/managerbase.cpp
@@ -33,6 +33,7 @@
 #include "backends/hal/halmanager.h"
 #include "backends/udisks/udisksmanager.h"
 #include "backends/upower/upowermanager.h"
+#include "backends/fuse/fusemanager.h"
 
 #if defined (HUPNP_FOUND)
 #include "backends/upnp/upnpdevicemanager.h"
@@ -87,6 +88,8 @@ void Solid::ManagerBasePrivate::loadBackends()
                            << new Solid::Backends::UPower::UPowerManager(0)
                            << new Solid::Backends::Fstab::FstabManager(0);
             }
+
+            m_backends << new Solid::Backends::Fuse::FuseManager(0);
 #        endif
 
 #        if defined (HUPNP_FOUND)
