[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [KSecretService] 0e975cf: Move the user interface stuff to its own
From:       Michael Leupold <lemma () confuego ! org>
Date:       2010-11-09 19:14:27
Message-ID: 20101109191427.D5400A60E1 () git ! kde ! org
[Download RAW message or body]


	A	 ui/tests/dialoguifactorytest.h	 [License: GPL(v2)]


	A	 ui/tests/dialoguifactorytest.cpp	 [License: GPL(v2)]


	A	 ui/tests/CMakeLists.txt	 [License: Trivialfile.]


	A	 ui/dialoguifactory.h	 [License: GPL(v2)]


	A	 ui/dialoguifactory.cpp	 [License: GPL(v2)]


	A	 ui/abstractuimanager.h	 [License: GPL(v2)]


	A	 ui/abstractuijobs.h	 [License: GPL(v2)]


	A	 ui/abstractuijobs.cpp	 [License: GPL(v2)]


	A	 ui/CMakeLists.txt	 [License: Trivialfile.]


	A	 frontend/tests/tempblockingjobs.h	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingjobs.cpp	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingitem.h	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingitem.cpp	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingcollectionmanager.h	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingcollectionmanager.cpp	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingcollection.h	 [License: GPL(v2)]


	A	 frontend/tests/tempblockingcollection.cpp	 [License: GPL(v2)]


	A	 frontend/tests/servicetest.h	 [License: GPL(v2)]


	A	 frontend/tests/servicetest.cpp	 [License: GPL(v2)]


	A	 frontend/tests/CMakeLists.txt	 [License: Trivialfile.]


	A	 frontend/secret/session.h	 [License: GPL(v2)]


	A	 frontend/secret/session.cpp	 [License: GPL(v2)]


	A	 frontend/secret/service.h	 [License: GPL(v2)]


	A	 frontend/secret/service.cpp	 [License: GPL(v2)]


	A	 frontend/secret/secret.h	 [License: GPL(v2)]


	A	 frontend/secret/secret.cpp	 [License: GPL(v2)]


	A	 frontend/secret/prompt.h	 [License: GPL(v2)]


	A	 frontend/secret/prompt.cpp	 [License: GPL(v2)]


	A	 frontend/secret/item.h	 [License: GPL(v2)]


	A	 frontend/secret/item.cpp	 [License: GPL(v2)]


	A	 frontend/secret/collection.h	 [License: GPL(v2)]


	A	 frontend/secret/collection.cpp	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/sessionadaptor.h	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/sessionadaptor.cpp	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/serviceadaptor.h	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/serviceadaptor.cpp	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/promptadaptor.h	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/promptadaptor.cpp	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/itemadaptor.h	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/itemadaptor.cpp	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/dbustypes.h	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/dbustypes.cpp	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/collectionadaptor.h	 [License: GPL(v2)]


	A	 frontend/secret/adaptors/collectionadaptor.cpp	 [License: GPL(v2)]


	A	 frontend/CMakeLists.txt	 [License: Trivialfile.]

commit 0e975cf34f7f4ce4ffc02a66916ce35faa82d5e7
Author: Michael Leupold <lemma@confuego.org>
Date:   Sun Aug 29 11:18:05 2010 +0000

    Move the user interface stuff to its own directory and its own static library for \
cleanup.  Rename daemon to frontend and daemon/dbus to frontend/secret to account for \
what stuff actually is for.  
    svn path=/trunk/playground/base/ksecretservice/; revision=1169479

diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa0d29e..929968e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,11 +17,12 @@ INCLUDE_DIRECTORIES (
 KDE4_ADD_EXECUTABLE (ksecretserviced main.cpp)
 TARGET_LINK_LIBRARIES (ksecretserviced
    ksecretservicebackend
-   ksecretservicedaemon
+   ksecretservicefrontend
    ksecretservicelib
    ${KDE4_KDEUI_LIBS}
 )
 
 ADD_SUBDIRECTORY (backend)
-ADD_SUBDIRECTORY (daemon)
+ADD_SUBDIRECTORY (frontend)
 ADD_SUBDIRECTORY (lib)
+ADD_SUBDIRECTORY (ui)
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index a081412..f5e127b 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -18,9 +18,6 @@ SET (ksecretservice_backend_SRCS
    ksecret/ksecretcollection.cpp
    ksecret/ksecretitem.cpp
    ksecret/ksecretjobs.cpp
-   # user interface
-   abstractuijobs.cpp
-   dialoguifactory.cpp
 )
 
 KDE4_ADD_LIBRARY (ksecretservicebackend STATIC ${ksecretservice_backend_SRCS})
diff --git a/backend/abstractuijobs.cpp b/backend/abstractuijobs.cpp
deleted file mode 100644
index b8304b0..0000000
--- a/backend/abstractuijobs.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "abstractuijobs.h"
-#include "abstractuimanager.h"
-
-#include <QtCore/QEventLoop>
-#include <QtCore/QTimer>
-
-AbstractUiJob::AbstractUiJob(AbstractUiManager *manager) : QueuedJob(manager)
-{
-}
-
-AbstractUiJob::~AbstractUiJob()
-{
-}
-
-void AbstractUiJob::exec()
-{
-   Q_ASSERT(false);
-}
-
-AbstractAskPasswordJob::AbstractAskPasswordJob(AbstractUiManager *manager,
-                                               const QString &collection,
-                                               bool secondTry)
- : AbstractUiJob(manager), m_collection(collection), m_secondTry(secondTry)
-{
-}
-
-AbstractAskPasswordJob::~AbstractAskPasswordJob()
-{
-}
-
-const QString &AbstractAskPasswordJob::collection() const
-{
-   return m_collection;
-}
-
-bool AbstractAskPasswordJob::isSecondTry() const
-{
-   return m_secondTry;
-}
-
-bool AbstractAskPasswordJob::result() const
-{
-   return m_result;
-}
-
-const QCA::SecureArray &AbstractAskPasswordJob::password() const
-{
-   return m_password;
-}
-
-void AbstractAskPasswordJob::setResult(bool result)
-{
-   m_result = result;
-}
-
-void AbstractAskPasswordJob::setPassword(const QCA::SecureArray &password)
-{
-   m_password = password;
-}
-
-#include "abstractuijobs.moc"
diff --git a/backend/abstractuijobs.h b/backend/abstractuijobs.h
deleted file mode 100644
index c9ad9aa..0000000
--- a/backend/abstractuijobs.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ABSTRACTUIJOBS_H
-#define ABSTRACTUIJOBS_H
-
-#include <queuedjob.h>
-#include <jobqueue.h>
-
-#include <QtCore/QQueue>
-#include <QtCrypto/QtCrypto>
-#include <kglobal.h>
-#include <kjob.h>
-
-class AbstractUiManager;
-
-/*
- * Abstract master-class of user interface jobs.
- */
-class AbstractUiJob : public QueuedJob
-{
-   Q_OBJECT
-   
-public:
-   /**
-    * Constructor.
-    *
-    * @param manager user interface job manager and parent object
-    */
-   explicit AbstractUiJob(AbstractUiManager *manager);
-   
-   /**
-    * Destructor.
-    */
-   virtual ~AbstractUiJob();
-   
-   /**
-    * Default implementation for user interface jobs. As a ui job can rarely be
-    * run synchronously, exec() crashes.
-    */
-   virtual void exec();
-   
-private:
-   friend class UiJobManager;
-};
-
-/**
- * Job that asks a user for a password to unlock a collection.
- */
-class AbstractAskPasswordJob : public AbstractUiJob
-{
-   Q_OBJECT
-   
-public:
-   /**
-    * Constructor.
-    *
-    * @param manager ui job manager and parent object
-    * @param collection label of the collection that should be opened
-    * @param secondTry set to true if this is not the user's first try to enter
-    *                  the password correctly
-    */
-   AbstractAskPasswordJob(AbstractUiManager *manager, const QString &collection,
-                          bool secondTry);
-
-   /**
-    * Destructor.
-    */
-   virtual ~AbstractAskPasswordJob();
-   
-   /**
-    * Get the label of the collection that's about to be unlocked.
-    */
-   const QString &collection() const;
-   
-   /**
-    * Check whether this is not the user's first try to enter the password.
-    */
-   bool isSecondTry() const;
-   
-   /**
-    * Get the result of the operation.
-    *
-    * @return true if the user entered a password, false if not
-    */
-   bool result() const;
-   
-   /**
-    * Get the password the user entered.
-    *
-    * @return the password entered by the user or an empty array if the user
-    *         didn't enter a password
-    */
-   const QCA::SecureArray &password() const;
-   
-protected:
-   /**
-    * Set the result of the operation.
-    *
-    * @remarks this is used by derived classes
-    * @param result result of the operation
-    */
-   void setResult(bool result);
-   
-   /**
-    * Set the password entered by the user.
-    *
-    * @remarks This is used by derived classes
-    * @param password password entered by the user
-    */
-   void setPassword(const QCA::SecureArray &password);
-   
-private:
-   QString m_collection;         // name of the collection to be unlocked
-   bool m_secondTry;              // true if this is not the first try
-   bool m_result;                // the result of the operation
-   QCA::SecureArray m_password;  // the password entered by the user
-};
-
-#endif
diff --git a/backend/abstractuimanager.h b/backend/abstractuimanager.h
deleted file mode 100644
index 24e0d06..0000000
--- a/backend/abstractuimanager.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ABSTRACTUIMANAGER_H
-#define ABSTRACTUIMANAGER_H
-
-#include "abstractuijobs.h"
-
-/**
- * Abstract factory that provides means to create a user interface for the various
- * backend classes.
- *
- * This class can be reimplemented to provide a standard UI, a stripped-down UI
- * (probably for mobile devices) or even a bogus UI which can be used inside
- * unit-tests.
- */
-class AbstractUiManager : public JobQueue 
-{
-public:
-   virtual ~AbstractUiManager()
-   {
-      // TODO: clean-up
-   };
-   
-   /**
-    * Create a job for asking for user's password for unlocking a collection.
-    *
-    * @param collection label of the collection to be unlocked
-    * @param secondTry set to true if the user already entered a wrong password \
                before
-    * @return a job which can be enqueued to ask the user for the unlock password
-    */
-   virtual AbstractAskPasswordJob *createAskPasswordJob(const QString &collection,
-                                                        bool secondTry) = 0;
-};
-
-#endif
diff --git a/backend/dialoguifactory.cpp b/backend/dialoguifactory.cpp
deleted file mode 100644
index ae12429..0000000
--- a/backend/dialoguifactory.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dialoguifactory.h"
-
-#include <QtCore/QTimer>
-#include <kpassworddialog.h>
-
-AbstractAskPasswordJob* DialogUiFactory::createAskPasswordJob(const QString& \
                collection,
-                                                              bool secondTry)
-{
-   return new DialogAskPasswordJob(this, collection, secondTry);
-}
-
-DialogAskPasswordJob::DialogAskPasswordJob(AbstractUiManager *manager,
-                                           const QString& collection,
-                                           bool secondTry)
- : AbstractAskPasswordJob(manager, collection, secondTry), m_dialog(0)
-{
-}
-
-DialogAskPasswordJob::~DialogAskPasswordJob()
-{
-}
-
-void DialogAskPasswordJob::start()
-{
-   Q_ASSERT(!m_dialog);
-   // TODO: provide parent widget!
-   m_dialog = new KPasswordDialog;
-   m_dialog->setAttribute(Qt::WA_DeleteOnClose, true);
-   // TODO: needs proper string
-   m_dialog->setPrompt("Collection " + collection() + " wants password.");
-   connect(m_dialog, SIGNAL(finished(int)), this, SLOT(dialogFinished(int)));
-   m_dialog->show();
-}
-
-void DialogAskPasswordJob::dialogFinished(int result)
-{
-   Q_ASSERT(m_dialog);
-   if (result == QDialog::Accepted) {
-      setPassword(QCA::SecureArray(m_dialog->password().toUtf8()));
-      setResult(true);
-   } else {
-      setResult(false);
-   }
-   emitResult();
-}
-
-#include "dialoguifactory.moc"
diff --git a/backend/dialoguifactory.h b/backend/dialoguifactory.h
deleted file mode 100644
index f3c4dc0..0000000
--- a/backend/dialoguifactory.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DIALOGUIFACTORY_H
-#define DIALOGUIFACTORY_H
-
-#include "abstractuijobs.h"
-#include "abstractuimanager.h"
-
-class KPasswordDialog;
-
-class DialogAskPasswordJob : public AbstractAskPasswordJob
-{
-   Q_OBJECT
-   
-public:
-   /**
-    * Constructor.
-    */
-   DialogAskPasswordJob(AbstractUiManager *manager, const QString& collection, bool \
                secondTry);
-   
-   /**
-    * Destructor.
-    */
-   ~DialogAskPasswordJob();
-
-   /**
-    * Contains the actual workload of showing the dialog.
-    */
-   virtual void start();
-   
-private Q_SLOTS:
-   /**
-    * Called when the dialog shown is either accepted or rejected.
-    */
-   void dialogFinished(int result);
-   
-private:
-   KPasswordDialog *m_dialog;
-};
-
-/**
- * Implement AbstractUiFactory to provide a user interface using dialogs.
- */
-class DialogUiFactory : public AbstractUiManager
-{
-public:
-   /**
-    * Destructor.
-    */
-   virtual ~DialogUiFactory() {};
-   
-   /**
-    * Create a job to ask for a user's password to unlock a collection.
-    */
-   virtual AbstractAskPasswordJob* createAskPasswordJob(const QString& collection,
-                                                        bool secondTry);
-};
-
-#endif
diff --git a/backend/tests/CMakeLists.txt b/backend/tests/CMakeLists.txt
index c9106a5..3951b1d 100644
--- a/backend/tests/CMakeLists.txt
+++ b/backend/tests/CMakeLists.txt
@@ -12,13 +12,4 @@ ADD_TEST (BackendItemCollectionHandlingTest \
ksecretservice_backend_test)  KDE4_ADD_EXECUTABLE (securebuffer_test \
securebuffertest.cpp)  TARGET_LINK_LIBRARIES (securebuffer_test ksecretservicebackend \
${QT_QTTEST_LIBRARIES})  
-# involves dialogs, thus not an automatic test
-KDE4_ADD_EXECUTABLE (dialoguifactory_test dialoguifactorytest.cpp)
-TARGET_LINK_LIBRARIES (dialoguifactory_test
-   ksecretservicebackend
-   ksecretservicelib
-   ${QT_QTTEST_LIBRARIES}
-   ${KDE4_KDEUI_LIBS}
-)
-
 ADD_TEST (SecureBufferTest securebuffer_test)
diff --git a/backend/tests/dialoguifactorytest.cpp \
b/backend/tests/dialoguifactorytest.cpp deleted file mode 100644
index 73f1a02..0000000
--- a/backend/tests/dialoguifactorytest.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dialoguifactorytest.h"
-
-#include <QtCrypto/QtCrypto>
-#include <qtest_kde.h>
-
-#include "../dialoguifactory.h"
-
-void DialogUiFactoryTest::initTestCase()
-{
-   QCA::init();
-}
-
-void DialogUiFactoryTest::testAskPassword()
-{
-   DialogUiFactory fact;
-   
-   // ask for a password (asynchronously)
-   AbstractAskPasswordJob *asyncJob1 = \
                fact.createAskPasswordJob("TESTCOLLECTION-ASYNC1", false);
-   AbstractAskPasswordJob *asyncJob2 = \
                fact.createAskPasswordJob("TESTCOLLECTION-ASYNC2", false);
-   QEventLoop loop;
-   connect(asyncJob2, SIGNAL(result(QueuedJob*)), &loop, SLOT(quit()));
-   asyncJob1->enqueue();
-   asyncJob2->enqueue();
-   loop.exec();
-}
-
-void DialogUiFactoryTest::cleanupTestCase()
-{
-}
-
-QTEST_KDEMAIN(DialogUiFactoryTest, GUI)
-#include "dialoguifactorytest.moc"
diff --git a/backend/tests/dialoguifactorytest.h \
b/backend/tests/dialoguifactorytest.h deleted file mode 100644
index d862ea7..0000000
--- a/backend/tests/dialoguifactorytest.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DIALOGUIFACTORYTEST_H
-#define DIALOGUIFACTORYTEST_H
-
-#include <QtTest>
-
-class DialogUiFactoryTest : public QObject
-{
-   Q_OBJECT
-   
-private Q_SLOTS:
-   void initTestCase();
-
-   void testAskPassword();
-
-   void cleanupTestCase();
-};
-
-#endif // BACKENDTEST_H
diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt
deleted file mode 100644
index 13bceb9..0000000
--- a/daemon/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR})
-ADD_SUBDIRECTORY (tests)
-
-SET (ksecretservice_daemon_SRCS
-   # Daemon
-   item.cpp
-   collection.cpp
-   prompt.cpp
-   secret.cpp
-   service.cpp
-   session.cpp
-
-   # Daemon DBus adaptors
-   dbus/dbustypes.cpp
-   dbus/collectionadaptor.cpp
-   dbus/itemadaptor.cpp
-   dbus/promptadaptor.cpp
-   dbus/serviceadaptor.cpp
-   dbus/sessionadaptor.cpp
-)
-
-KDE4_ADD_LIBRARY (ksecretservicedaemon STATIC ${ksecretservice_daemon_SRCS})
-TARGET_LINK_LIBRARIES (ksecretservicedaemon ${KDE4_KDECORE_LIBS} ${QCA2_LIBRARIES})
diff --git a/daemon/collection.cpp b/daemon/collection.cpp
deleted file mode 100644
index 15d8ce6..0000000
--- a/daemon/collection.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "collection.h"
-#include "dbus/collectionadaptor.h"
-#include "service.h"
-#include "item.h"
-#include "session.h"
-#include "prompt.h"
-
-#include <backend/backendcollection.h>
-#include <backend/backenditem.h>
-
-#include <QtDBus/QDBusConnection>
-
-#include <QtCore/QDebug>
-
-Collection::Collection(BackendCollection *collection, Service *service)
- : QObject(service), m_service(service), m_collection(collection)
-{
-   Q_ASSERT(collection);
-   m_objectPath.setPath(service->objectPath().path() + "/collection/" + \
                collection->id());
-
-   new orgFreedesktopSecret::CollectionAdaptor(this);
-   QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-
-   connect(collection, SIGNAL(itemCreated(BackendItem*)),
-                       SLOT(slotItemCreated(BackendItem*)));
-   connect(collection, SIGNAL(itemDeleted(BackendItem*)),
-                       SLOT(slotItemDeleted(BackendItem*)));
-   connect(collection, SIGNAL(itemChanged(BackendItem*)),
-                       SLOT(slotItemChanged(BackendItem*)));
-}
-
-const QDBusObjectPath &Collection::objectPath() const
-{
-   return m_objectPath;
-}
-
-const QList<QDBusObjectPath> &Collection::items() const
-{
-   return m_items;
-}
-
-void Collection::setLabel(const QString &label)
-{
-   BackendReturn<void> rc = m_collection->setLabel(label);
-   if (rc.isError()) {
-      // TODO: generate D-Bus error
-   }
-}
-
-QString Collection::label() const
-{
-   BackendReturn<QString> rc = m_collection->label();
-   if (rc.isError()) {
-      // TODO: generate D-Bus error
-   }
-   return rc.value();
-}
-
-bool Collection::locked() const
-{
-   return m_collection->isLocked();
-}
-
-qulonglong Collection::created() const
-{
-   return m_collection->created().toTime_t();
-}
-
-qulonglong Collection::modified() const
-{
-   return m_collection->modified().toTime_t();
-}
-
-QDBusObjectPath Collection::deleteCollection()
-{
-   DeleteCollectionJob *dcj = m_collection->createDeleteJob();
-   if (dcj->isImmediate()) {
-      dcj->exec();
-      return QDBusObjectPath("/");
-   } else {
-      SingleJobPrompt *p = new SingleJobPrompt(m_service, dcj, this);
-      return p->objectPath();
-   }
-}
-
-QList<QDBusObjectPath> Collection::searchItems(const QMap<QString, QString> \
                &attributes)
-{
-   QList<QDBusObjectPath> rc;
-   BackendReturn<QList<BackendItem*> > br = m_collection->searchItems(attributes);
-   if (br.isError()) {
-      // TODO: generate D-Bus error
-   }
-   else {
-      Q_FOREACH(BackendItem *item, br.value()) {
-         rc.append(QDBusObjectPath(m_objectPath.path() + "/" + item->id()));
-      }
-   }
-   return rc;
-}
-
-QDBusObjectPath Collection::createItem(const QMap<QString, QVariant> &properties,
-                                       const Secret &secret, bool replace,
-                                       QDBusObjectPath &prompt)
-{
-   // default label?
-   QString label;
-   QMap<QString, QString> attributes;
-   bool locked = false;
-
-   // get the session object
-   QObject *object = \
                QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path());
                
-   Session *session;
-   if (!(session = qobject_cast<Session*>(object))) {
-      // TODO: error, requires session
-   }
-   
-   if (properties.contains("Label")) {
-      label = properties["Label"].toString();
-   }
-   if (properties.contains("Locked")) {
-      locked = properties["Locked"].toBool();
-   }
-   if (properties.contains("Attributes")) {
-      attributes = qdbus_cast<StringStringMap>(properties["Attributes"].value<QDBusArgument>());
                
-   }
-
-   // TODO: check the parameters before creating the prompt
-   bool ok;
-   QCA::SecureArray secretValue = session->decrypt(secret, ok);
-   if (!ok) {
-      // TODO: invalid session
-   }
-   CreateItemJob *cij = m_collection->createCreateItemJob(label, attributes, \
                secretValue,
-                                                          replace, locked);
-   if (cij->isImmediate()) {
-      cij->exec();
-      if (cij->error() != NoError || !cij->item()) {
-         // TODO: error creating the item
-      }
-      
-      // the Item is already created inside slotItemCreated()
-      prompt.setPath("/");
-      QDBusObjectPath itemPath(m_objectPath.path() + "/" + cij->item()->id());
-      return itemPath;
-   } else {
-      SingleJobPrompt *p = new SingleJobPrompt(m_service, cij, this);
-      prompt = p->objectPath();
-      return QDBusObjectPath("/");
-   }
-}
-
-BackendCollection *Collection::backendCollection() const
-{
-   return m_collection;
-}
-
-void Collection::slotItemCreated(BackendItem *item)
-{
-   Q_ASSERT(item);
-   Item *itm = new Item(item, this);
-   m_items.append(itm->objectPath());
-   emit itemCreated(itm->objectPath());
-}
-
-void Collection::slotItemDeleted(BackendItem *item)
-{
-   Q_ASSERT(item);
-   QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
-   m_items.removeAll(itmPath);
-   emit itemDeleted(itmPath);
-}
-
-void Collection::slotItemChanged(BackendItem *item)
-{
-   Q_ASSERT(item);
-   QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
-   emit itemChanged(itmPath);
-}
-
-#include "collection.moc"
diff --git a/daemon/collection.h b/daemon/collection.h
deleted file mode 100644
index f96b414..0000000
--- a/daemon/collection.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_COLLECTION_H
-#define DAEMON_COLLECTION_H
-
-#include "secret.h"
-
-#include <QtCore/QObject>
-#include <QtDBus/QDBusObjectPath>
-
-class BackendCollection;
-class BackendItem;
-
-class Service;
-class Item;
-   
-/**
- * Represents a collection on the D-Bus implementing the \
                org.freedesktop.Secret.Collection
- * interface.
- */
-class Collection : public QObject
-{
-   Q_OBJECT
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param collection Backend collection object
-    * @param service Parent service
-    */
-   Collection(BackendCollection *collection, Service *service);
-
-   /**
-    * Return the collection's path on the D-Bus.
-    *
-    * @return the Collection object's path
-    */
-   const QDBusObjectPath &objectPath() const;
-
-   /**
-    * Get the items stored inside this collection.
-    *
-    * @return a list of object paths of items inside the collection
-    */
-   const QList<QDBusObjectPath> &items() const;
-
-   /**
-    * Set the collection's label.
-    *
-    * @param label label to set for the collection
-    */
-   void setLabel(const QString &label);
-
-   /**
-    * Get the collection's label.
-    *
-    * @return the collection's label
-    */
-   QString label() const;
-
-   /**
-    * Check whether this collection is locked.
-    *
-    * @return true if the collection is locked, false if it is unlocked
-    */
-   bool locked() const;
-
-   /**
-    * Get the collection's creation time as a unix timestamp.
-    *
-    * @return collection's creation time
-    */
-   qulonglong created() const;
-
-   /**
-    * Get the collection's last modification time as a unix timestamp.
-    *
-    * @return collection's modification time
-    */
-   qulonglong modified() const;
-
-   /**
-    * Delete this collection.
-    *
-    * @return the object path of a Prompt object or special value "/" if the
-    *         collection was deleted without prompting
-    */
-   QDBusObjectPath deleteCollection();
-
-   /**
-    * Search items inside the collection.
-    *
-    * @param attributes search attributes to match items against
-    */
-   QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes);
-
-   /**
-    * Create a new item inside the collection.
-    *
-    * @param properties Properties for the new item
-    * @param secret Secret for the new item
-    * @param replace if true, an existing item with the same attributes will be \
                replaced,
-    *                if false and an item with the same attributes exists, no new \
                item
-    *                will be created
-    * @param prompt object path of a prompt object if prompting is necessary or "/" \
                if
-    *               the action could be completed without a prompt
-    * @return object path of the new item or "/" if prompting is necessary
-    */
-   QDBusObjectPath createItem(const QMap<QString, QVariant> &properties,
-                              const Secret &secret, bool replace, QDBusObjectPath \
                &prompt);
-                              
-   /**
-    * Get the backend collection linked to this object.
-    */
-   BackendCollection *backendCollection() const;
-
-Q_SIGNALS:
-   /**
-    * Signals the creation of a new item.
-    *
-    * @param item object path of the item that was created
-    */
-   void itemCreated(const QDBusObjectPath &item);
-
-   /**
-    * Signals the deletion of an item.
-    *
-    * @param item object path of the item that was deleted
-    */
-   void itemDeleted(const QDBusObjectPath &item);
-
-   /**
-    * Signals that an item inside the collection was changed.
-    *
-    * @param item object path of the item that was changed
-    */
-   void itemChanged(const QDBusObjectPath &item);
-
-private Q_SLOTS:
-   // handle itemCreated() calls from a backend collection
-   void slotItemCreated(BackendItem *item);
-   // handle itemDeleted() calls from a backend collection
-   void slotItemDeleted(BackendItem *item);
-   // handle itemChanged() calls from a backend collection
-   void slotItemChanged(BackendItem *item);
-   
-private:
-   Service *m_service; // parent service
-   BackendCollection *m_collection;
-   QDBusObjectPath m_objectPath;
-   QList<QDBusObjectPath> m_items; // cache for items' object paths
-};
-
-#endif
diff --git a/daemon/dbus/collectionadaptor.cpp b/daemon/dbus/collectionadaptor.cpp
deleted file mode 100644
index 35b431a..0000000
--- a/daemon/dbus/collectionadaptor.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "collectionadaptor.h"
-#include "../collection.h"
-
-namespace orgFreedesktopSecret
-{
-
-CollectionAdaptor::CollectionAdaptor(Collection *collection)
- : QDBusAbstractAdaptor(collection), m_collection(collection)
-{
-   Q_ASSERT(collection);
-
-   connect(m_collection, SIGNAL(itemCreated(const QDBusObjectPath &)),
-                         SIGNAL(ItemCreated(const QDBusObjectPath &)));
-   connect(m_collection, SIGNAL(itemDeleted(const QDBusObjectPath &)),
-                         SIGNAL(ItemDeleted(const QDBusObjectPath &)));
-   connect(m_collection, SIGNAL(itemChanged(const QDBusObjectPath &)),
-                         SIGNAL(ItemChanged(const QDBusObjectPath &)));
-}
-
-const QList<QDBusObjectPath> &CollectionAdaptor::items() const
-{
-   return m_collection->items();
-}
-
-void CollectionAdaptor::setLabel(const QString &label)
-{
-   m_collection->setLabel(label);
-}
-
-QString CollectionAdaptor::label() const
-{
-   return m_collection->label();
-}
-
-bool CollectionAdaptor::locked() const
-{
-   return m_collection->locked();
-}
-
-qulonglong CollectionAdaptor::created() const
-{
-   return m_collection->created();
-}
-
-qulonglong CollectionAdaptor::modified() const
-{
-   return m_collection->modified();
-}
-
-QDBusObjectPath CollectionAdaptor::Delete()
-{
-   return m_collection->deleteCollection();
-}
-
-QList<QDBusObjectPath> CollectionAdaptor::SearchItems(const StringStringMap \
                &attributes)
-{
-   return m_collection->searchItems(attributes);
-}
-
-QDBusObjectPath CollectionAdaptor::CreateItem(const QMap<QString, QVariant> \
                &properties,
-                                              const Secret &secret, bool replace,
-                                              QDBusObjectPath &prompt)
-{
-   return m_collection->createItem(properties, secret, replace, prompt);
-}
-
-}
-
-#include "collectionadaptor.moc"
diff --git a/daemon/dbus/collectionadaptor.h b/daemon/dbus/collectionadaptor.h
deleted file mode 100644
index cb7ad00..0000000
--- a/daemon/dbus/collectionadaptor.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
-
-#include "dbustypes.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-
-class Collection;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Collection objects.
- */
-class CollectionAdaptor : public QDBusAbstractAdaptor
-{
-   Q_OBJECT
-   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Collection")
-   Q_PROPERTY(QList<QDBusObjectPath> Items READ items)
-   Q_PROPERTY(QString Label READ label WRITE setLabel)
-   Q_PROPERTY(bool Locked READ locked)
-   Q_PROPERTY(qulonglong Created READ created)
-   Q_PROPERTY(qulonglong Modified READ modified)
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param collection collection object to attach the adaptor to
-    */
-   CollectionAdaptor(Collection *collection);
-
-   const QList<QDBusObjectPath> &items() const;
-
-   void setLabel(const QString &label);
-   
-   QString label() const;
-
-   bool locked() const;
-
-   qulonglong created() const;
-
-   qulonglong modified() const;
-
-public Q_SLOTS:
-   QDBusObjectPath Delete();
-
-   QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes);
-
-   QDBusObjectPath CreateItem(const QMap<QString, QVariant> &properties,
-                              const Secret &secret, bool replace,
-                              QDBusObjectPath &prompt);
-
-Q_SIGNALS:
-   void ItemCreated(const QDBusObjectPath &item);
-
-   void ItemDeleted(const QDBusObjectPath &item);
-
-   void ItemChanged(const QDBusObjectPath &item);
-
-private:
-   Collection *m_collection;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/dbustypes.cpp b/daemon/dbus/dbustypes.cpp
deleted file mode 100644
index 6d5362f..0000000
--- a/daemon/dbus/dbustypes.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dbustypes.h"
-
-#include <QtDBus/QDBusMetaType>
-
-void registerDBusTypes()
-{
-   // register meta-types needed for this adaptor
-   qRegisterMetaType<Secret>();
-   qDBusRegisterMetaType<Secret>();
-   qRegisterMetaType<StringStringMap>();
-   qDBusRegisterMetaType<StringStringMap>();
-   qDBusRegisterMetaType<ObjectPathSecretMap>();
-}
diff --git a/daemon/dbus/dbustypes.h b/daemon/dbus/dbustypes.h
deleted file mode 100644
index 12425dc..0000000
--- a/daemon/dbus/dbustypes.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
-#define ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
-
-#include "../secret.h"
-
-#include <QtDBus/QDBusObjectPath>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-
-/**
- * Register the types needed for the fd.o Secrets D-Bus interface.
- */
-void registerDBusTypes();
-
-typedef QMap<QString, QString> StringStringMap;
-typedef QMap<QDBusObjectPath, Secret> ObjectPathSecretMap;
-
-Q_DECLARE_METATYPE(StringStringMap);
-Q_DECLARE_METATYPE(ObjectPathSecretMap);
-
-#endif
diff --git a/daemon/dbus/itemadaptor.cpp b/daemon/dbus/itemadaptor.cpp
deleted file mode 100644
index 04f68ea..0000000
--- a/daemon/dbus/itemadaptor.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "itemadaptor.h"
-#include "../item.h"
-#include "../secret.h"
-
-namespace orgFreedesktopSecret
-{
-
-ItemAdaptor::ItemAdaptor(Item *item)
- : QDBusAbstractAdaptor(item), m_item(item)
-{
-   Q_ASSERT(item);
-}
-
-bool ItemAdaptor::locked() const
-{
-   return m_item->locked();
-}
-
-void ItemAdaptor::setAttributes(const StringStringMap &attributes)
-{
-   m_item->setAttributes(attributes);
-}
-
-StringStringMap ItemAdaptor::attributes() const
-{
-   return m_item->attributes();
-}
-
-void ItemAdaptor::setLabel(const QString &label)
-{
-   m_item->setLabel(label);
-}
-
-QString ItemAdaptor::label() const
-{
-   return m_item->label();
-}
-
-qulonglong ItemAdaptor::created() const
-{
-   return m_item->created();
-}
-
-qulonglong ItemAdaptor::modified() const
-{
-   return m_item->modified();
-}
-
-QDBusObjectPath ItemAdaptor::Delete()
-{
-   return m_item->deleteItem();
-}
-
-Secret ItemAdaptor::GetSecret(const QDBusObjectPath &session)
-{
-   return m_item->getSecret(session);
-}
-
-void ItemAdaptor::SetSecret(const Secret &secret)
-{
-   m_item->setSecret(secret);
-}
-
-}
-
-#include "itemadaptor.moc"
diff --git a/daemon/dbus/itemadaptor.h b/daemon/dbus/itemadaptor.h
deleted file mode 100644
index 2037c17..0000000
--- a/daemon/dbus/itemadaptor.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
-
-#include "dbustypes.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-#include <QtCore/QString>
-#include <QtCore/QMap>
-
-class Item;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Item objects.
- */
-class ItemAdaptor : public QDBusAbstractAdaptor
-{
-   Q_OBJECT
-   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Item")
-   Q_PROPERTY(bool Locked READ locked)
-   Q_PROPERTY(StringStringMap Attributes READ attributes WRITE setAttributes)
-   Q_PROPERTY(QString Label READ label WRITE setLabel)
-   Q_PROPERTY(qulonglong Created READ created)
-   Q_PROPERTY(qulonglong Modified READ modified)
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param item item object to attach the adaptor to
-    */
-   ItemAdaptor(Item *item);
-
-   bool locked() const;
-
-   void setAttributes(const StringStringMap &attributes);
-   
-   StringStringMap attributes() const;
-
-   void setLabel(const QString &label);
-
-   QString label() const;
-
-   qulonglong created() const;
-
-   qulonglong modified() const;
-
-public Q_SLOTS:
-   QDBusObjectPath Delete();
-
-   Secret GetSecret(const QDBusObjectPath &session);
-
-   void SetSecret(const Secret &secret);
-
-private:
-   Item *m_item;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/promptadaptor.cpp b/daemon/dbus/promptadaptor.cpp
deleted file mode 100644
index 44ddda3..0000000
--- a/daemon/dbus/promptadaptor.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "promptadaptor.h"
-#include "../prompt.h"
-
-namespace orgFreedesktopSecret
-{
-
-PromptAdaptor::PromptAdaptor(PromptBase *prompt)
- : QDBusAbstractAdaptor(prompt), m_prompt(prompt)
-{
-   Q_ASSERT(prompt);
-
-   connect(prompt, SIGNAL(completed(bool, QVariant)), SLOT(slotCompleted(bool, \
                QVariant)));
-}
-
-void PromptAdaptor::Prompt(const QString &windowId)
-{
-   m_prompt->prompt(windowId);
-}
-
-void PromptAdaptor::Dismiss()
-{
-   m_prompt->dismiss();
-}
-
-void PromptAdaptor::slotCompleted(bool dismissed, const QVariant &result)
-{
-   emit Completed(dismissed, QDBusVariant(result));
-}
-
-}
-
-#include "promptadaptor.moc"
diff --git a/daemon/dbus/promptadaptor.h b/daemon/dbus/promptadaptor.h
deleted file mode 100644
index 8338eca..0000000
--- a/daemon/dbus/promptadaptor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
-
-#include "../prompt.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Prompt objects.
- */
-class PromptAdaptor : public QDBusAbstractAdaptor
-{
-   Q_OBJECT
-   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Prompt")
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param prompt prompt object to attach the adaptor to
-    */
-   PromptAdaptor(PromptBase *prompt);
-
-public Q_SLOTS:
-   void Prompt(const QString &windowId);
-
-   void Dismiss();
-
-Q_SIGNALS:
-   void Completed(bool dismissed, QDBusVariant result);
-
-private Q_SLOTS:
-   void slotCompleted(bool dismissed, const QVariant &result);
-   
-private:
-   PromptBase *m_prompt;
-};
-
-}
-
-#endif
diff --git a/daemon/dbus/serviceadaptor.cpp b/daemon/dbus/serviceadaptor.cpp
deleted file mode 100644
index 276ba19..0000000
--- a/daemon/dbus/serviceadaptor.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "serviceadaptor.h"
-#include "dbustypes.h"
-#include "../service.h"
-
-namespace orgFreedesktopSecret
-{
-
-ServiceAdaptor::ServiceAdaptor(Service *service)
- : QDBusAbstractAdaptor(service), m_service(service)
-{
-   Q_ASSERT(service);
-
-   // register all types needed for the D-Bus interface
-   registerDBusTypes();
-
-   connect(service, SIGNAL(collectionCreated(const QDBusObjectPath&)),
-                    SIGNAL(CollectionCreated(const QDBusObjectPath&)));
-   connect(service, SIGNAL(collectionDeleted(const QDBusObjectPath&)),
-                    SIGNAL(CollectionDeleted(const QDBusObjectPath&)));
-   connect(service, SIGNAL(collectionChanged(const QDBusObjectPath&)),
-                    SIGNAL(CollectionChanged(const QDBusObjectPath&)));
-}
-
-const QList<QDBusObjectPath> &ServiceAdaptor::collections() const
-{
-   return m_service->collections();
-}
-
-QDBusVariant ServiceAdaptor::OpenSession(const QString &algorithm, const \
                QDBusVariant &input,
-                                         QDBusObjectPath &result)
-{
-   return QDBusVariant(m_service->openSession(algorithm, input.variant(), result));
-}
-
-QDBusObjectPath ServiceAdaptor::CreateCollection(const QMap<QString, QVariant> \
                &properties,
-                                                 QDBusObjectPath &prompt)
-{
-   return m_service->createCollection(properties, prompt);
-}
-
-QList<QDBusObjectPath> ServiceAdaptor::SearchItems(const StringStringMap \
                &attributes,
-                                                   QList<QDBusObjectPath> &locked)
-{
-   return m_service->searchItems(attributes, locked);
-}
-
-QList<QDBusObjectPath> ServiceAdaptor::Unlock(const QList<QDBusObjectPath> &objects,
-                                              QDBusObjectPath &prompt)
-{
-   return m_service->unlock(objects, prompt);
-}
-
-QList<QDBusObjectPath> ServiceAdaptor::Lock(const QList<QDBusObjectPath> &objects,
-                                            QDBusObjectPath &prompt)
-{
-   return m_service->lock(objects, prompt);
-}
-
-ObjectPathSecretMap ServiceAdaptor::GetSecrets(const QList<QDBusObjectPath> &items,
-                                               const QDBusObjectPath &session)
-{
-   return m_service->getSecrets(items, session);
-}
-
-}
-
-#include "serviceadaptor.moc"
diff --git a/daemon/dbus/serviceadaptor.h b/daemon/dbus/serviceadaptor.h
deleted file mode 100644
index 436a4bd..0000000
--- a/daemon/dbus/serviceadaptor.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
-
-#include "dbustypes.h"
-#include "../secret.h"
-
-#include <QtDBus/QDBusAbstractAdaptor>
-#include <QtDBus/QDBusObjectPath>
-
-class Service;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Service objects.
- */
-class ServiceAdaptor : public QDBusAbstractAdaptor
-{
-   Q_OBJECT
-   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Service")
-   Q_PROPERTY(QList<QDBusObjectPath> Collections READ collections)
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param service service object to attach the adaptor to
-    */
-   ServiceAdaptor(Service *service);
-
-   const QList<QDBusObjectPath> &collections() const;
-
-public Q_SLOTS:
-   QDBusVariant OpenSession(const QString &algorithm, const QDBusVariant &input,
-                            QDBusObjectPath &result);
-   
-   QDBusObjectPath CreateCollection(const QMap<QString, QVariant> &properties,
-                                    QDBusObjectPath &prompt);
-                                    
-   QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes,
-                                      QList<QDBusObjectPath> &locked);
-                                      
-   QList<QDBusObjectPath> Unlock(const QList<QDBusObjectPath> &objects, \
                QDBusObjectPath &prompt);
-   
-   QList<QDBusObjectPath> Lock(const QList<QDBusObjectPath> &objects, \
                QDBusObjectPath &prompt);
-
-   ObjectPathSecretMap GetSecrets(const QList<QDBusObjectPath> &items,
-                                  const QDBusObjectPath &session);
-
-Q_SIGNALS:
-   void CollectionCreated(const QDBusObjectPath &collection);
-
-   void CollectionDeleted(const QDBusObjectPath &collection);
-
-   void CollectionChanged(const QDBusObjectPath &collection);
-
-private:
-   Service *m_service;
-};
-   
-}
-
-#endif
diff --git a/daemon/dbus/sessionadaptor.cpp b/daemon/dbus/sessionadaptor.cpp
deleted file mode 100644
index e2d1e53..0000000
--- a/daemon/dbus/sessionadaptor.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "sessionadaptor.h"
-#include "../session.h"
-
-namespace orgFreedesktopSecret
-{
-
-SessionAdaptor::SessionAdaptor(Session *session)
- : QDBusAbstractAdaptor(session), m_session(session)
-{
-   Q_ASSERT(session);
-}
-
-void SessionAdaptor::Close()
-{
-   m_session->close();
-}
-
-}
-
-#include "sessionadaptor.moc"
diff --git a/daemon/dbus/sessionadaptor.h b/daemon/dbus/sessionadaptor.h
deleted file mode 100644
index 0eb553c..0000000
--- a/daemon/dbus/sessionadaptor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
-#define ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
-
-#include <QtDBus/QDBusAbstractAdaptor>
-
-class Session;
-
-namespace orgFreedesktopSecret
-{
-
-/**
- * D-Bus adaptor class for Session objects.
- */
-class SessionAdaptor : public QDBusAbstractAdaptor
-{
-   Q_OBJECT
-   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Session")
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param session session object to attach the adaptor to
-    */
-   SessionAdaptor(Session *session);
-
-public Q_SLOTS:
-   void Close();
-
-private:
-   Session *m_session;
-};
-
-}
-
-#endif
diff --git a/daemon/item.cpp b/daemon/item.cpp
deleted file mode 100644
index 93e1b09..0000000
--- a/daemon/item.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "item.h"
-#include "collection.h"
-#include "dbus/itemadaptor.h"
-#include "session.h"
-#include "secret.h"
-#include "prompt.h"
-
-#include <backend/backenditem.h>
-
-#include <QtDBus/QDBusConnection>
-
-Item::Item(BackendItem *item, Collection *collection)
- : QObject(collection), m_item(item)
-{
-    Q_ASSERT(item);
-    m_objectPath.setPath(collection->objectPath().path() + "/" + item->id());
-
-    new orgFreedesktopSecret::ItemAdaptor(this);
-    QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-}
-
-const QDBusObjectPath &Item::objectPath() const
-{
-   return m_objectPath;
-}
-
-bool Item::locked() const
-{
-   return m_item->isLocked();
-}
-
-void Item::setAttributes(const QMap<QString, QString> &attributes)
-{
-   BackendReturn<void> rc = m_item->setAttributes(attributes);
-   if (rc.isError()) {
-      // TODO: set D-Bus error
-   }
-}
-
-QMap<QString, QString> Item::attributes() const
-{
-   BackendReturn<QMap<QString, QString> > rc = m_item->attributes();
-   if (rc.isError()) {
-      // TODO: set D-Bus error
-   }
-   return rc.value();
-}
-
-void Item::setLabel(const QString &label)
-{
-   BackendReturn<void> rc = m_item->setLabel(label);
-   if (rc.isError()) {
-      // TODO: set D-Bus error
-   }
-}
-
-QString Item::label() const
-{
-   BackendReturn<QString> rc = m_item->label();
-   if (rc.isError()) {
-      // TODO: set D-Bus error
-   }
-   return rc.value();
-}
-
-qulonglong Item::created() const
-{
-   return m_item->created().toTime_t();
-}
-
-qulonglong Item::modified() const
-{
-   return m_item->modified().toTime_t();
-}
-
-QDBusObjectPath Item::deleteItem()
-{
-   DeleteItemJob *dij = m_item->createDeleteJob();
-   if (dij->isImmediate()) {
-      dij->exec();
-      return QDBusObjectPath("/");
-   } else {
-      // FIXME: needs the service!
-      SingleJobPrompt *p = new SingleJobPrompt(0, dij, this);
-      return p->objectPath();
-   }
-}
-
-Secret Item::getSecret(const QDBusObjectPath &session)
-{
-   if (m_item->isLocked()) {
-      // TODO: error, requires unlocking
-      return Secret();
-   }
-   
-   QObject *object = \
                QDBusConnection::sessionBus().objectRegisteredAt(session.path());
-   Session *sessionObj;
-   if (object && (sessionObj = qobject_cast<Session*>(object))) {
-      BackendReturn<QCA::SecureArray> br = m_item->secret();
-      if (br.isError()) {
-         // TODO: handle error
-         return Secret();
-      }
-      bool ok;
-      Secret secret = sessionObj->encrypt(br.value(), ok);
-      if (br.isError()) {
-         // TODO: error, invalid session
-         return Secret();
-      }
-      return secret;
-   } else {
-      // TODO: error, requires session
-      return Secret();
-   }
-}
-
-void Item::setSecret(const Secret &secret)
-{
-   if (m_item->isLocked()) {
-      // TODO: error, requires unlocking
-      return;
-   }
-   
-   QObject *object = \
                QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path());
                
-   Session *sessionObj;
-   if (object && (sessionObj = qobject_cast<Session*>(object))) {
-      bool ok;
-      BackendReturn<QCA::SecureArray> br = sessionObj->decrypt(secret, ok);
-      if (!ok) {
-         // TODO: invalid session
-         return;
-      }
-      BackendReturn<void> rc = m_item->setSecret(br.value());
-      if (rc.isError()) {
-         // TODO: handle error
-         return;
-      }
-   }
-   
-   // TODO: error, invalid session
-   
-   return;
-}
-
-BackendItem *Item::backendItem() const
-{
-   return m_item;
-}
-
-#include "item.moc"
diff --git a/daemon/item.h b/daemon/item.h
deleted file mode 100644
index b53df41..0000000
--- a/daemon/item.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_ITEM_H
-#define DAEMON_ITEM_H
-
-#include "secret.h"
-
-#include <QtCore/QObject>
-#include <QtDBus/QDBusContext>
-
-class BackendItem;
-class Collection;
-class Service;
-   
-/**
- * Represents an item on the D-Bus implementing the org.freedesktop.Secret.Item
- * interface.
- */
-class Item : public QObject, protected QDBusContext
-{
-   Q_OBJECT
-
-public:
-   /**
-    * Constructor.
-    * 
-    * @param item Backend item object
-    * @param collection Parent collection
-    */
-   Item(BackendItem *item, Collection *collection);
-
-   /**
-    * Return the item's path on the D-Bus.
-    *
-    * @return the Item object's path
-    */
-   const QDBusObjectPath &objectPath() const;
-
-public: // called by D-Bus adaptors
-   
-   /**
-    * Check whether this item is locked.
-    *
-    * @return true if the item is locked, false if it is unlocked
-    */
-   bool locked() const;
-
-   /**
-    * Set the item's attributes.
-    *
-    * @param attributes the attributes to set for the item
-    */
-   void setAttributes(const QMap<QString, QString> &attributes);
-
-   /**
-    * Get the item's attributes.
-    *
-    * @return the attributes stored for this item
-    */
-   QMap<QString, QString> attributes() const;
-
-   /**
-    * Set the item's human-readable label.
-    *
-    * @param label label to assign to this item
-    */
-   void setLabel(const QString &label);
-
-   /**
-    * Get the human-readable label assigned to this item.
-    *
-    * @return the item assigned to this item
-    */
-   QString label() const;
-
-   /**
-    * Retrieve the item's time of creation as a unix timestamp.
-    *
-    * @return item's time of creation
-    */
-   qulonglong created() const;
-
-   /**
-    * Retrieve the item's last modification date as a unix timestamp.
-    *
-    * @return item's last time of modification
-    */
-   qulonglong modified() const;
-
-   /**
-    * Delete the item from the collection it's in.
-    *
-    * @return the object path of a prompt object for the operation or "/" if the
-    *         item was deleted without a prompt.
-    */
-   QDBusObjectPath deleteItem();
-
-   /**
-    * Get the secret stored withing the item.
-    *
-    * @param session Session to use for securing the D-Bus transport
-    * @return the (possibly encrypted) Secret structure
-    */
-   Secret getSecret(const QDBusObjectPath &session);
-
-   /**
-    * Set the secret stored within the item.
-    *
-    * @param secret Secret to store inside the item
-    */
-   void setSecret(const Secret &secret);
-
-public:
-   /**
-    * Get the backend item associated with this frontend item.
-    *
-    * @return the backend item belonging to this frontend item
-    * @remarks called by other frontend objects
-    */
-   BackendItem *backendItem() const;
-
-private:
-   BackendItem *m_item;
-   QDBusObjectPath m_objectPath;
-};
-
-#endif
diff --git a/daemon/prompt.cpp b/daemon/prompt.cpp
deleted file mode 100644
index ad92607..0000000
--- a/daemon/prompt.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "prompt.h"
-#include "service.h"
-#include "dbus/promptadaptor.h"
-
-#include <backend/backendcollection.h>
-#include <backend/backenditem.h>
-#include <secrettool.h>
-
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusObjectPath>
-
-PromptBase::PromptBase(Service *service, QObject *parent)
- : QObject(parent), m_serviceObjectPath(service->objectPath())
-{
-   Q_ASSERT(service);
-   m_objectPath.setPath(service->objectPath().path() + "/prompts/" + createId());
-
-   new orgFreedesktopSecret::PromptAdaptor(this);
-   QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-}
-
-PromptBase::~PromptBase()
-{
-}
-
-const QDBusObjectPath &PromptBase::objectPath() const
-{
-   return m_objectPath;
-}
-
-const QDBusObjectPath &PromptBase::serviceObjectPath() const
-{
-   return m_serviceObjectPath;
-}
-
-void PromptBase::emitCompleted(bool dismissed, const QVariant &result)
-{
-   emit completed(dismissed, result);
-}
-
-SingleJobPrompt::SingleJobPrompt(Service* service, BackendJob* job, QObject* parent)
- : PromptBase(service, parent), m_prompted(false), m_job(job)
-{
-   connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
-}
-
-SingleJobPrompt::~SingleJobPrompt()
-{
-   // TODO: delete the job?
-}
-
-void SingleJobPrompt::prompt(const QString &windowId)
-{
-   Q_UNUSED(windowId);
-   if (m_prompted) {
-      return;
-   }
-   m_prompted = true;
-   
-   // TODO: convert windowId to a WId and pass it to the job
-   m_job->enqueue();
-}
-
-void SingleJobPrompt::dismiss()
-{
-   if (m_prompted) {
-      return;
-   }
-   m_prompted = true;
-
-   m_job->dismiss();
-}
-
-void SingleJobPrompt::jobResult(QueuedJob *job)
-{
-   Q_ASSERT(job == m_job);
-   // check for errors first
-   if (m_job->isDismissed()) {
-      emit completed(true, QVariant(""));
-   } else if (m_job->error() != NoError) {
-      // TODO: figure out how to handle errors gracefully.      
-      emit completed(false, QVariant(""));
-   } else {
-      switch (m_job->type()) {
-         
-      case BackendJob::TypeUnlockCollection:
-      case BackendJob::TypeLockCollection:
-      case BackendJob::TypeDeleteCollection:
-      case BackendJob::TypeChangeAuthenticationCollection:
-      case BackendJob::TypeDeleteItem:
-      case BackendJob::TypeLockItem:
-      case BackendJob::TypeUnlockItem:
-      case BackendJob::TypeChangeAuthenticationItem:
-         {
-            BooleanResultJob *brj = qobject_cast<BooleanResultJob*>(m_job);
-            Q_ASSERT(brj);
-            emitCompleted(false, QVariant(brj->result()));
-         }
-         break;
-         
-      case BackendJob::TypeCreateCollectionMaster:
-         {
-            CreateCollectionMasterJob *ccmj = \
                qobject_cast<CreateCollectionMasterJob*>(m_job);
-            Q_ASSERT(ccmj);
-            QDBusObjectPath result("/");
-            if (ccmj->collection()) {
-               BackendCollection *coll = ccmj->collection();
-               result.setPath(serviceObjectPath().path() + "/collection/" + \
                coll->id());
-            }
-            
-            emitCompleted(false, qVariantFromValue(result));
-         }
-         break;
-         
-      case BackendJob::TypeCreateCollection:
-         {
-            CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(m_job);
-            Q_ASSERT(ccj);
-            QDBusObjectPath result("/");
-            if (ccj->collection()) {
-               BackendCollection *coll = ccj->collection();
-               result.setPath(serviceObjectPath().path() + "/collection/" + \
                coll->id());
-            }
-            
-            emitCompleted(false, qVariantFromValue(result));
-         }
-         break;
-         
-      case BackendJob::TypeCreateItem:
-         {
-            CreateItemJob *cij = qobject_cast<CreateItemJob*>(m_job);
-            Q_ASSERT(cij);
-            QDBusObjectPath result("/");
-            if (cij->item()) {
-               BackendItem *item = cij->item();
-               result.setPath(serviceObjectPath().path() + "/collection/" +
-                  cij->collection()->id() + "/" + item->id());
-            }
-            
-            emitCompleted(false, qVariantFromValue(result));
-         }
-         break;
-         
-      default:
-         // should not happen!
-         Q_ASSERT(false);
-      }
-   }
-   
-   deleteLater();
-}
-
-ServiceMultiPrompt::ServiceMultiPrompt(Service *service, const QSet<BackendJob*> \
                jobs,
-                                     QObject *parent)
- : PromptBase(service, parent), m_prompted(false), m_jobs(jobs)
-{
-   bool jobTypeDetermined = false;
-   bool jobTypeUnlock = false;
-   
-   Q_FOREACH(BackendJob *job, m_jobs) {
-      // make sure the subjobs are either all unlock or all lock calls
-      bool currentJobTypeUnlock = (job->type() == BackendJob::TypeUnlockCollection \
                ||
-                                   job->type() == BackendJob::TypeUnlockItem);
-      if (jobTypeDetermined && jobTypeUnlock != currentJobTypeUnlock) {
-         Q_ASSERT(false);
-      } else if (!jobTypeDetermined) {
-         jobTypeUnlock = currentJobTypeUnlock;
-         jobTypeDetermined = true;
-      }
-      connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
-   }
-}
-
-ServiceMultiPrompt::~ServiceMultiPrompt()
-{
-   // TODO: delete jobs if not started?
-}
-
-void ServiceMultiPrompt::prompt(const QString &windowId)
-{
-   Q_UNUSED(windowId);
-   if (m_prompted) {
-      return;
-   }
-   m_prompted = true;
-   
-   // TODO: convert windowId to a WId and pass it to the job
-   Q_FOREACH(BackendJob *job, m_jobs) {
-      job->enqueue();
-   }
-}
-
-void ServiceMultiPrompt::dismiss()
-{
-   if (m_prompted) {
-      return;
-   }
-   m_prompted = true;
-   
-   Q_FOREACH(BackendJob *job, m_jobs) {
-      disconnect(job, SIGNAL(result(QueuedJob*)), this, \
                SLOT(jobResult(QueuedJob*)));
-      job->dismiss();
-   }
-
-   // emit result right away so we don't have to catch all result() signals
-   // from individual jobs.
-   emitCompleted(true, qVariantFromValue(QList<QDBusObjectPath>()));
-   deleteLater();
-}
-
-void ServiceMultiPrompt::jobResult(QueuedJob *job)
-{
-   BackendJob *bj = qobject_cast<BackendJob*>(job);
-   Q_ASSERT(bj);
-   Q_ASSERT(m_jobs.contains(bj));
-   // remove job from the set of jobs we're waiting for
-   m_jobs.remove(bj);
-   if (bj->error() != NoError) {
-      // TODO: figure out what to do with erroneous jobs
-   } else {
-      switch (bj->type()) {
-         
-      case BackendJob::TypeUnlockCollection:
-         {
-            UnlockCollectionJob *ucj = qobject_cast<UnlockCollectionJob*>(bj);
-            Q_ASSERT(ucj);
-            if (ucj->result()) {
-               BackendCollection *coll = ucj->collection();
-               QDBusObjectPath path;
-               path.setPath(serviceObjectPath().path() + "/collection/" + \
                coll->id());
-               m_result.append(path);
-            }
-         }
-         break;
-
-      case BackendJob::TypeLockCollection:
-         {
-            LockCollectionJob *lcj = qobject_cast<LockCollectionJob*>(bj);
-            Q_ASSERT(lcj);
-            if (lcj->result()) {
-               BackendCollection *coll = lcj->collection();
-               QDBusObjectPath path;
-               path.setPath(serviceObjectPath().path() + "/collection/" + \
                coll->id());
-               m_result.append(path);
-            }
-         }
-         break;
-         
-      case BackendJob::TypeUnlockItem:
-         {
-            UnlockItemJob *uij = qobject_cast<UnlockItemJob*>(bj);
-            Q_ASSERT(uij);
-            if (uij->result()) {
-               BackendItem *item = uij->item();
-               BackendCollection *coll = 0;
-               // TODO: I NEED THE COLLECTION DAMMIT
-               QDBusObjectPath path;
-               path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
                +
-                            "/" + item->id());
-               m_result.append(path);
-            }
-         }
-         break;
-
-      case BackendJob::TypeLockItem:
-         {
-            LockItemJob *lij = qobject_cast<LockItemJob*>(bj);
-            Q_ASSERT(lij);
-            if (lij->result()) {
-               BackendItem *item = lij->item();
-               BackendCollection *coll = 0;
-               // TODO: I NEED THE COLLECTION DAMMIT
-               QDBusObjectPath path;
-               path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
                +
-                            "/" + item->id());
-               m_result.append(path);
-            }
-         }
-         break;
-         
-      default:
-         Q_ASSERT(false);
-      }
-   }
-   
-   if (m_jobs.isEmpty()) {
-      // all jobs finished
-      emitCompleted(false, qVariantFromValue(m_result));
-      deleteLater();
-   }
-}
-
-#include "prompt.moc"
diff --git a/daemon/prompt.h b/daemon/prompt.h
deleted file mode 100644
index b5aac66..0000000
--- a/daemon/prompt.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_PROMPT_H
-#define DAEMON_PROMPT_H
-
-#include <backend/backendjob.h>
-
-#include <QtCore/QObject>
-#include <QtCore/QSet>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusContext>
-
-class Service;
-
-/**
- * Implementation of prompt objects according to the org.freedesktop.Secret.Prompt
- * interface.
- */
-class PromptBase : public QObject, protected QDBusContext
-{
-   Q_OBJECT
-   
-public:
-   /**
-    * Constructor.
-    *
-    * @param service Service object (used to derive the object path of the prompt)
-    * @param job the job encapsulated by the prompt
-    * @param parent Parent object
-    */
-   PromptBase(Service *service, QObject *parent);
-   
-   /**
-    * Destructor.
-    */
-   virtual ~PromptBase();
-   
-   /**
-    * Return the prompt's path on the D-Bus.
-    *
-    * @return the Prompt object's path
-    */
-   const QDBusObjectPath &objectPath() const;
-   
-   /**
-    * Return the service object's path on the D-Bus.
-    *
-    * @return the Service object's path
-    */
-   const QDBusObjectPath &serviceObjectPath() const;
-   
-   /**
-    * Perform the prompt.
-    *
-    * @param windowId Platform specific window handle to use for showing the prompt
-    * @todo implement window handle handling
-    */
-   virtual void prompt(const QString &windowId) = 0;
-   
-   /**
-    * Dismiss the prompt.
-    */
-   virtual void dismiss() = 0;
-   
-Q_SIGNALS:
-   /**
-    * Emitted when the operation performed by the prompt was completed
-    *
-    * @param dismissed if true the prompt was dismissed, if false it was completed
-    * @param result result of the operation encapulated by the prompt object
-    */
-   void completed(bool dismissed, QVariant result);
-   
-protected:
-   /**
-    * Used to emit completed() signals in derived classes.
-    *
-    * @param dismissed if true the prompt was dismissed, if false it was completed
-    * @param result result of the operation encapsulated by the prompt object
-    */
-   void emitCompleted(bool dismissed, const QVariant &result);
-   
-private:
-   QDBusObjectPath m_objectPath; // the prompt object's objectpath
-   QDBusObjectPath m_serviceObjectPath; // the service's objectpath
-};
-
-/**
- * Prompt object encapsulating a single BackendJob.
- */
-class SingleJobPrompt : public PromptBase
-{
-   Q_OBJECT
-   
-public:
-   /**
-    * Constructor.
-    *
-    * @param service Service object (used to derive the object path of the prompt)
-    * @param job the job encapsulated by the prompt
-    * @param parent Parent object
-    */
-   SingleJobPrompt(Service *service, BackendJob *job, QObject *parent = 0);
-   
-   /**
-    * Destructor.
-    */
-   virtual ~SingleJobPrompt();
-   
-   /**
-    * Perform the prompt.
-    *
-    * @param windowId Platform specific window handle to use for showing the prompt
-    * @todo implement window handle handling
-    */
-   virtual void prompt(const QString &windowId);
-   
-   /**
-    * Dismiss the prompt.
-    */
-   virtual void dismiss();
-   
-private Q_SLOTS:
-   /**
-    * Connected to the backend job's result() signal this notifies about
-    * the job's completion.
-    *
-    * @param job the job that finished
-    */
-   void jobResult(QueuedJob *job);
-
-private:
-   bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
                already
-   BackendJob *m_job; // the encapulated job
-};
-
-/**
- * Prompt object encapsulating a Service.Unlock or a Service.Lock call with multiple \
                targets.
- */
-class ServiceMultiPrompt : public PromptBase
-{
-   Q_OBJECT
-   
-public:
-   /**
-    * Constructor.
-    *
-    * @param service Service object (used to derive the object path of the prompt)
-    * @param jobs the unlock jobs to encapsulate
-    * @param parent parent object
-    */
-   ServiceMultiPrompt(Service *service, const QSet<BackendJob*> jobs, QObject \
                *parent = 0);
-   
-   /**
-    * Destructor.
-    */
-   virtual ~ServiceMultiPrompt();
-   
-   /**
-    * Perform the prompt.
-    *
-    * @pararm windowId Platform specific window handle to use for showing the prompt
-    * @todo implement window handling
-    */
-   virtual void prompt(const QString &windowId);
-   
-   /**
-    * Dismiss this prompt.
-    */
-   virtual void dismiss();
-   
-private Q_SLOTS:
-   /**
-    * Connected to the backend jobs' result() signals this notifies about a
-    * job's completion.
-    *
-    * @param job the job that finished
-    */
-   void jobResult(QueuedJob *job);
-   
-private:
-   bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
                already
-   QList<QDBusObjectPath> m_result; // resulting unlocked/locked object paths
-   QSet<BackendJob*> m_jobs; // encapsulated jobs
-};
-
-#endif
diff --git a/daemon/secret.cpp b/daemon/secret.cpp
deleted file mode 100644
index 6639f90..0000000
--- a/daemon/secret.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "secret.h"
-
-#include <QtCore/QSharedData>
-
-Secret::Secret() : d(new SecretData)
-{
-}
-
-Secret::Secret(const Secret &other) : d(other.d)
-{
-}
-
-Secret::~Secret()
-{
-}
-
-void Secret::setSession(const QDBusObjectPath &session)
-{
-   d->m_session = session;
-}
-
-const QDBusObjectPath &Secret::session() const
-{
-   return d->m_session;
-}
-
-void Secret::setParameters(const QByteArray &parameters)
-{
-   d->m_parameters = parameters;
-}
-
-const QByteArray &Secret::parameters() const
-{
-   return d->m_parameters;
-}
-
-void Secret::setValue(const QByteArray &value)
-{
-   // TODO: encryption
-   d->m_value = value;
-}
-
-const QByteArray &Secret::value() const
-{
-   // TODO: decryption
-   return d->m_value;
-}
-
-QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret)
-{
-   argument.beginStructure();
-   argument << secret.session() << secret.parameters() << secret.value();
-   argument.endStructure();
-   return argument;
-}
-
-const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret)
-{
-   QDBusObjectPath session;
-   QByteArray parameters;
-   QByteArray value;
-   
-   argument.beginStructure();
-   argument >> session >> parameters >> value;
-   argument.endStructure();
-
-   secret.setSession(session);
-   secret.setParameters(parameters);
-   secret.setValue(value);
-
-   return argument;
-}
diff --git a/daemon/secret.h b/daemon/secret.h
deleted file mode 100644
index 8173faf..0000000
--- a/daemon/secret.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_SECRET_H
-#define DAEMON_SECRET_H
-
-#include <QtCore/QSharedDataPointer>
-#include <QtCore/QByteArray>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusArgument>
-#include <QtCrypto/QtCrypto>
-
-/**
- * This class represents secret (possibly encrypted) for transfer on the
- * D-Bus. Encryption and decryption is handled by the respective session.
- *
- * @remarks Objects of this class are implicitly shared
- */
-class Secret
-{
-   // TODO: this should actually be inside secret.cpp but I'm getting strange
-   //       errors if I put it there. investigate.
-   class SecretData : public QSharedData
-   {
-   public:
-      SecretData() {}
-      SecretData(const SecretData &other)
-         : QSharedData(other), m_session(other.m_session), \
                m_parameters(other.m_parameters),
-         m_value(other.m_value) {}
-      ~SecretData() {}
-      QDBusObjectPath m_session;
-      QByteArray m_parameters;
-      QByteArray m_value;
-   };
-   
-public:
-   /**
-    * Constructs an empty Secret.
-    */
-   Secret();
-
-   /**
-    * Copy constructor.
-    */
-   Secret(const Secret &other);
-
-   /**
-    * Destructor.
-    */
-   ~Secret();
-
-   /**
-    * Set the session object D-Bus path.
-    */
-   void setSession(const QDBusObjectPath &session);
-
-   /**
-    * Get the session object D-Bus path.
-    */
-   const QDBusObjectPath &session() const;
-
-   /**
-    * Set the encryption parameters.
-    */
-   void setParameters(const QByteArray &parameters);
-
-   /**
-    * Get the encryption parameters.
-    */
-   const QByteArray &parameters() const;
-
-   /**
-    * Set the secret's encrypted value
-    */
-   void setValue(const QByteArray &value);
-
-   /**
-    * Get the secret's encrypted value
-    */
-   const QByteArray &value() const;
-
-private:
-   class SecretData;
-   QSharedDataPointer<SecretData> d;
-};
-
-Q_DECLARE_METATYPE(Secret)
-
-QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret);
-const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret);
-
-#endif
diff --git a/daemon/service.cpp b/daemon/service.cpp
deleted file mode 100644
index 280435d..0000000
--- a/daemon/service.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "service.h"
-#include "dbus/serviceadaptor.h"
-#include "collection.h"
-#include "prompt.h"
-#include "session.h"
-#include "secret.h"
-#include "item.h"
-
-#include <backend/backendcollection.h>
-#include <backend/backenditem.h>
-
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusMetaType>
-#include <QtDBus/QDBusMessage>
-
-Service::Service(BackendMaster *master, QObject *parent)
- : QObject(parent), m_master(master), m_basePath("/org/freedesktop/secrets")
-{
-   Q_ASSERT(master);
-   
-   new orgFreedesktopSecret::ServiceAdaptor(this);
-   QDBusConnection::sessionBus().registerObject(m_basePath.path(), this);
-
-   // TODO: make master singleton so we can get a KWallet-compatible interface
-   //       on top of it as well.
-
-   connect(m_master, SIGNAL(collectionCreated(BackendCollection*)),
-                     SLOT(slotCollectionCreated(BackendCollection*)));
-   connect(m_master, SIGNAL(collectionDeleted(BackendCollection*)),
-                     SLOT(slotCollectionDeleted(BackendCollection*)));
-   connect(m_master, SIGNAL(collectionChanged(BackendCollection*)),
-                     SLOT(slotCollectionChanged(BackendCollection*)));
-
-   // TODO: add managers to master
-}
-
-const QDBusObjectPath &Service::objectPath() const
-{
-   return m_basePath;
-}
-
-const QList<QDBusObjectPath> &Service::collections() const
-{
-   return m_collections;
-}
-
-QVariant Service::openSession(const QString &algorithm, const QVariant &input,
-                              QDBusObjectPath &result)
-{
-   QVariant output;
-   QString peer;
-   if (calledFromDBus()) {
-      peer = message().service();
-   }
-   Session *session = Session::create(algorithm, input, output, peer, this);
-   if (session) {
-      result = session->objectPath();
-   } else {
-      result = QDBusObjectPath("/");
-      if (calledFromDBus()) {
-         sendErrorReply("org.freedesktop.Secret.Error.NotSupported");
-      }
-   }
-   return output;
-}
-
-QDBusObjectPath Service::createCollection(const QMap<QString, QVariant> &properties,
-                                          QDBusObjectPath &prompt)
-{
-   // TODO: default label
-   QString label;
-   bool locked = false;
-
-   if (properties.contains("Label")) {
-      label = properties["Label"].toString();
-   }
-   if (properties.contains("Locked")) {
-      locked = properties["Locked"].toBool();
-   }
-   
-   CreateCollectionMasterJob *job = m_master->createCreateCollectionMasterJob(label, \
                locked);
-   if (job->isImmediate()) {
-      job->exec();
-      if (job->error() != NoError || !job->collection()) {
-         // TODO: error creating the collection
-         return QDBusObjectPath("/");
-      } else {
-         BackendCollection *coll = job->collection();
-         prompt.setPath("/");
-         QDBusObjectPath collPath(m_basePath.path() + "/collection/" + coll->id());
-         return collPath;
-      }
-   } else {
-      PromptBase *p = new SingleJobPrompt(this, job, this);
-      prompt = p->objectPath();
-      return QDBusObjectPath("/");
-   }
-}
-
-QList<QDBusObjectPath> Service::searchItems(const QMap<QString, QString> \
                &attributes,
-                                            QList<QDBusObjectPath> &locked)
-{
-   // TODO: check if session exists
-   // TODO: should this rather be implemented using Daemon::Collection?
-   QList<QDBusObjectPath> unlocked;
-   Q_FOREACH(BackendCollection* collection, m_master->collections()) {
-      QString collPath = m_basePath.path() + "/collection/" + collection->id();
-      BackendReturn<QList<BackendItem*> > rc = collection->searchItems(attributes);
-      if (!rc.isError()) {
-         QList<BackendItem*> items = rc.value();
-         Q_FOREACH(BackendItem *item, items) {
-            if (item->isLocked()) {
-               locked.append(QDBusObjectPath(collPath + "/" + item->id()));
-            } else {
-               unlocked.append(QDBusObjectPath(collPath + "/" + item->id()));
-            }
-         }
-      }
-   }
-   return unlocked;
-}
-
-QList<QDBusObjectPath> Service::unlock(const QList<QDBusObjectPath> &objects,
-                                       QDBusObjectPath &prompt)
-{
-   // TODO: check is session exists
-   // TODO: bypass prompt
-
-   // objects already unlocked
-   QList<QDBusObjectPath> rc;
-   // jobs to call asynchronously
-   QSet<BackendJob*> unlockJobs;
-   QObject *object;
-   Item *item;
-   Collection *collection;
-   BackendItem *bi;
-   BackendCollection *bc;
-   
-   Q_FOREACH(const QDBusObjectPath &path, objects) {
-      object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
-      if (!object) {
-         continue;
-      }
-      if ((collection = qobject_cast<Collection*>(object))) {
-         bc = collection->backendCollection();
-         if (bc) {
-            if (!bc->isLocked()) {
-               rc.append(path);
-            } else {
-               UnlockCollectionJob *ucj = bc->createUnlockJob();
-               if (ucj->isImmediate()) {
-                  ucj->exec();
-                  if (ucj->error() != NoError || !ucj->result()) {
-                     // not unlocked, maybe due to an error.
-                     // There's not much to do about it. Silently ignore.
-                  } else {
-                     rc.append(path);
-                  }
-               } else {
-                  unlockJobs.insert(ucj);
-               }
-            }
-         }
-      } else if ((item = qobject_cast<Item*>(object))) {
-         bi = item->backendItem();
-         if (bi) {
-            if (!bi->isLocked()) {
-               rc.append(path);
-            } else {
-               UnlockItemJob *uij = bi->createUnlockJob();
-               if (uij->isImmediate()) {
-                  uij->exec();
-                  if (uij->error() != NoError ||!uij->result()) {
-                     // not unlocked, maybe due to an error.
-                     // There's not much to do about it. Silently ignore.
-                  } else {
-                     rc.append(path);
-                  }
-               } else {
-                  unlockJobs.insert(uij);
-               }
-            }
-         }
-      }
-      // NOTE: objects which either don't exist or whose type is wrong are silently \
                ignored.
-   }
-
-   if (!unlockJobs.isEmpty()) {
-      ServiceMultiPrompt *p = new ServiceMultiPrompt(this, unlockJobs, this);
-      prompt = p->objectPath();
-   } else {
-      prompt.setPath("/");
-   }
-
-   return rc;
-}
-
-QList<QDBusObjectPath> Service::lock(const QList<QDBusObjectPath> &objects,
-                                     QDBusObjectPath &prompt)
-{
-   // TODO: check is session exists
-   
-   // objects already locked
-   QList<QDBusObjectPath> rc;
-   // jobs to call asynchronously
-   QSet<BackendJob*> lockJobs;
-   QObject *object;
-   Item *item;
-   Collection *collection;
-   BackendItem *bi;
-   BackendCollection *bc;
-   
-   Q_FOREACH(const QDBusObjectPath &path, objects) {
-      object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
-      if (!object) {
-         continue;
-      }
-      if ((collection = qobject_cast<Collection*>(object))) {
-         bc = collection->backendCollection();
-         if (bc) {
-            if (bc->isLocked()) {
-               rc.append(path);
-            } else {
-               LockCollectionJob *lcj = bc->createLockJob();
-               if (lcj->isImmediate()) {
-                  lcj->exec();
-                  if (lcj->error() != NoError || !lcj->result()) {
-                     // not locked, maybe due to an error.
-                     // There's not much to do about it. Silently ignore.
-                  } else {
-                     rc.append(path);
-                  }
-               } else {
-                  lockJobs.insert(lcj);
-               }
-            }
-         }
-      } else if ((item = qobject_cast<Item*>(object))) {
-         bi = item->backendItem();
-         if (bi) {
-            if (bi->isLocked()) {
-               rc.append(path);
-            } else {
-               LockItemJob *lij = bi->createLockJob();
-               if (lij->isImmediate()) {
-                  lij->exec();
-                  if (lij->error() != NoError || !lij->result()) {
-                     // not locked, maybe due to an error.
-                     // There's not much to do about it. Silently ignore.
-                  } else {
-                     rc.append(path);
-                  }
-               } else {
-                  lockJobs.insert(lij);
-               }
-            }
-         }
-      }
-      // NOTE: objects which either don't exist or whose type is wrong are silently \
                ignored.
-   }
-
-   if (!lockJobs.isEmpty()) {
-      ServiceMultiPrompt *p = new ServiceMultiPrompt(this, lockJobs, this);
-      prompt = p->objectPath();
-   } else {
-      prompt.setPath("/");
-   }
-
-   return rc;
-}
-
-QMap<QDBusObjectPath, Secret> Service::getSecrets(const QList<QDBusObjectPath> \
                &items,
-                                                  const QDBusObjectPath &session)
-{
-   QMap<QDBusObjectPath, Secret> rc;
-   QObject *object;
-   Session *sessionObj;
-   Item *item;
-   bool ok;
-   Secret secret;
-   
-   object = QDBusConnection::sessionBus().objectRegisteredAt(session.path());
-   if (!object || !(sessionObj = qobject_cast<Session*>(object))) {
-      if (calledFromDBus()) {
-         sendErrorReply("org.freedesktop.Secret.Error.NoSession");
-      }
-      return rc;
-   }
-   
-   Q_FOREACH(const QDBusObjectPath &path, items) {
-      object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
-      if (object && (item = qobject_cast<Item*>(object))) {
-         BackendItem *bi = item->backendItem();
-         if (bi && !bi->isLocked()) {
-            BackendReturn<QCA::SecureArray> be = bi->secret();
-            // TODO: what should this do if getting the secret failed?
-            if (!be.isError()) {
-               secret = sessionObj->encrypt(be.value(), ok);
-               // TODO: what should this do if encrypting failed?
-               if (ok) {
-                  rc.insert(path, secret);
-               }
-            }
-         }
-      }
-   }
-
-   return rc;
-}
-
-void Service::slotCollectionCreated(BackendCollection *collection)
-{
-   Q_ASSERT(collection);
-   Collection *coll = new Collection(collection, this);
-   m_collections.append(coll->objectPath());
-   emit collectionCreated(coll->objectPath());
-}
-
-void Service::slotCollectionDeleted(BackendCollection *collection)
-{
-   Q_ASSERT(collection);
-   QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
-   m_collections.removeAll(collPath);
-   // TODO: make sure Daemon::Collection gets destroyed
-   emit collectionDeleted(collPath);
-}
-
-void Service::slotCollectionChanged(BackendCollection *collection)
-{
-   Q_ASSERT(collection);
-   QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
-   emit collectionChanged(collPath);
-}
-
-#include "service.moc"
diff --git a/daemon/service.h b/daemon/service.h
deleted file mode 100644
index 29a8a98..0000000
--- a/daemon/service.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_SERVICE_H
-#define DAEMON_SERVICE_H
-
-#include <backend/backendmaster.h>
-
-#include <QtCore/QObject>
-#include <QtCore/QMultiMap>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusContext>
-
-class Secret;
-class Collection;
-
-class _TypeRegistrar;
-   
-/**
- * Main entry point of the secret service D-Bus daemon implementing the
- * org.freedesktop.Secret.Service interface.
- * 
- * @todo Implement proper session handling
- */
-class Service : public QObject, protected QDBusContext
-{
-   Q_OBJECT
-
-public:
-   /**
-    * Constructor.
-    *
-    * @param master Backend master to use
-    * @param parent Parent object
-    */
-   Service(BackendMaster *master, QObject *parent = 0);
-
-   /**
-    * Return the service's path on the D-Bus.
-    *
-    * @return the Service object's path
-    */
-   const QDBusObjectPath &objectPath() const;
-
-   /**
-    * Accessor for the list of known collections.
-    *
-    * @return all collections known to the service.
-    */
-   const QList<QDBusObjectPath> &collections() const;
-
-   /**
-    * Open a unique session for the caller application.
-    *
-    * @param algorithm the algorithm the caller wishes to use
-    * @param input input arguments for the algorithm
-    * @param result the object path of the session, if session was created
-    * @return output of the session algorithm negotiation
-    */
-   QVariant openSession(const QString &algorithm, const QVariant &input, \
                QDBusObjectPath &result);
-   
-   /**
-    * Create a new collection with the specified properties.
-    *
-    * @param properties properties for the new collection
-    * @param prompt a prompt object if prompting is necessary, or "/" if no prompt \
                was needed
-    * @return the new collection object or "/" if prompting is necessary
-    */
-   QDBusObjectPath createCollection(const QMap<QString, QVariant> &properties,
-                                    QDBusObjectPath &prompt);
-
-   /**
-    * Find items in any collection.
-    *
-    * @param attributes the attributes an item has to match in order to be found
-    * @param locked items found that require authentication
-    * @return items found that are already unlocked
-    */
-   QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes,
-                                      QList<QDBusObjectPath> &locked);
-                                      
-   /**
-    * Unlock the specified items or collections.
-    *
-    * @param objects objects to unlock
-    * @param prompt a prompt object which can be used to unlock the remaining \
                objects or
-    *               "/" if no prompt is necessary.
-    * @return objects that were unlocked without a prompt
-    */
-   QList<QDBusObjectPath> unlock(const QList<QDBusObjectPath> &objects, \
                QDBusObjectPath &prompt);
-
-   /**
-    * Lock the specified items or collections.
-    *
-    * @param objects objects to lock
-    * @param prompt a prompt to lock the objects or "/" if no prompt is necessary
-    * @return objects that were locked without a prompt
-    */
-   QList<QDBusObjectPath> lock(const QList<QDBusObjectPath> &objects, \
                QDBusObjectPath &prompt);
-
-   /**
-    * Retrieve multiple secrets from different items.
-    *
-    * @param items items to get secrets for
-    * @param session the session to use to encode the secrets
-    * @return the secrets for the items.
-    */
-   QMap<QDBusObjectPath, Secret> getSecrets(const QList<QDBusObjectPath> &items,
-                                            const QDBusObjectPath &session);
-   
-Q_SIGNALS:
-   /**
-    * Emitted when a new collection is discovered or created.
-    *
-    * @param collection Objectpath of the collection that was discovered/created
-    */
-   void collectionCreated(const QDBusObjectPath &collection);
-
-   /**
-    * Emitted when an existing collection was deleted or disappeared.
-    *
-    * @param collection Objectpath of the collection that was deleted
-    */
-   void collectionDeleted(const QDBusObjectPath &collection);
-
-   /**
-    * Emitted when an existing collection changed.
-    *
-    * @param collection Objectpath of the collection that changed
-    */
-   void collectionChanged(const QDBusObjectPath &collection);
-   
-private Q_SLOTS:
-   // handle collectionCreated() calls from master
-   void slotCollectionCreated(BackendCollection *collection);
-   // handle collectionDeleted() calls from master
-   void slotCollectionDeleted(BackendCollection *collection);
-   // handle collectionChanged() calls from master
-   void slotCollectionChanged(BackendCollection *collection);
-   
-private:
-   BackendMaster *m_master;
-   QList<QDBusObjectPath> m_collections; // cache object paths of collections
-   const QDBusObjectPath m_basePath;
-};
-
-#endif
diff --git a/daemon/session.cpp b/daemon/session.cpp
deleted file mode 100644
index 72a6b16..0000000
--- a/daemon/session.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "session.h"
-#include "dbus/sessionadaptor.h"
-#include "service.h"
-
-#include <secrettool.h>
-
-#include <QtDBus/QDBusConnection>
-#include <QtCore/QRegExp>
-
-#include <QtCore/QDebug>
-
-Session::Session(Service *parent)
- : QObject(parent),
-   m_objectPath(parent->objectPath().path() + "/session/" + createId()),
-   m_cipher(0)
-{
-   // register on the bus
-   new orgFreedesktopSecret::SessionAdaptor(this);
-   QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
-}
-
-Session::~Session()
-{
-   delete m_cipher;
-}
-
-const QDBusObjectPath &Session::objectPath() const
-{
-   return m_objectPath;
-}
-
-Session *Session::create(const QString &algorithm, const QVariant &input,
-                         QVariant &output, const QString &peer, Service *parent)
-{
-   static QRegExp rxAlgorithm("^dh-ietf(\\d+)-([^-]+)-([^-]+)-([^-]+)$",
-                              Qt::CaseInsensitive);
-   
-   Session *session = 0;
-   
-   if (algorithm == "plain") {
-      session = new Session(parent);
-      session->m_encrypted = false;
-      output.setValue(QString(""));
-   } else if (rxAlgorithm.exactMatch(algorithm) &&
-              input.type() == QVariant::ByteArray) {
-      QString encalgo = rxAlgorithm.cap(2).toLower();
-      QString blockmode = rxAlgorithm.cap(3).toLower();
-      QString padding = rxAlgorithm.cap(4).toLower();
-
-      QCA::KeyGenerator keygen;
-      
-      // determine the discrete logarithm group to use
-      QCA::DLGroupSet groupnum;
-      switch (rxAlgorithm.cap(1).toInt()) {
-      case 768:
-         groupnum = QCA::IETF_768;
-         break;
-      case 1024:
-         groupnum = QCA::IETF_1024;
-         break;
-      case 1536:
-         groupnum = QCA::IETF_1536;
-         break;
-      case 2048:
-         groupnum = QCA::IETF_2048;
-         break;
-      case 3072:
-         groupnum = QCA::IETF_3072;
-         break;
-      case 4096:
-         groupnum = QCA::IETF_4096;
-         break;
-      case 6144:
-         groupnum = QCA::IETF_6144;
-         break;
-      case 8192:
-         groupnum = QCA::IETF_8192;
-         break;
-      default:
-         // no known discrete logarithm group
-         return 0;
-      }
-      QCA::DLGroup dlgroup(keygen.createDLGroup(groupnum));
-      if (dlgroup.isNull()) {
-         return 0;
-      }
-      
-      // determine if we support (or want to support)
-      // the encryption algorithm.
-      if ((encalgo == "blowfish" || encalgo == "twofish" ||
-           encalgo == "aes128" || encalgo == "aes192" ||
-           encalgo == "aes256") &&
-           QCA::isSupported(QString("%1-%2-%3").arg(encalgo, blockmode, padding)
-                           .toLatin1().constData())) {
-         
-         // get client's public key
-         QCA::DHPublicKey clientKey(dlgroup,
-                                    \
                QCA::BigInteger(QCA::SecureArray(input.toByteArray())));
-         // generate own private key
-         QCA::PrivateKey privKey(keygen.createDH(dlgroup));
-         // generate the shared symmetric key
-         QCA::SymmetricKey sharedKey(privKey.deriveKey(clientKey));
-
-         QCA::Cipher::Mode cbm;
-         if (blockmode == "cbc") {
-            cbm = QCA::Cipher::CBC;
-         } else {
-            return 0;
-         }
-         
-         QCA::Cipher::Padding cp;
-         if (padding == "pkcs7") {
-            cp = QCA::Cipher::PKCS7;
-         } else if (padding == "default") {
-            cp = QCA::Cipher::DefaultPadding;
-         } else {
-            return 0;
-         }
-         
-         QCA::Cipher *cipher = new QCA::Cipher(encalgo, cbm, cp);
-         
-         // check if creating the cipher worked and if our shared
-         // key is longer than the minimum length required.
-         if (sharedKey.size() >= cipher->keyLength().minimum()) {
-            // generate the response to the client so it can derive
-            // the key as well.
-            session = new Session(parent);
-            session->m_encrypted = true;
-            session->m_cipher = cipher;
-            session->m_symmetricKey = sharedKey;
-            output.setValue(privKey.toPublicKey().toDH().y().toArray().toByteArray());
                
-         } else {
-            return 0;
-         }
-      }
-   } else {
-      return 0;
-   }
-
-   // creating the session was successful
-   session->m_peer = peer;
-   return session;
-}
-
-Secret Session::encrypt(const QCA::SecureArray &value, bool &ok)
-{
-   ok = false;
-
-   Secret s;
-   s.setSession(m_objectPath);
-   if (m_encrypted) {
-      Q_ASSERT(m_cipher);
-      QCA::InitializationVector iv(m_cipher->blockSize());
-      m_cipher->setup(QCA::Encode, m_symmetricKey, iv);
-      QCA::SecureArray encval = m_cipher->update(value);
-      if (!m_cipher->ok()) {
-         return s;
-      }
-      encval += m_cipher->final();
-      if (m_cipher->ok()) {
-         return s;
-      }
-      s.setValue(encval.toByteArray());
-      s.setParameters(iv.toByteArray());
-   } else {
-      s.setValue(value.toByteArray());      
-   }
-
-
-   ok = true;
-   return s;
-}
-
-QCA::SecureArray Session::decrypt(const Secret &secret, bool &ok)
-{
-   // make sure this is really meant for us
-   Q_ASSERT(secret.session() == m_objectPath);
-   ok = false;
-   
-   QCA::SecureArray value;
-   if (m_encrypted) {
-      Q_ASSERT(m_cipher);
-      if (!secret.parameters().size() == m_cipher->blockSize()) {
-         return value;
-      }
-      QCA::InitializationVector iv(secret.parameters());
-      m_cipher->setup(QCA::Decode, m_symmetricKey, iv);
-      value = m_cipher->update(secret.value());
-      if (!m_cipher->ok()) {
-         return value;
-      }
-      value += m_cipher->final();
-      if (!m_cipher->ok()) {
-         return value;
-      }
-   } else {
-      value = secret.value();
-   }
-
-   ok = true;
-   return value;
-}
-
-void Session::close()
-{
-   deleteLater();
-}
-
-const QString &Session::peer() const
-{
-   return m_peer;
-}
-
-#include "session.moc"
diff --git a/daemon/session.h b/daemon/session.h
deleted file mode 100644
index e2cb335..0000000
--- a/daemon/session.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAEMON_SESSION_H
-#define DAEMON_SESSION_H
-
-#include "secret.h"
-
-#include <QtCore/QObject>
-#include <QtCrypto/QtCrypto>
-
-class Service;
-
-/**
- * Represents an open session of a client on the D-Bus implementing the
- * org.freedesktop.Secret.Session interface.
- *
- * @todo stub implementation, currently only supports plain (no encryption)
- */
-class Session : public QObject
-{
-   Q_OBJECT
-
-private:
-   /**
-    * Constructor.
-    *
-    * @param parent Parent Service object
-    */
-   Session(Service *parent);
-
-public:
-   /**
-    * Destructor.
-    */
-   ~Session();
-   
-   /**
-    * Get the session's object path.
-    */
-   const QDBusObjectPath &objectPath() const;
-   
-   /**
-    * Try to create a (possibly encrypted) session for the use of transferring
-    * secrets.
-    *
-    * @param algorithm the negotiation/encryption algorithm to use
-    * @param input negotiation algorithm input
-    * @param output negotiation algorithm output
-    * @param parent Parent Service object
-    * @return a session object if negotiation was successful, 0 if the algorithm \
                isn't
-    *         supported or an error occurred
-    */
-   static Session *create(const QString &algorithm, const QVariant &input,
-                          QVariant &output, const QString &peer, Service *parent);
-
-   /**
-    * Encrypt a secret value using this session.
-    *
-    * @param value value to encrypt
-    * @param ok set to true if encrypting succeeds, set to false else
-    * @return the secret encrypted for transport
-    */
-   Secret encrypt(const QCA::SecureArray &value, bool &ok);
-
-   /**
-    * Decrypt a secret value using this session.
-    *
-    * @param secret Secret received on the D-Bus
-    * @param ok set to true if decrypting succeeds, set to false else
-    * @return the unencryped value
-    */
-   QCA::SecureArray decrypt(const Secret &secret, bool &ok);
-                             
-   /**
-    * Close this session.
-    */
-   void close();
-   
-   /**
-    * Get the session's D-Bus peer (the client requesting the session).
-    */
-   const QString &peer() const;
-
-private:
-   QDBusObjectPath m_objectPath;
-   QString m_peer; // D-Bus address of the application that requested this session
-   
-   // if true, use encryption, if false, use plaintext
-   bool m_encrypted;
-   
-   // the cipher and the symmetric key used for encryption
-   QCA::Cipher *m_cipher;
-   QCA::SymmetricKey m_symmetricKey;
-};
-
-#endif
diff --git a/daemon/tests/CMakeLists.txt b/daemon/tests/CMakeLists.txt
deleted file mode 100644
index 04029ff..0000000
--- a/daemon/tests/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
-
-INCLUDE_DIRECTORIES (
-   ${KDE4_INCLUDES}
-   ${QCA2_INCLUDE_DIR}
-   ${CMAKE_SOURCE_DIR}
-   ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-KDE4_ADD_EXECUTABLE (ksecretservice_daemon_test
-   servicetest.cpp
-   tempblockingcollectionmanager.cpp
-   tempblockingcollection.cpp
-   tempblockingitem.cpp
-   tempblockingjobs.cpp
-)
-TARGET_LINK_LIBRARIES (ksecretservice_daemon_test
-   ksecretservicebackend
-   ksecretservicedaemon
-   ksecretservicelib
-   ${QT_QTTEST_LIBRARIES}
-)
-
-ADD_TEST (DaemonSessionTest ksecretservice_daemon_test)
diff --git a/daemon/tests/servicetest.cpp b/daemon/tests/servicetest.cpp
deleted file mode 100644
index 000dcc4..0000000
--- a/daemon/tests/servicetest.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "servicetest.h"
-
-#include "backend/backendmaster.h"
-#include "backend/temporary/temporarycollectionmanager.h"
-#include "tempblockingcollectionmanager.h"
-#include "daemon/service.h"
-#include "daemon/dbus/dbustypes.h"
-
-#include <qtest_kde.h>
-
-#include <QtTest/QTest>
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusInterface>
-#include <QtDBus/QDBusMessage>
-#include <QtDBus/QDBusReply>
-#include <QtDBus/QDBusConnectionInterface>
-#include <QtCrypto/QtCrypto>
-
-#include <QtCore/QDebug>
-
-void ServiceTest::initTestCase()
-{
-   QVERIFY(QDBusConnection::sessionBus().registerService("org.freedesktop.Secret"));
-
-   QCA::init();
-   
-   m_master = new BackendMaster;
-   m_tempCollMan = new TemporaryCollectionManager(m_master);
-   m_master->addManager(m_tempCollMan);
-   m_service = new Service(m_master);
-}
-
-void ServiceTest::dbusService()
-{
-   // make sure the service is available
-   QDBusConnectionInterface *ifaceConn = QDBusConnection::sessionBus().interface();
-   QVERIFY(ifaceConn && ifaceConn->isValid());
-
-   QDBusReply<bool> registered = \
                ifaceConn->isServiceRegistered("org.freedesktop.Secret");
-   QVERIFY(registered.isValid());
-   QVERIFY(registered.value());
-}
-
-void ServiceTest::session()
-{
-   QDBusInterface ifaceService("org.freedesktop.Secret", \
                "/org/freedesktop/secrets");
-   QVERIFY(ifaceService.isValid());
-   QCA::KeyGenerator keygen;
-   
-   // "unsupported" session algorithm
-   QList<QVariant> unsuppInput;
-   unsuppInput << QString("unsupported") << \
                QVariant::fromValue(QDBusVariant(QString("")));
-   QDBusMessage unsuppReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "OpenSession",
-                                                                unsuppInput);
-   QCOMPARE(unsuppReply.type(), QDBusMessage::ErrorMessage);
-   QCOMPARE(unsuppReply.errorName(),
-            QLatin1String("org.freedesktop.Secret.Error.NotSupported"));
-
-   // "plain" session algorithm
-   QDBusObjectPath plainPath;
-   QList<QVariant> plainInput;
-   plainInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
-   QDBusMessage plainReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "OpenSession",
-                                                               plainInput);
-   QCOMPARE(plainReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> plainArgs = plainReply.arguments();
-   QCOMPARE(plainArgs.size(), 2);
-   QCOMPARE(plainArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
-   QCOMPARE(plainArgs.at(0).value<QString>(), QLatin1String(""));
-   QCOMPARE(plainArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
-   plainPath = plainArgs.at(1).value<QDBusObjectPath>();
-   QVERIFY(plainPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
                
-   QDBusInterface plainIface("org.freedesktop.Secret", plainPath.path(),
-                             "org.freedesktop.Secret.Session");
-   QVERIFY(plainIface.isValid());
-   QDBusMessage plainReply2 = plainIface.call("Close");
-   QCOMPARE(plainReply2.type(), QDBusMessage::ReplyMessage);
-   QCOMPARE(plainIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
-
-   // "dh-ietf1024-aes128-cbc-pkcs7" encryption
-   QDBusObjectPath dhPath;
-   QList<QVariant> dhInput;
-   QCA::DLGroup dhDlgroup(keygen.createDLGroup(QCA::IETF_1024));
-   QVERIFY(!dhDlgroup.isNull());
-   QCA::PrivateKey dhPrivkey(keygen.createDH(dhDlgroup));
-   QCA::PublicKey dhPubkey(dhPrivkey);
-   QByteArray dhBytePub(dhPubkey.toDH().y().toArray().toByteArray());
-   dhInput << QString("dh-ietf1024-aes128-cbc-pkcs7")
-           << QVariant::fromValue(QDBusVariant(dhBytePub));
-   QDBusMessage dhReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "OpenSession",
-                                                            dhInput);
-   QCOMPARE(dhReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> dhArgs = dhReply.arguments();
-   QCOMPARE(dhArgs.size(), 2);
-   QCOMPARE(dhArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
-   QVariant dhOutputVar = dhArgs.at(0).value<QDBusVariant>().variant();
-   QCOMPARE(dhOutputVar.type(), QVariant::ByteArray);
-   QByteArray dhOutput = dhOutputVar.toByteArray();
-   QCA::DHPublicKey dhServiceKey(dhDlgroup,
-                                 QCA::BigInteger(QCA::SecureArray(dhOutput)));
-   QCA::SymmetricKey dhSharedKey(dhPrivkey.deriveKey(dhServiceKey));
-   QCA::Cipher *dhCipher = new QCA::Cipher("aes128", QCA::Cipher::CBC, \
                QCA::Cipher::PKCS7);
-   QVERIFY(dhSharedKey.size() >= dhCipher->keyLength().minimum());
-   QCOMPARE(plainArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
-   dhPath = dhArgs.at(1).value<QDBusObjectPath>();
-   QVERIFY(dhPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
                
-   QDBusInterface dhIface("org.freedesktop.Secret", dhPath.path(),
-                          "org.freedesktop.Secret.Session");
-   QVERIFY(dhIface.isValid());
-   QDBusMessage dhReply2 = dhIface.call("Close");
-   QCOMPARE(dhReply2.type(), QDBusMessage::ReplyMessage);
-   QCOMPARE(dhIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
-}
-
-void ServiceTest::nonBlockingCollection()
-{
-   QDBusInterface ifaceService("org.freedesktop.Secret", \
                "/org/freedesktop/secrets");
-   QVERIFY(ifaceService.isValid());
-
-   // create a session
-   QDBusObjectPath sessionPath;
-   QList<QVariant> sessionInput;
-   sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
-   QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "OpenSession",
-                                                                 sessionInput);
-   sessionPath = sessionReply.arguments().at(1).value<QDBusObjectPath>();
-
-   // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
-   ObjectPathSignalSpy createdSpy(&ifaceService, \
                SIGNAL(CollectionCreated(QDBusObjectPath)));
-   QVERIFY(createdSpy.isValid());
-   ObjectPathSignalSpy deletedSpy(&ifaceService, \
                SIGNAL(CollectionDeleted(QDBusObjectPath)));
-   QVERIFY(deletedSpy.isValid());
-   ObjectPathSignalSpy changedSpy(&ifaceService, \
                SIGNAL(CollectionChanged(QDBusObjectPath)));
-   QVERIFY(changedSpy.isValid());
-   
-   // create a collection
-   QDBusObjectPath collectionPath;
-   QMap<QString, QVariant> createProperties;
-   QList<QVariant> createInput;
-   createProperties["Label"] = "test";
-   createProperties["Locked"] = false; // create collection unlocked
-   createInput << QVariant::fromValue(createProperties);
-   QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "CreateCollection",
-                                                                createInput);
-                                                                
-   QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> createArgs = createReply.arguments();
-   QCOMPARE(createArgs.size(), 2);
-   QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
-   // CreateCollection is blocking, so the first output (path) should be "/".
-   QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
-   QDBusObjectPath promptPath = createArgs.at(1).value<QDBusObjectPath>();
-   QVERIFY(promptPath.path().startsWith(
-           QLatin1String("/org/freedesktop/secrets/prompts/")));
-
-   // prompt and wait for the result.
-   ClientPrompt *prompt = new ClientPrompt(promptPath);
-   prompt->promptAndWait(5000);
-   QVERIFY(prompt->completed());
-   QVERIFY(!prompt->dismissed());
-   QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
-   collectionPath = prompt->result().value<QDBusObjectPath>();
-   QVERIFY(collectionPath.path().startsWith(
-           QLatin1String("/org/freedesktop/secrets/collection/")));
-   QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
-                                  "org.freedesktop.Secret.Collection");
-   QVERIFY(ifaceCollection.isValid());
-   delete prompt;
-
-   // make sure the CollectionCreated signal was sent
-   if (createdSpy.size() < 1) {
-      createdSpy.waitForSignal(5000);
-   }
-   QCOMPARE(createdSpy.size(), 1);
-   QCOMPARE(createdSpy.takeFirst(), collectionPath);
-
-   // read collection properties
-   QVariant propItems = ifaceCollection.property("Items");
-   QVERIFY(propItems.isValid());
-   QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
-   QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
                >();
-   QVERIFY(propItemsList.isEmpty());
-   QVariant propLabel = ifaceCollection.property("Label");
-   QVERIFY(propLabel.isValid());
-   QCOMPARE(propLabel.type(), QVariant::String);
-   QCOMPARE(propLabel.value<QString>(), QString("test"));
-   QVariant propLocked = ifaceCollection.property("Locked");
-   QVERIFY(propLocked.isValid());
-   QCOMPARE(propLocked.value<bool>(), false);
-   QVariant propCreated = ifaceCollection.property("Created");
-   QVERIFY(propCreated.isValid());
-   QCOMPARE(propCreated.type(), QVariant::ULongLong);
-   qulonglong propCreatedUll = propCreated.value<qulonglong>();
-   QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
-   QVariant propModified = ifaceCollection.property("Modified");
-   QVERIFY(propModified.isValid());
-   QCOMPARE(propModified.type(), QVariant::ULongLong);
-   QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
-   
-   // set the label and re-read it.
-   ifaceCollection.setProperty("Label", QString("test2"));
-   propLabel = ifaceCollection.property("Label");
-   QVERIFY(propLabel.isValid());
-   QCOMPARE(propLabel.type(), QVariant::String);
-   QCOMPARE(propLabel.value<QString>(), QString("test2"));
-   
-   // make sure the CollectionChanged signal was sent
-   if (changedSpy.size() < 1) {
-      changedSpy.waitForSignal(5000);
-   }
-   QCOMPARE(changedSpy.size(), 1);
-   QCOMPARE(changedSpy.takeFirst(), collectionPath);
-
-   // delete the collection
-   QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
-   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> deleteArgs = deleteReply.arguments();
-   QCOMPARE(deleteArgs.size(), 1);
-   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TemporaryCollection is non-blocking, so the output (prompt) should be "/".
-   QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
-   // make sure the collection is gone
-   QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
-   
-   // make sure the CollectionDeleted signal was sent
-   if (deletedSpy.size() < 1) {
-      deletedSpy.waitForSignal(5000);
-   }
-   QCOMPARE(deletedSpy.size(), 1);
-   QCOMPARE(deletedSpy.takeFirst(), collectionPath);
-   
-   // close the session
-   QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
-}
-
-void ServiceTest::nonBlockingItem()
-{
-   QDBusInterface ifaceService("org.freedesktop.Secret", \
                "/org/freedesktop/secrets");
-
-   // create a session
-   QDBusObjectPath sessionPath;
-   QList<QVariant> sessionInput;
-   sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
-   QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "OpenSession",
-                                                                 sessionInput);
-   sessionPath = sessionReply.arguments().at(1).value<QDBusObjectPath>();
-   
-   // create a collection
-   QDBusObjectPath collectionPath;
-   QMap<QString, QVariant> collProperties;
-   QList<QVariant> collInput;
-   collProperties["Label"] = "test3";
-   collProperties["Locked"] = false;
-   collInput << QVariant::fromValue(collProperties);
-   QDBusMessage collReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "CreateCollection",
-                                                              collInput);
-   QDBusObjectPath promptPath = \
                collReply.arguments().at(1).value<QDBusObjectPath>();
-   ClientPrompt *prompt = new ClientPrompt(promptPath);
-   prompt->promptAndWait(5000);
-   QVERIFY(prompt->completed());
-   collectionPath = prompt->result().value<QDBusObjectPath>();
-   delete prompt;
-   QDBusInterface ifaceColl("org.freedesktop.Secret", collectionPath.path());
-   
-   ObjectPathSignalSpy createdSpy(&ifaceColl, SIGNAL(ItemCreated(QDBusObjectPath)));
-   QVERIFY(createdSpy.isValid());
-   ObjectPathSignalSpy deletedSpy(&ifaceColl, SIGNAL(ItemDeleted(QDBusObjectPath)));
-   QVERIFY(deletedSpy.isValid());
-   ObjectPathSignalSpy changedSpy(&ifaceColl, SIGNAL(ItemChanged(QDBusObjectPath)));
-   QVERIFY(changedSpy.isValid());
-   
-   // create an item
-   QDBusObjectPath itemPath;
-   StringStringMap itemAttributes;
-   itemAttributes["attribute1"] = "value1";
-   itemAttributes["attribute2"] = "value2";
-   QMap<QString, QVariant> itemProperties;
-   itemProperties["Attributes"] = QVariant::fromValue(itemAttributes);
-   itemProperties["Label"] = "item1";
-   itemProperties["Locked"] = false;
-   QList<QVariant> itemInput;
-   Secret secret;
-   secret.setSession(sessionPath);
-   secret.setValue(QByteArray("mysecret"));
-   itemInput << QVariant::fromValue(itemProperties);
-   itemInput << QVariant::fromValue(secret);
-   itemInput << false;
-   QDBusMessage itemReply = ifaceColl.callWithArgumentList(QDBus::Block, \
                "CreateItem",
-                                                           itemInput);
-   QCOMPARE(itemReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> itemArgs = itemReply.arguments();
-   QCOMPARE(itemArgs.size(), 2);
-   QCOMPARE(itemArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   QCOMPARE(itemArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TemporaryItem is non-blocking, so the second output (prompt) should be "/"
-   QCOMPARE(itemArgs.at(1).value<QDBusObjectPath>().path(), QLatin1String("/"));
-   itemPath = itemArgs.at(0).value<QDBusObjectPath>();
-   QVERIFY(itemPath.path().startsWith(collectionPath.path() + "/"));
-   QDBusInterface ifaceItem("org.freedesktop.Secret", itemPath.path(),
-                            "org.freedesktop.Secret.Item");
-   QVERIFY(ifaceItem.isValid());
-   
-   // make sure the ItemCreated signal was sent
-   if (createdSpy.size() < 1) {
-      createdSpy.waitForSignal(5000);
-   }
-   QCOMPARE(createdSpy.size(), 1);
-   QCOMPARE(createdSpy.takeFirst(), itemPath);
-   
-   // check if the collection's Items property contains the item.
-   QVariant propItems = ifaceColl.property("Items");
-   QVERIFY(propItems.isValid());
-   QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
-   QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
                >();
-   QCOMPARE(propItemsList.count(), 1);
-   QCOMPARE(propItemsList.at(0), itemPath);
-
-   // read item properties
-   QVariant propLocked = ifaceItem.property("Locked");
-   QVERIFY(propLocked.isValid());
-   QCOMPARE(propLocked.type(), QVariant::Bool);
-   QCOMPARE(propLocked.value<bool>(), false);
-   QVariant propLabel = ifaceItem.property("Label");
-   QVERIFY(propLabel.isValid());
-   QCOMPARE(propLabel.type(), QVariant::String);
-   QCOMPARE(propLabel.value<QString>(), QLatin1String("item1"));
-   QVariant propCreated = ifaceItem.property("Created");
-   QVERIFY(propCreated.isValid());
-   QCOMPARE(propCreated.type(), QVariant::ULongLong);
-   qulonglong propCreatedUll = propCreated.value<qulonglong>();
-   QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
-   QVariant propModified = ifaceItem.property("Modified");
-   QVERIFY(propModified.isValid());
-   QCOMPARE(propModified.type(), QVariant::ULongLong);
-   QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
-   QVariant propAttributes = ifaceItem.property("Attributes");
-   QVERIFY(propAttributes.isValid());
-   QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
-   StringStringMap propAttributesMap = propAttributes.value<StringStringMap>();
-   QCOMPARE(propAttributesMap.size(), 2);
-   QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("value1"));
-   QCOMPARE(propAttributesMap.value("attribute2"), QLatin1String("value2"));
-   
-   // read the secret
-   QDBusMessage secretReply = ifaceItem.call(QDBus::Block, "GetSecret",
-                                             \
                QVariant::fromValue<QDBusObjectPath>(sessionPath));
-   QCOMPARE(secretReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> secretOutput = secretReply.arguments();
-   QCOMPARE(secretOutput.count(), 1);
-   Secret outsecret = qdbus_cast<Secret>(secretOutput.at(0));
-   QCOMPARE(outsecret.session(), sessionPath);
-   QCOMPARE(outsecret.value(), QByteArray("mysecret"));
-   
-   // set and re-read item properties
-   ifaceItem.setProperty("Label", QString("item2"));
-   propLabel = ifaceItem.property("Label");
-   QVERIFY(propLabel.isValid());
-   QCOMPARE(propLabel.type(), QVariant::String);
-   QCOMPARE(propLabel.value<QString>(), QLatin1String("item2"));
-   propAttributesMap["attribute3"] = "value3";
-   propAttributesMap["attribute1"] = "othervalue";
-   propAttributesMap.remove("attribute2");
-   ifaceItem.setProperty("Attributes", \
                QVariant::fromValue<StringStringMap>(propAttributesMap));
-   propAttributes = ifaceItem.property("Attributes");
-   QVERIFY(propAttributes.isValid());
-   QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
-   propAttributesMap = propAttributes.value<StringStringMap>();
-   QCOMPARE(propAttributesMap.size(), 2);
-   QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("othervalue"));
-   QCOMPARE(propAttributesMap.value("attribute3"), QLatin1String("value3"));
-   
-   // set and re-read the secret
-   secret.setValue("mysecret2");
-   secretReply = ifaceItem.call(QDBus::Block, "SetSecret", \
                QVariant::fromValue<Secret>(secret));
-   QCOMPARE(secretReply.type(), QDBusMessage::ReplyMessage);
-   secretReply = ifaceItem.call(QDBus::Block, "GetSecret",
-                                QVariant::fromValue<QDBusObjectPath>(sessionPath));
-   QCOMPARE(secretReply.type(), QDBusMessage::ReplyMessage);
-   secretOutput = secretReply.arguments();
-   QCOMPARE(secretOutput.count(), 1);
-   outsecret = qdbus_cast<Secret>(secretOutput.at(0));
-   QCOMPARE(outsecret.session(), sessionPath);
-   QCOMPARE(outsecret.value(), QByteArray("mysecret2"));
-   
-
-   // we should have received 2 ItemChanged signals
-   if (changedSpy.size() < 3) {
-      changedSpy.waitForSignals(3, 5000);
-   }
-   QCOMPARE(changedSpy.size(), 3);
-   QCOMPARE(changedSpy.takeFirst(), itemPath);
-   QCOMPARE(changedSpy.takeFirst(), itemPath);
-   QCOMPARE(changedSpy.takeFirst(), itemPath);
-   
-   // delete the item
-   QDBusMessage deleteReply = ifaceItem.call(QDBus::Block, "Delete");
-   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> deleteArgs = deleteReply.arguments();
-   QCOMPARE(deleteArgs.size(), 1);
-   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TemporaryItem is non-blocking, so the output (prompt) should be "/"
-   QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
-   // make sure the item is gone
-   QCOMPARE(ifaceItem.call("Introspect").type(), QDBusMessage::ErrorMessage);
-   
-   // make sure the ItemDeleted signal was sent
-   if (deletedSpy.size() < 1) {
-      deletedSpy.waitForSignal(5000);
-   }
-   QCOMPARE(deletedSpy.size(), 1);
-   QCOMPARE(deletedSpy.takeFirst(), itemPath);
-   
-   // delete the collection
-   ifaceColl.call(QDBus::Block, "Delete");
-   // close the session
-   QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
-}
-
-void ServiceTest::reInitTestCase()
-{
-   // remove the TemporaryCollectionManager and replace it with a \
                TempBlockingCollectionManager
-   m_master->removeManager(m_tempCollMan);
-   delete m_tempCollMan;
-   m_tempBlockCollMan = new TempBlockingCollectionManager(m_master);
-   m_master->addManager(m_tempBlockCollMan);
-}
-
-void ServiceTest::blockingCollection()
-{
-   ClientPrompt *prompt = 0;
-   
-   QDBusInterface ifaceService("org.freedesktop.Secret", \
                "/org/freedesktop/secrets");
-   QVERIFY(ifaceService.isValid());
-
-   // create a session
-   // create a session
-   QDBusObjectPath sessionPath;
-   QList<QVariant> sessionInput;
-   sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
-   QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "OpenSession",
-                                                                 sessionInput);
-   sessionPath = sessionReply.arguments().at(1).value<QDBusObjectPath>();
-
-   // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
-   ObjectPathSignalSpy createdSpy(&ifaceService, \
                SIGNAL(CollectionCreated(QDBusObjectPath)));
-   QVERIFY(createdSpy.isValid());
-   ObjectPathSignalSpy deletedSpy(&ifaceService, \
                SIGNAL(CollectionDeleted(QDBusObjectPath)));
-   QVERIFY(deletedSpy.isValid());
-   ObjectPathSignalSpy changedSpy(&ifaceService, \
                SIGNAL(CollectionChanged(QDBusObjectPath)));
-   QVERIFY(changedSpy.isValid());
-
-   // create a collection
-   QDBusObjectPath promptPath;
-   QMap<QString, QVariant> createProperties;
-   QList<QVariant> createInput;
-   createProperties["Label"] = "test";
-   createProperties["Locked"] = false; // create collection unlocked
-   createInput << QVariant::fromValue(createProperties);
-   QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
                "CreateCollection",
-                                                                createInput);
-   QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> createArgs = createReply.arguments();
-   QCOMPARE(createArgs.size(), 2);
-   QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TempBlockingCollection is blocking, so the first output (path) should be "/".
-   QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
-   promptPath = createArgs.at(1).value<QDBusObjectPath>();
-   QVERIFY(promptPath.path().startsWith(
-           QLatin1String("/org/freedesktop/secrets/prompts/")));
-
-   // dismiss the prompt and wait for the result.
-   prompt = new ClientPrompt(promptPath);
-   prompt->dismissAndWait(5000);
-   QVERIFY(prompt->completed());
-   QVERIFY(prompt->dismissed());
-   delete prompt;
-
-   createReply = ifaceService.callWithArgumentList(QDBus::Block, "CreateCollection",
-                                                   createInput);
-   QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
-   createArgs = createReply.arguments();
-   QCOMPARE(createArgs.size(), 2);
-   QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TempBlockingCollection is blocking, so the first output (path) should be "/".
-   QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
-   promptPath = createArgs.at(1).value<QDBusObjectPath>();
-   QVERIFY(promptPath.path().startsWith(
-           QLatin1String("/org/freedesktop/secrets/prompts/")));
-
-   // prompt and wait for the result.
-   prompt = new ClientPrompt(promptPath);
-   prompt->promptAndWait(5000);
-   QVERIFY(prompt->completed());
-   QVERIFY(!prompt->dismissed());
-   QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
-   QDBusObjectPath collectionPath = prompt->result().value<QDBusObjectPath>();
-   QVERIFY(collectionPath.path().startsWith(
-           QLatin1String("/org/freedesktop/secrets/collection/")));
-   QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
-                                  "org.freedesktop.Secret.Collection");
-   QVERIFY(ifaceCollection.isValid());
-   delete prompt;
-
-   // make sure the CollectionCreated signal was sent
-   if (createdSpy.size() < 1) {
-      createdSpy.waitForSignal(5000);
-   }
-   QCOMPARE(createdSpy.size(), 1);
-   QCOMPARE(createdSpy.takeFirst(), collectionPath);
-
-   // read collection properties
-   QVariant propItems = ifaceCollection.property("Items");
-   QVERIFY(propItems.isValid());
-   QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
-   QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
                >();
-   QVERIFY(propItemsList.isEmpty());
-   QVariant propLabel = ifaceCollection.property("Label");
-   QVERIFY(propLabel.isValid());
-   QCOMPARE(propLabel.type(), QVariant::String);
-   QCOMPARE(propLabel.value<QString>(), QString("test"));
-   QVariant propLocked = ifaceCollection.property("Locked");
-   QVERIFY(propLocked.isValid());
-   QCOMPARE(propLocked.value<bool>(), false);
-   QVariant propCreated = ifaceCollection.property("Created");
-   QVERIFY(propCreated.isValid());
-   QCOMPARE(propCreated.type(), QVariant::ULongLong);
-   qulonglong propCreatedUll = propCreated.value<qulonglong>();
-   QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
-   QVariant propModified = ifaceCollection.property("Modified");
-   QVERIFY(propModified.isValid());
-   QCOMPARE(propModified.type(), QVariant::ULongLong);
-   QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
-
-   // set the label and re-read it.
-   ifaceCollection.setProperty("Label", QString("test2"));
-   propLabel = ifaceCollection.property("Label");
-   QVERIFY(propLabel.isValid());
-   QCOMPARE(propLabel.type(), QVariant::String);
-   QCOMPARE(propLabel.value<QString>(), QString("test2"));
-
-   // make sure the CollectionChanged signal was sent
-   if (changedSpy.size() < 1) {
-      changedSpy.waitForSignal(5000);
-   }
-   QCOMPARE(changedSpy.size(), 1);
-   QCOMPARE(changedSpy.takeFirst(), collectionPath);
-
-   // delete the collection
-   QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
-   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
-   QList<QVariant> deleteArgs = deleteReply.arguments();
-   QCOMPARE(deleteArgs.size(), 1);
-   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
                one.
-   promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
-   QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
                
-
-   // dismiss the prompt and wait for the result.
-   prompt = new ClientPrompt(promptPath);
-   prompt->dismissAndWait(5000);
-   QVERIFY(prompt->completed());
-   QVERIFY(prompt->dismissed());
-   delete prompt;
-
-   // retry and complete the prompt this time
-   deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
-   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
-   deleteArgs = deleteReply.arguments();
-   QCOMPARE(deleteArgs.size(), 1);
-   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
-   // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
                one.
-   promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
-   QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
                
-   prompt = new ClientPrompt(promptPath);
-   prompt->promptAndWait(5000);
-   QVERIFY(prompt->completed());
-   QVERIFY(!prompt->dismissed());
-   delete prompt;
-
-   // make sure the collection is gone
-   QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
-
-   // make sure the CollectionDeleted signal was sent
-   if (deletedSpy.size() < 1) {
-      deletedSpy.waitForSignal(5000);
-   }
-   QCOMPARE(deletedSpy.size(), 1);
-   QCOMPARE(deletedSpy.takeFirst(), collectionPath);
-
-   // close the session
-   QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
-}
-
-void ServiceTest::blockingItem()
-{
-   // TODO: test
-}
-
-void ServiceTest::cleanupTestCase()
-{
-   delete m_service;
-   delete m_master;
-
-   QCA::deinit();
-}
-
-QTEST_KDEMAIN_CORE(ServiceTest)
-
-ObjectPathSignalSpy::ObjectPathSignalSpy(QDBusAbstractInterface *iface,
-                                         const char *signal)
-{
-   m_valid = connect(iface, signal, SLOT(slotReceived(QDBusObjectPath)));
-}
-
-bool ObjectPathSignalSpy::isValid() const
-{
-   return m_valid;
-}
-
-void ObjectPathSignalSpy::waitForSignal(int time)
-{
-   waitForSignals(1, time);
-}
-
-void ObjectPathSignalSpy::waitForSignals(int num, int time)
-{
-   m_numWaiting = num;
-   if (count() < m_numWaiting)
-   {
-      QEventLoop loop;
-      loop.connect(this, SIGNAL(doneWaiting()), SLOT(quit()));
-      QTimer::singleShot(time, &loop, SLOT(quit()));
-      loop.exec();
-   }
-}
-
-void ObjectPathSignalSpy::slotReceived(const QDBusObjectPath &objectPath)
-{
-   append(objectPath);
-   if (count() >= m_numWaiting) {
-      emit doneWaiting();
-   }
-}
-
-ClientPrompt::ClientPrompt(QDBusObjectPath promptPath)
- : m_completed(false), m_dismissed(false),
-   m_interface("org.freedesktop.Secret", promptPath.path())
-{
-   Q_ASSERT(m_interface.isValid());
-   connect(&m_interface, SIGNAL(Completed(bool, QDBusVariant)),
-                         SLOT(slotCompleted(bool, QDBusVariant)));
-}
-
-void ClientPrompt::promptAndWait(int time)
-{
-   QDBusMessage reply = m_interface.call(QDBus::Block, "Prompt", QString(""));
-   Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
-   justWait(time);
-}
-
-void ClientPrompt::dismissAndWait(int time)
-{
-   QDBusMessage reply = m_interface.call(QDBus::Block, "Dismiss");
-   Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
-   justWait(time);
-}
-
-void ClientPrompt::slotCompleted(bool dismissed, const QDBusVariant &result)
-{
-   m_completed = true;
-   m_dismissed = dismissed;
-   m_result = result.variant();
-   m_loop.quit();
-}
-
-void ClientPrompt::justWait(int time)
-{
-   if (time > 0) {
-      QTimer::singleShot(time, &m_loop, SLOT(quit()));
-   }
-   m_loop.exec();
-}
-
-#include "servicetest.moc"
diff --git a/daemon/tests/servicetest.h b/daemon/tests/servicetest.h
deleted file mode 100644
index 4f9dbb3..0000000
--- a/daemon/tests/servicetest.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef SERVICETEST_H
-#define SERVICETEST_H
-
-#include <QtCore/QObject>
-#include <QtCore/QList>
-#include <QtCore/QVariant>
-#include <QtCore/QEventLoop>
-#include <QtDBus/QDBusVariant>
-#include <QtDBus/QDBusObjectPath>
-#include <QtDBus/QDBusInterface>
-
-class BackendMaster;
-class TemporaryCollectionManager;
-class TempBlockingCollectionManager;
-class Service;
-class QDBusAbstractInterface;
-
-/**
- * Unit-test for the fd.o Secret daemon
- */
-class ServiceTest : public QObject
-{
-   Q_OBJECT
-
-private:
-   BackendMaster *m_master;
-   TemporaryCollectionManager *m_tempCollMan;
-   TempBlockingCollectionManager *m_tempBlockCollMan;
-   Service *m_service;
-
-private Q_SLOTS:
-   // create services and collections needed for testing
-   void initTestCase();
-
-   // check if Service is registered with D-Bus
-   void dbusService();
-
-   // open various sessions, make sure they are available on the bus, then close \
                them.
-   void session();
-
-   // create and remove collections
-   void nonBlockingCollection();
-   
-   // create and remove items
-   void nonBlockingItem();
-
-   // change some of the parameters of the testcase needed for the tests to come
-   void reInitTestCase();
-   
-   // create and remove blocking collections
-   void blockingCollection();
-
-   // create and remove blocking items
-   void blockingItem();
-
-   // cleanup
-   void cleanupTestCase();
-};
-
-/**
- * Listens to D-Bus signals which only have an object-path
- * as only argument.
- */
-class ObjectPathSignalSpy : public QObject, public QList<QDBusObjectPath>
-{
-   Q_OBJECT
-
-public:
-   // constructor. similar to QSignalSpy's constructor.
-   ObjectPathSignalSpy(QDBusAbstractInterface *iface, const char *signal);
-   
-   // return true if the connection to the signal was successful
-   bool isValid() const;
-   
-   // wait a specified number of ms for the signal to be received.
-   void waitForSignal(int time);
-   
-   // wait a specified number of ms for multiple signals to be received
-   void waitForSignals(int num, int time);
-
-Q_SIGNALS:
-   // stop waiting for the signal.
-   void doneWaiting();
-   
-private Q_SLOTS:
-   // Single slot which receives all of the various signals.
-   void slotReceived(const QDBusObjectPath &objectPath);
-   
-private:
-   bool m_valid;
-   int m_numWaiting;
-};
-
-/**
- * Client mini-stub for org.freedesktop.Secret.Prompt.
- */
-class ClientPrompt : public QObject
-{
-   Q_OBJECT
-
-public:
-   // constructor. wraps around the prompt at promptPath.
-   ClientPrompt(QDBusObjectPath promptPath);
-
-   // Call the Prompt method and wait some time for completion
-   // (sends bogus window-id)
-   void promptAndWait(int time);
-
-   // Call the Dismiss method and wait some time for completion
-   void dismissAndWait(int time);
-
-   // check if the call has been completed
-   bool completed() const {
-      return m_completed;
-   }
-
-   // check if the call was dismissed
-   bool dismissed() const {
-      return m_dismissed;
-   }
-
-   // get the call's result
-   const QVariant &result() const {
-      return m_result;
-   }
-
-private Q_SLOTS:
-   // listens for Completed signals of the D-Bus prompt.
-   void slotCompleted(bool dismissed, const QDBusVariant &result);
-
-private:
-   // just wait (called by *AndWait methods)
-   void justWait(int time);
-   
-   bool m_completed;
-   bool m_dismissed;
-   QVariant m_result;
-   QDBusInterface m_interface;
-   QEventLoop m_loop;
-};
-
-#endif
diff --git a/daemon/tests/tempblockingcollection.cpp \
b/daemon/tests/tempblockingcollection.cpp deleted file mode 100644
index 8169aaa..0000000
--- a/daemon/tests/tempblockingcollection.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingcollection.h"
-#include "tempblockingitem.h"
-#include "tempblockingjobs.h"
-
-#include <secrettool.h>
-
-TempBlockingCollection::TempBlockingCollection(const QString &id, \
                BackendCollectionManager *parent)
- : BackendCollection(parent)
-{
-   m_id = id;
-   QDateTime now = QDateTime::currentDateTime();
-   m_created = now;
-   m_modified = now;
-}
-
-TempBlockingCollection::~TempBlockingCollection()
-{
-}
-
-QString TempBlockingCollection::id() const
-{
-   return m_id;
-}
-
-BackendReturn<QString> TempBlockingCollection::label() const
-{
-   return m_label;
-}
-
-BackendReturn<void> TempBlockingCollection::setLabel(const QString &label)
-{
-   m_label = label;
-   emit collectionChanged(this);
-   return BackendReturn<void>();
-}
-
-QDateTime TempBlockingCollection::created() const
-{
-   return m_created;
-}
-
-QDateTime TempBlockingCollection::modified() const
-{
-   return m_modified;
-}
-
-bool TempBlockingCollection::isLocked() const
-{
-   return false;
-}
-
-BackendReturn<QList<BackendItem*> > TempBlockingCollection::items() const
-{
-   return m_items;
-}
-
-BackendReturn<QList<BackendItem*> > TempBlockingCollection::searchItems(
-   const QMap<QString, QString> &attributes) const
-{
-   TempBlockingItem *titem;
-   QList<BackendItem*> foundItems;
-   Q_FOREACH(BackendItem *item, m_items) {
-      titem = qobject_cast<TempBlockingItem*>(item);
-      if (titem && titem->matches(attributes)) {
-         foundItems.append(item);
-      }
-   }
-   return foundItems;
-}
-
-UnlockCollectionJob *TempBlockingCollection::createUnlockJob()
-{
-   return new TempBlockingUnlockCollectionJob(this);
-}
-
-LockCollectionJob *TempBlockingCollection::createLockJob()
-{
-   return new TempBlockingLockCollectionJob(this);
-}
-
-DeleteCollectionJob *TempBlockingCollection::createDeleteJob()
-{
-   TempBlockingDeleteCollectionJob *job = new TempBlockingDeleteCollectionJob(this);
-   connect(job, SIGNAL(result(QueuedJob*)),
-                SLOT(deleteCollectionJobResult(QueuedJob*)));
-   return job;
-}
-
-CreateItemJob *TempBlockingCollection::createCreateItemJob(const QString &label,
-                                                           const QMap<QString, \
                QString> &attributes,
-                                                           const QCA::SecureArray \
                &secret,
-                                                           bool locked, bool \
                replace)
-{
-   return new TempBlockingCreateItemJob(label, attributes, secret, locked, replace, \
                this);
-}
-
-ChangeAuthenticationCollectionJob \
                *TempBlockingCollection::createChangeAuthenticationJob()
-{
-   return new TempBlockingChangeAuthenticationCollectionJob(this);
-}
-
-BackendReturn<BackendItem*> TempBlockingCollection::createItem(const QString &label,
-                                                               const QMap<QString, \
                QString> &attributes,
-                                                               const \
                QCA::SecureArray &secret,
-                                                               bool locked, bool \
                replace)
-{
-   Q_UNUSED(locked);
-
-   TempBlockingItem *item = 0;
-   bool replacing = false;
-
-   // check for duplicates
-   BackendReturn<QList<BackendItem*> > foundItems = searchItems(attributes);
-   if (!foundItems.isError() && foundItems.value().size() > 0) {
-      QList<BackendItem*> oldlist = foundItems.value();
-      Q_FOREACH(BackendItem* olditem, oldlist) {
-         if (olditem->attributes().value() == attributes) {
-            if (replace) {
-               // replacing an existing item
-               item = qobject_cast<TempBlockingItem*>(olditem);
-               replacing = true;
-            } else {
-               // item existing but should not be replaced
-               return BackendReturn<BackendItem*>(0, ErrorAlreadyExists);
-            }
-            break;
-         }
-      }
-   }
-
-   if (!item) {
-      item = new TempBlockingItem(createId(), this);
-   }
-   item->blockSignals(true);
-   item->setLabel(label);
-   item->setAttributes(attributes);
-   item->setSecret(secret);
-   item->blockSignals(false);
-
-   if (replacing) {
-      emit itemChanged(item);
-   } else {
-      m_items.append(item);
-      // new item, signals need to be wired
-      connect(item, SIGNAL(itemDeleted(BackendItem*)), \
                SLOT(slotItemDeleted(BackendItem*)));
-      connect(item, SIGNAL(itemChanged(BackendItem*)), \
                SIGNAL(itemChanged(BackendItem*)));
-      emit itemCreated(item);
-   }
-
-   return item;
-}
-
-void TempBlockingCollection::slotItemDeleted(BackendItem *item)
-{
-   m_items.removeAll(item);
-   emit itemDeleted(item);
-}
-
-void TempBlockingCollection::deleteCollectionJobResult(QueuedJob *job)
-{
-   TempBlockingDeleteCollectionJob * dcj = \
                qobject_cast<TempBlockingDeleteCollectionJob*>(job);
-   Q_ASSERT(dcj);
-   if (!dcj->result()) {
-      return;
-   }
-   emit collectionDeleted(this);
-}
-
-#include "tempblockingcollection.moc"
diff --git a/daemon/tests/tempblockingcollection.h \
b/daemon/tests/tempblockingcollection.h deleted file mode 100644
index 7a71c2b..0000000
--- a/daemon/tests/tempblockingcollection.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGCOLLECTION_H
-#define TEMPBLOCKINGCOLLECTION_H
-
-#include "backend/backendcollection.h"
-
-// implement a temporary collection that blocks every call.
-class TempBlockingCollection : public BackendCollection
-{
-   Q_OBJECT
-
-public:
-   TempBlockingCollection(const QString &id, BackendCollectionManager *parent);
-   virtual ~TempBlockingCollection();
-   virtual QString id() const;
-   virtual BackendReturn<QString> label() const;
-   virtual BackendReturn<void> setLabel(const QString &label);
-   virtual QDateTime created() const;
-   virtual QDateTime modified() const;
-   virtual bool isLocked() const;
-   virtual BackendReturn<QList<BackendItem*> > items() const;
-   virtual BackendReturn<QList<BackendItem*> > searchItems(const QMap<QString, \
                QString> &attributes) const;
-   virtual UnlockCollectionJob *createUnlockJob();
-   virtual LockCollectionJob *createLockJob();
-   virtual DeleteCollectionJob *createDeleteJob();
-   virtual CreateItemJob *createCreateItemJob(const QString &label,
-                                              const QMap<QString, QString> \
                &attributes,
-                                              const QCA::SecureArray &secret, bool \
                locked,
-                                              bool replace);
-   virtual ChangeAuthenticationCollectionJob *createChangeAuthenticationJob();
-
-protected:
-   BackendReturn<BackendItem*> createItem(const QString &label,
-                                          const QMap<QString, QString> &attributes,
-                                          const QCA::SecureArray &secret, bool \
                locked,
-                                          bool replace);
-
-private Q_SLOTS:
-   void slotItemDeleted(BackendItem *item);
-   void deleteCollectionJobResult(QueuedJob *job);
-
-private:
-   friend class TempBlockingCreateItemJob;
-   
-   QString m_id;
-   QString m_label;
-   QDateTime m_created;
-   QDateTime m_modified;
-
-   QList<BackendItem*> m_items;
-};
-
-#endif
diff --git a/daemon/tests/tempblockingcollectionmanager.cpp \
b/daemon/tests/tempblockingcollectionmanager.cpp deleted file mode 100644
index 3c57fad..0000000
--- a/daemon/tests/tempblockingcollectionmanager.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingcollectionmanager.h"
-#include "tempblockingcollection.h"
-#include "tempblockingjobs.h"
-
-#include <secrettool.h>
-
-TempBlockingCollectionManager::TempBlockingCollectionManager(QObject *parent)
- : BackendCollectionManager(parent)
-{
-}
-
-TempBlockingCollectionManager::~TempBlockingCollectionManager()
-{
-}
-
-CreateCollectionJob *TempBlockingCollectionManager::createCreateCollectionJob(const \
                QString &label,
-                                                                              bool \
                locked)
-{
-   TempBlockingCreateCollectionJob *job = new TempBlockingCreateCollectionJob(label,
-                                                                              \
                locked,
-                                                                              this);
-   connect(job, SIGNAL(result(QueuedJob*)),
-                SLOT(createCollectionJobResult(QueuedJob*)));
-   return job;
-}
-
-void TempBlockingCollectionManager::createCollectionJobResult(QueuedJob *job)
-{
-   CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(job);
-   Q_ASSERT(ccj);
-   
-   if (!ccj->collection()) {
-      return;
-   }
-   
-   // connect signals
-   connect(ccj->collection(), SIGNAL(collectionDeleted(BackendCollection*)),
-                              SIGNAL(collectionDeleted(BackendCollection*)));
-   emit collectionCreated(ccj->collection());
-}
-
-#include "tempblockingcollectionmanager.moc"
diff --git a/daemon/tests/tempblockingcollectionmanager.h \
b/daemon/tests/tempblockingcollectionmanager.h deleted file mode 100644
index 4272d29..0000000
--- a/daemon/tests/tempblockingcollectionmanager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGCOLLECTIONMANAGER_H
-#define TEMPBLOCKINGCOLLECTIONMANAGER_H
-
-#include "backend/backendcollectionmanager.h"
-
-class TempBlockingCollection;
-
-// implement a temporary collection manager that blocks every call.
-class TempBlockingCollectionManager : public BackendCollectionManager
-{
-   Q_OBJECT
-
-public:
-   friend class TempBlockingCollection;
-
-public:
-   TempBlockingCollectionManager(QObject *parent = 0);
-   virtual ~TempBlockingCollectionManager();
-   virtual CreateCollectionJob *createCreateCollectionJob(const QString &label,
-                                                          bool locked);
-                                                          
-private Q_SLOTS:
-   void createCollectionJobResult(QueuedJob *job);
-};
-
-#endif
diff --git a/daemon/tests/tempblockingitem.cpp b/daemon/tests/tempblockingitem.cpp
deleted file mode 100644
index b819bd3..0000000
--- a/daemon/tests/tempblockingitem.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingitem.h"
-#include "tempblockingcollection.h"
-#include "tempblockingjobs.h"
-
-TempBlockingItem::TempBlockingItem(const QString &id, TempBlockingCollection \
                *parent)
- : BackendItem(parent), m_id(id)
-{
-   QDateTime now = QDateTime::currentDateTime();
-   m_created = now;
-   m_modified = now;
-}
-
-TempBlockingItem::~TempBlockingItem()
-{
-}
-
-QString TempBlockingItem::id() const
-{
-   return m_id;
-}
-
-BackendReturn<QString> TempBlockingItem::label() const
-{
-   return m_label;
-}
-
-BackendReturn<void> TempBlockingItem::setLabel(const QString &label)
-{
-   m_label = label;
-   markAsModified();
-   return BackendReturn<void>();
-}
-
-BackendReturn<QCA::SecureArray> TempBlockingItem::secret() const
-{
-   return m_secret;
-}
-
-BackendReturn<void> TempBlockingItem::setSecret(const QCA::SecureArray &secret)
-{
-   m_secret = secret;
-   markAsModified();
-   return BackendReturn<void>();
-}
-
-BackendReturn<QMap<QString, QString> > TempBlockingItem::attributes() const
-{
-   return m_attributes;
-}
-
-BackendReturn<void> TempBlockingItem::setAttributes(const QMap<QString, QString> \
                &attributes)
-{
-   m_attributes = attributes;
-   markAsModified();
-   return BackendReturn<void>();
-}
-
-QDateTime TempBlockingItem::created() const
-{
-   return m_created;
-}
-
-QDateTime TempBlockingItem::modified() const
-{
-   return m_modified;
-}
-
-bool TempBlockingItem::isLocked() const
-{
-   return false;
-}
-
-UnlockItemJob *TempBlockingItem::createUnlockJob()
-{
-   return new TempBlockingUnlockItemJob(this);
-}
-
-LockItemJob *TempBlockingItem::createLockJob()
-{
-   return new TempBlockingLockItemJob(this);
-}
-
-DeleteItemJob *TempBlockingItem::createDeleteJob()
-{
-   TempBlockingDeleteItemJob *job = new TempBlockingDeleteItemJob(this);
-   connect(job, SIGNAL(result(QueuedJob*)), SLOT(deleteItemJobResult(QueuedJob*)));
-   return job;
-}
-
-ChangeAuthenticationItemJob *TempBlockingItem::createChangeAuthenticationJob()
-{
-   return new TempBlockingChangeAuthenticationItemJob(this);
-}
-
-bool TempBlockingItem::matches(const QMap<QString, QString> &attributes)
-{
-   QMap<QString, QString>::const_iterator it = attributes.constBegin();
-   QMap<QString, QString>::const_iterator end = attributes.constEnd();
-   for ( ; it != end; ++it) {
-      if (!m_attributes.contains(it.key()) ||
-          m_attributes.value(it.key()) != it.value()) {
-         return false;
-      }
-   }
-   
-   return true;
-}
-
-void TempBlockingItem::deleteItemJobResult(QueuedJob *job)
-{
-   TempBlockingDeleteItemJob *dij = qobject_cast<TempBlockingDeleteItemJob*>(job);
-   Q_ASSERT(dij);
-   if (!dij->result()) {
-      return;
-   }
-   emit itemDeleted(this);
-}
-
-void TempBlockingItem::markAsModified()
-{
-   m_modified = QDateTime::currentDateTime();
-   emit itemChanged(this);
-}
-
-#include "tempblockingitem.moc"
diff --git a/daemon/tests/tempblockingitem.h b/daemon/tests/tempblockingitem.h
deleted file mode 100644
index 1b16a0c..0000000
--- a/daemon/tests/tempblockingitem.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGITEM_H
-#define TEMPBLOCKINGITEM_H
-
-#include "backend/backenditem.h"
-
-class TempBlockingCollection;
-
-// temporary item that blocks every call
-class TempBlockingItem : public BackendItem
-{
-   Q_OBJECT
-
-public:
-   friend class TempBlockingCollection;
-
-   TempBlockingItem(const QString &id, TempBlockingCollection *parent);
-   ~TempBlockingItem();
-   virtual QString id() const;
-   virtual BackendReturn<QString> label() const;
-   virtual BackendReturn<void> setLabel(const QString &label);
-   virtual BackendReturn<QCA::SecureArray> secret() const;
-   virtual BackendReturn<void> setSecret(const QCA::SecureArray &secret);
-   virtual BackendReturn<QMap<QString, QString> > attributes() const;
-   virtual BackendReturn<void> setAttributes(const QMap<QString, QString> \
                &attributes);
-   virtual QDateTime created() const;
-   virtual QDateTime modified() const;
-   virtual bool isLocked() const;
-   virtual UnlockItemJob *createUnlockJob();
-   virtual LockItemJob *createLockJob();
-   virtual DeleteItemJob *createDeleteJob();
-   virtual ChangeAuthenticationItemJob *createChangeAuthenticationJob();
-   bool matches(const QMap<QString, QString> &attributes);
-   
-private Q_SLOTS:
-   void deleteItemJobResult(QueuedJob *job);
-   
-private:
-   void markAsModified();
-   
-   QString m_id;
-   QString m_label;
-   QDateTime m_created;
-   QDateTime m_modified;
-   QMap<QString, QString> m_attributes;
-   
-   QCA::SecureArray m_secret;
-};
-
-#endif
diff --git a/daemon/tests/tempblockingjobs.cpp b/daemon/tests/tempblockingjobs.cpp
deleted file mode 100644
index 47382e2..0000000
--- a/daemon/tests/tempblockingjobs.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tempblockingjobs.h"
-
-#include <secrettool.h>
-
-#include <QtCore/QTimer>
-
-TempBlockingCreateCollectionJob::TempBlockingCreateCollectionJob(const QString \
                &label, bool locked,
-                                                                 \
                TempBlockingCollectionManager *manager)
- : CreateCollectionJob(label, locked, manager)
-{
-}
-
-void TempBlockingCreateCollectionJob::perform()
-{
-   TempBlockingCollection *coll = new TempBlockingCollection(createId(), manager());
-   coll->setLabel(label());
-   
-   setCollection(coll);
-   emitResult();
-}
-
-TempBlockingUnlockCollectionJob::TempBlockingUnlockCollectionJob(BackendCollection* \
                coll)
- : UnlockCollectionJob(coll)
-{
-}
-
-void TempBlockingUnlockCollectionJob::perform()
-{
-   setResult(true);
-   emitResult();
-}
-
-TempBlockingLockCollectionJob::TempBlockingLockCollectionJob(BackendCollection* \
                coll)
- : LockCollectionJob(coll)
-{
-}
-
-void TempBlockingLockCollectionJob::perform()
-{
-   setError(ErrorNotSupported);
-   setResult(false);
-   emitResult();
-}
-
-TempBlockingDeleteCollectionJob::TempBlockingDeleteCollectionJob(BackendCollection* \
                coll)
- : DeleteCollectionJob(coll)
-{
-}
-
-void TempBlockingDeleteCollectionJob::perform()
-{
-   setResult(true);
-   collection()->deleteLater();
-   emitResult();
-}
-
-TempBlockingChangeAuthenticationCollectionJob::TempBlockingChangeAuthenticationCollectionJob(BackendCollection* \
                coll)
- : ChangeAuthenticationCollectionJob(coll)
-{
-}
-
-void TempBlockingChangeAuthenticationCollectionJob::perform()
-{
-   setError(ErrorNotSupported);
-   setResult(false);
-   emitResult();
-}
-
-TempBlockingCreateItemJob::TempBlockingCreateItemJob(const QString& label,
-                                                     const QMap< QString, QString >& \
                attributes,
-                                                     const QCA::SecureArray& secret, \
                bool locked,
-                                                     bool replace,
-                                                     TempBlockingCollection* \
                collection)
- : CreateItemJob(label, attributes, secret, locked, replace, collection),
-   m_tempColl(collection)
-{
-}
-
-void TempBlockingCreateItemJob::perform()
-{
-   BackendReturn<BackendItem*> rc = m_tempColl->createItem(label(), attributes(),
-                                                           secret(), locked(),
-                                                           replace());
-                                                           
-   if (rc.isError()) {
-      setError(rc.error(), rc.errorMessage());
-   } else {
-      setItem(rc.value());
-   }
-   emitResult();
-}
-
-TempBlockingUnlockItemJob::TempBlockingUnlockItemJob(BackendItem* item)
- : UnlockItemJob(item)
-{
-}
-
-void TempBlockingUnlockItemJob::perform()
-{
-   setResult(true);
-   emitResult();
-}
-
-TempBlockingLockItemJob::TempBlockingLockItemJob(BackendItem* item)
- : LockItemJob(item)
-{
-}
-
-void TempBlockingLockItemJob::perform()
-{
-   setError(ErrorNotSupported);
-   setResult(false);
-   emitResult();
-}
-
-TempBlockingDeleteItemJob::TempBlockingDeleteItemJob(BackendItem* item)
- : DeleteItemJob(item)
-{
-}
-
-void TempBlockingDeleteItemJob::perform()
-{
-   setResult(true);
-   item()->deleteLater();
-   emitResult();
-}
-
-TempBlockingChangeAuthenticationItemJob::TempBlockingChangeAuthenticationItemJob(BackendItem* \
                item)
- : ChangeAuthenticationItemJob(item)
-{
-}
-
-void TempBlockingChangeAuthenticationItemJob::perform()
-{
-   setError(ErrorNotSupported);
-   setResult(false);
-   emitResult();
-}
-
-#include "tempblockingjobs.moc"
diff --git a/daemon/tests/tempblockingjobs.h b/daemon/tests/tempblockingjobs.h
deleted file mode 100644
index bf04014..0000000
--- a/daemon/tests/tempblockingjobs.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2010, Michael Leupold <lemma@confuego.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License or (at your option) 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 14 of version 3 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEMPBLOCKINGJOBS_H
-#define TEMPBLOCKINGJOBS_H
-
-#include "tempblockingcollectionmanager.h"
-#include "tempblockingcollection.h"
-#include "tempblockingitem.h"
-
-#include <QtCore/QTimer>
-
-class TempBlockingCreateCollectionJob : public CreateCollectionJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingCreateCollectionJob(const QString &label, bool locked,
-                                   TempBlockingCollectionManager *manager);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-   
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingUnlockCollectionJob : public UnlockCollectionJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingUnlockCollectionJob(BackendCollection *coll);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-   
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingDeleteCollectionJob : public DeleteCollectionJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingDeleteCollectionJob(BackendCollection *coll);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingLockCollectionJob : public LockCollectionJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingLockCollectionJob(BackendCollection *coll);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingChangeAuthenticationCollectionJob : public \
                ChangeAuthenticationCollectionJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingChangeAuthenticationCollectionJob(BackendCollection *coll);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingCreateItemJob : public CreateItemJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingCreateItemJob(const QString &label, const QMap<QString, QString> \
                &attributes,
-                             const QCA::SecureArray &secret, bool locked, bool \
                replace,
-                             TempBlockingCollection *collection);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-   
-private:
-   TempBlockingCollection* m_tempColl;
-};
-
-class TempBlockingUnlockItemJob : public UnlockItemJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingUnlockItemJob(BackendItem *item);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingLockItemJob : public LockItemJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingLockItemJob(BackendItem *item);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingDeleteItemJob : public DeleteItemJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingDeleteItemJob(BackendItem *item);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-class TempBlockingChangeAuthenticationItemJob : public ChangeAuthenticationItemJob
-{
-   Q_OBJECT
-   
-public:
-   TempBlockingChangeAuthenticationItemJob(BackendItem *item);
-   virtual bool isImmediate() const { return false; }
-   virtual void exec() { Q_ASSERT(false); }
-   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
-
-private Q_SLOTS:
-   void perform();
-};
-
-#endif
diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt
new file mode 100644
index 0000000..e7329dc
--- /dev/null
+++ b/frontend/CMakeLists.txt
@@ -0,0 +1,22 @@
+INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR})
+ADD_SUBDIRECTORY (tests)
+
+SET (ksecretservice_frontend_SRCS
+   # fd.o Secret Storage daemon
+   secret/item.cpp
+   secret/collection.cpp
+   secret/prompt.cpp
+   secret/secret.cpp
+   secret/service.cpp
+   secret/session.cpp
+   # Daemon DBus adaptors
+   secret/adaptors/dbustypes.cpp
+   secret/adaptors/collectionadaptor.cpp
+   secret/adaptors/itemadaptor.cpp
+   secret/adaptors/promptadaptor.cpp
+   secret/adaptors/serviceadaptor.cpp
+   secret/adaptors/sessionadaptor.cpp
+)
+
+KDE4_ADD_LIBRARY (ksecretservicefrontend STATIC ${ksecretservice_frontend_SRCS})
+TARGET_LINK_LIBRARIES (ksecretservicefrontend ${KDE4_KDECORE_LIBS} \
                ${QCA2_LIBRARIES})
diff --git a/frontend/secret/adaptors/collectionadaptor.cpp \
b/frontend/secret/adaptors/collectionadaptor.cpp new file mode 100644
index 0000000..35b431a
--- /dev/null
+++ b/frontend/secret/adaptors/collectionadaptor.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "collectionadaptor.h"
+#include "../collection.h"
+
+namespace orgFreedesktopSecret
+{
+
+CollectionAdaptor::CollectionAdaptor(Collection *collection)
+ : QDBusAbstractAdaptor(collection), m_collection(collection)
+{
+   Q_ASSERT(collection);
+
+   connect(m_collection, SIGNAL(itemCreated(const QDBusObjectPath &)),
+                         SIGNAL(ItemCreated(const QDBusObjectPath &)));
+   connect(m_collection, SIGNAL(itemDeleted(const QDBusObjectPath &)),
+                         SIGNAL(ItemDeleted(const QDBusObjectPath &)));
+   connect(m_collection, SIGNAL(itemChanged(const QDBusObjectPath &)),
+                         SIGNAL(ItemChanged(const QDBusObjectPath &)));
+}
+
+const QList<QDBusObjectPath> &CollectionAdaptor::items() const
+{
+   return m_collection->items();
+}
+
+void CollectionAdaptor::setLabel(const QString &label)
+{
+   m_collection->setLabel(label);
+}
+
+QString CollectionAdaptor::label() const
+{
+   return m_collection->label();
+}
+
+bool CollectionAdaptor::locked() const
+{
+   return m_collection->locked();
+}
+
+qulonglong CollectionAdaptor::created() const
+{
+   return m_collection->created();
+}
+
+qulonglong CollectionAdaptor::modified() const
+{
+   return m_collection->modified();
+}
+
+QDBusObjectPath CollectionAdaptor::Delete()
+{
+   return m_collection->deleteCollection();
+}
+
+QList<QDBusObjectPath> CollectionAdaptor::SearchItems(const StringStringMap \
&attributes) +{
+   return m_collection->searchItems(attributes);
+}
+
+QDBusObjectPath CollectionAdaptor::CreateItem(const QMap<QString, QVariant> \
&properties, +                                              const Secret &secret, \
bool replace, +                                              QDBusObjectPath &prompt)
+{
+   return m_collection->createItem(properties, secret, replace, prompt);
+}
+
+}
+
+#include "collectionadaptor.moc"
diff --git a/frontend/secret/adaptors/collectionadaptor.h \
b/frontend/secret/adaptors/collectionadaptor.h new file mode 100644
index 0000000..cb7ad00
--- /dev/null
+++ b/frontend/secret/adaptors/collectionadaptor.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_COLLECTIONADAPTOR_H
+
+#include "dbustypes.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+
+class Collection;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Collection objects.
+ */
+class CollectionAdaptor : public QDBusAbstractAdaptor
+{
+   Q_OBJECT
+   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Collection")
+   Q_PROPERTY(QList<QDBusObjectPath> Items READ items)
+   Q_PROPERTY(QString Label READ label WRITE setLabel)
+   Q_PROPERTY(bool Locked READ locked)
+   Q_PROPERTY(qulonglong Created READ created)
+   Q_PROPERTY(qulonglong Modified READ modified)
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param collection collection object to attach the adaptor to
+    */
+   CollectionAdaptor(Collection *collection);
+
+   const QList<QDBusObjectPath> &items() const;
+
+   void setLabel(const QString &label);
+   
+   QString label() const;
+
+   bool locked() const;
+
+   qulonglong created() const;
+
+   qulonglong modified() const;
+
+public Q_SLOTS:
+   QDBusObjectPath Delete();
+
+   QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes);
+
+   QDBusObjectPath CreateItem(const QMap<QString, QVariant> &properties,
+                              const Secret &secret, bool replace,
+                              QDBusObjectPath &prompt);
+
+Q_SIGNALS:
+   void ItemCreated(const QDBusObjectPath &item);
+
+   void ItemDeleted(const QDBusObjectPath &item);
+
+   void ItemChanged(const QDBusObjectPath &item);
+
+private:
+   Collection *m_collection;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/dbustypes.cpp \
b/frontend/secret/adaptors/dbustypes.cpp new file mode 100644
index 0000000..6d5362f
--- /dev/null
+++ b/frontend/secret/adaptors/dbustypes.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dbustypes.h"
+
+#include <QtDBus/QDBusMetaType>
+
+void registerDBusTypes()
+{
+   // register meta-types needed for this adaptor
+   qRegisterMetaType<Secret>();
+   qDBusRegisterMetaType<Secret>();
+   qRegisterMetaType<StringStringMap>();
+   qDBusRegisterMetaType<StringStringMap>();
+   qDBusRegisterMetaType<ObjectPathSecretMap>();
+}
diff --git a/frontend/secret/adaptors/dbustypes.h \
b/frontend/secret/adaptors/dbustypes.h new file mode 100644
index 0000000..12425dc
--- /dev/null
+++ b/frontend/secret/adaptors/dbustypes.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
+#define ORG_FREEDESKTOP_SECRET_DBUSTYPES_H
+
+#include "../secret.h"
+
+#include <QtDBus/QDBusObjectPath>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+
+/**
+ * Register the types needed for the fd.o Secrets D-Bus interface.
+ */
+void registerDBusTypes();
+
+typedef QMap<QString, QString> StringStringMap;
+typedef QMap<QDBusObjectPath, Secret> ObjectPathSecretMap;
+
+Q_DECLARE_METATYPE(StringStringMap);
+Q_DECLARE_METATYPE(ObjectPathSecretMap);
+
+#endif
diff --git a/frontend/secret/adaptors/itemadaptor.cpp \
b/frontend/secret/adaptors/itemadaptor.cpp new file mode 100644
index 0000000..04f68ea
--- /dev/null
+++ b/frontend/secret/adaptors/itemadaptor.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "itemadaptor.h"
+#include "../item.h"
+#include "../secret.h"
+
+namespace orgFreedesktopSecret
+{
+
+ItemAdaptor::ItemAdaptor(Item *item)
+ : QDBusAbstractAdaptor(item), m_item(item)
+{
+   Q_ASSERT(item);
+}
+
+bool ItemAdaptor::locked() const
+{
+   return m_item->locked();
+}
+
+void ItemAdaptor::setAttributes(const StringStringMap &attributes)
+{
+   m_item->setAttributes(attributes);
+}
+
+StringStringMap ItemAdaptor::attributes() const
+{
+   return m_item->attributes();
+}
+
+void ItemAdaptor::setLabel(const QString &label)
+{
+   m_item->setLabel(label);
+}
+
+QString ItemAdaptor::label() const
+{
+   return m_item->label();
+}
+
+qulonglong ItemAdaptor::created() const
+{
+   return m_item->created();
+}
+
+qulonglong ItemAdaptor::modified() const
+{
+   return m_item->modified();
+}
+
+QDBusObjectPath ItemAdaptor::Delete()
+{
+   return m_item->deleteItem();
+}
+
+Secret ItemAdaptor::GetSecret(const QDBusObjectPath &session)
+{
+   return m_item->getSecret(session);
+}
+
+void ItemAdaptor::SetSecret(const Secret &secret)
+{
+   m_item->setSecret(secret);
+}
+
+}
+
+#include "itemadaptor.moc"
diff --git a/frontend/secret/adaptors/itemadaptor.h \
b/frontend/secret/adaptors/itemadaptor.h new file mode 100644
index 0000000..2037c17
--- /dev/null
+++ b/frontend/secret/adaptors/itemadaptor.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_ITEMADAPTOR_H
+
+#include "dbustypes.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtCore/QString>
+#include <QtCore/QMap>
+
+class Item;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Item objects.
+ */
+class ItemAdaptor : public QDBusAbstractAdaptor
+{
+   Q_OBJECT
+   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Item")
+   Q_PROPERTY(bool Locked READ locked)
+   Q_PROPERTY(StringStringMap Attributes READ attributes WRITE setAttributes)
+   Q_PROPERTY(QString Label READ label WRITE setLabel)
+   Q_PROPERTY(qulonglong Created READ created)
+   Q_PROPERTY(qulonglong Modified READ modified)
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param item item object to attach the adaptor to
+    */
+   ItemAdaptor(Item *item);
+
+   bool locked() const;
+
+   void setAttributes(const StringStringMap &attributes);
+   
+   StringStringMap attributes() const;
+
+   void setLabel(const QString &label);
+
+   QString label() const;
+
+   qulonglong created() const;
+
+   qulonglong modified() const;
+
+public Q_SLOTS:
+   QDBusObjectPath Delete();
+
+   Secret GetSecret(const QDBusObjectPath &session);
+
+   void SetSecret(const Secret &secret);
+
+private:
+   Item *m_item;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/promptadaptor.cpp \
b/frontend/secret/adaptors/promptadaptor.cpp new file mode 100644
index 0000000..44ddda3
--- /dev/null
+++ b/frontend/secret/adaptors/promptadaptor.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "promptadaptor.h"
+#include "../prompt.h"
+
+namespace orgFreedesktopSecret
+{
+
+PromptAdaptor::PromptAdaptor(PromptBase *prompt)
+ : QDBusAbstractAdaptor(prompt), m_prompt(prompt)
+{
+   Q_ASSERT(prompt);
+
+   connect(prompt, SIGNAL(completed(bool, QVariant)), SLOT(slotCompleted(bool, \
QVariant))); +}
+
+void PromptAdaptor::Prompt(const QString &windowId)
+{
+   m_prompt->prompt(windowId);
+}
+
+void PromptAdaptor::Dismiss()
+{
+   m_prompt->dismiss();
+}
+
+void PromptAdaptor::slotCompleted(bool dismissed, const QVariant &result)
+{
+   emit Completed(dismissed, QDBusVariant(result));
+}
+
+}
+
+#include "promptadaptor.moc"
diff --git a/frontend/secret/adaptors/promptadaptor.h \
b/frontend/secret/adaptors/promptadaptor.h new file mode 100644
index 0000000..8338eca
--- /dev/null
+++ b/frontend/secret/adaptors/promptadaptor.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_PROMPTADAPTOR_H
+
+#include "../prompt.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Prompt objects.
+ */
+class PromptAdaptor : public QDBusAbstractAdaptor
+{
+   Q_OBJECT
+   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Prompt")
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param prompt prompt object to attach the adaptor to
+    */
+   PromptAdaptor(PromptBase *prompt);
+
+public Q_SLOTS:
+   void Prompt(const QString &windowId);
+
+   void Dismiss();
+
+Q_SIGNALS:
+   void Completed(bool dismissed, QDBusVariant result);
+
+private Q_SLOTS:
+   void slotCompleted(bool dismissed, const QVariant &result);
+   
+private:
+   PromptBase *m_prompt;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/adaptors/serviceadaptor.cpp \
b/frontend/secret/adaptors/serviceadaptor.cpp new file mode 100644
index 0000000..276ba19
--- /dev/null
+++ b/frontend/secret/adaptors/serviceadaptor.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "serviceadaptor.h"
+#include "dbustypes.h"
+#include "../service.h"
+
+namespace orgFreedesktopSecret
+{
+
+ServiceAdaptor::ServiceAdaptor(Service *service)
+ : QDBusAbstractAdaptor(service), m_service(service)
+{
+   Q_ASSERT(service);
+
+   // register all types needed for the D-Bus interface
+   registerDBusTypes();
+
+   connect(service, SIGNAL(collectionCreated(const QDBusObjectPath&)),
+                    SIGNAL(CollectionCreated(const QDBusObjectPath&)));
+   connect(service, SIGNAL(collectionDeleted(const QDBusObjectPath&)),
+                    SIGNAL(CollectionDeleted(const QDBusObjectPath&)));
+   connect(service, SIGNAL(collectionChanged(const QDBusObjectPath&)),
+                    SIGNAL(CollectionChanged(const QDBusObjectPath&)));
+}
+
+const QList<QDBusObjectPath> &ServiceAdaptor::collections() const
+{
+   return m_service->collections();
+}
+
+QDBusVariant ServiceAdaptor::OpenSession(const QString &algorithm, const \
QDBusVariant &input, +                                         QDBusObjectPath \
&result) +{
+   return QDBusVariant(m_service->openSession(algorithm, input.variant(), result));
+}
+
+QDBusObjectPath ServiceAdaptor::CreateCollection(const QMap<QString, QVariant> \
&properties, +                                                 QDBusObjectPath \
&prompt) +{
+   return m_service->createCollection(properties, prompt);
+}
+
+QList<QDBusObjectPath> ServiceAdaptor::SearchItems(const StringStringMap \
&attributes, +                                                   \
QList<QDBusObjectPath> &locked) +{
+   return m_service->searchItems(attributes, locked);
+}
+
+QList<QDBusObjectPath> ServiceAdaptor::Unlock(const QList<QDBusObjectPath> &objects,
+                                              QDBusObjectPath &prompt)
+{
+   return m_service->unlock(objects, prompt);
+}
+
+QList<QDBusObjectPath> ServiceAdaptor::Lock(const QList<QDBusObjectPath> &objects,
+                                            QDBusObjectPath &prompt)
+{
+   return m_service->lock(objects, prompt);
+}
+
+ObjectPathSecretMap ServiceAdaptor::GetSecrets(const QList<QDBusObjectPath> &items,
+                                               const QDBusObjectPath &session)
+{
+   return m_service->getSecrets(items, session);
+}
+
+}
+
+#include "serviceadaptor.moc"
diff --git a/frontend/secret/adaptors/serviceadaptor.h \
b/frontend/secret/adaptors/serviceadaptor.h new file mode 100644
index 0000000..436a4bd
--- /dev/null
+++ b/frontend/secret/adaptors/serviceadaptor.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_SERVICEADAPTOR_H
+
+#include "dbustypes.h"
+#include "../secret.h"
+
+#include <QtDBus/QDBusAbstractAdaptor>
+#include <QtDBus/QDBusObjectPath>
+
+class Service;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Service objects.
+ */
+class ServiceAdaptor : public QDBusAbstractAdaptor
+{
+   Q_OBJECT
+   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Service")
+   Q_PROPERTY(QList<QDBusObjectPath> Collections READ collections)
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param service service object to attach the adaptor to
+    */
+   ServiceAdaptor(Service *service);
+
+   const QList<QDBusObjectPath> &collections() const;
+
+public Q_SLOTS:
+   QDBusVariant OpenSession(const QString &algorithm, const QDBusVariant &input,
+                            QDBusObjectPath &result);
+   
+   QDBusObjectPath CreateCollection(const QMap<QString, QVariant> &properties,
+                                    QDBusObjectPath &prompt);
+                                    
+   QList<QDBusObjectPath> SearchItems(const StringStringMap &attributes,
+                                      QList<QDBusObjectPath> &locked);
+                                      
+   QList<QDBusObjectPath> Unlock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +   
+   QList<QDBusObjectPath> Lock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+   ObjectPathSecretMap GetSecrets(const QList<QDBusObjectPath> &items,
+                                  const QDBusObjectPath &session);
+
+Q_SIGNALS:
+   void CollectionCreated(const QDBusObjectPath &collection);
+
+   void CollectionDeleted(const QDBusObjectPath &collection);
+
+   void CollectionChanged(const QDBusObjectPath &collection);
+
+private:
+   Service *m_service;
+};
+   
+}
+
+#endif
diff --git a/frontend/secret/adaptors/sessionadaptor.cpp \
b/frontend/secret/adaptors/sessionadaptor.cpp new file mode 100644
index 0000000..e2d1e53
--- /dev/null
+++ b/frontend/secret/adaptors/sessionadaptor.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sessionadaptor.h"
+#include "../session.h"
+
+namespace orgFreedesktopSecret
+{
+
+SessionAdaptor::SessionAdaptor(Session *session)
+ : QDBusAbstractAdaptor(session), m_session(session)
+{
+   Q_ASSERT(session);
+}
+
+void SessionAdaptor::Close()
+{
+   m_session->close();
+}
+
+}
+
+#include "sessionadaptor.moc"
diff --git a/frontend/secret/adaptors/sessionadaptor.h \
b/frontend/secret/adaptors/sessionadaptor.h new file mode 100644
index 0000000..0eb553c
--- /dev/null
+++ b/frontend/secret/adaptors/sessionadaptor.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
+#define ORG_FREEDESKTOP_SECRET_SESSIONADAPTOR_H
+
+#include <QtDBus/QDBusAbstractAdaptor>
+
+class Session;
+
+namespace orgFreedesktopSecret
+{
+
+/**
+ * D-Bus adaptor class for Session objects.
+ */
+class SessionAdaptor : public QDBusAbstractAdaptor
+{
+   Q_OBJECT
+   Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Secret.Session")
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param session session object to attach the adaptor to
+    */
+   SessionAdaptor(Session *session);
+
+public Q_SLOTS:
+   void Close();
+
+private:
+   Session *m_session;
+};
+
+}
+
+#endif
diff --git a/frontend/secret/collection.cpp b/frontend/secret/collection.cpp
new file mode 100644
index 0000000..e8834d2
--- /dev/null
+++ b/frontend/secret/collection.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "collection.h"
+#include "adaptors/collectionadaptor.h"
+#include "service.h"
+#include "item.h"
+#include "session.h"
+#include "prompt.h"
+
+#include <backend/backendcollection.h>
+#include <backend/backenditem.h>
+
+#include <QtDBus/QDBusConnection>
+
+#include <QtCore/QDebug>
+
+Collection::Collection(BackendCollection *collection, Service *service)
+ : QObject(service), m_service(service), m_collection(collection)
+{
+   Q_ASSERT(collection);
+   m_objectPath.setPath(service->objectPath().path() + "/collection/" + \
collection->id()); +
+   new orgFreedesktopSecret::CollectionAdaptor(this);
+   QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+
+   connect(collection, SIGNAL(itemCreated(BackendItem*)),
+                       SLOT(slotItemCreated(BackendItem*)));
+   connect(collection, SIGNAL(itemDeleted(BackendItem*)),
+                       SLOT(slotItemDeleted(BackendItem*)));
+   connect(collection, SIGNAL(itemChanged(BackendItem*)),
+                       SLOT(slotItemChanged(BackendItem*)));
+}
+
+const QDBusObjectPath &Collection::objectPath() const
+{
+   return m_objectPath;
+}
+
+const QList<QDBusObjectPath> &Collection::items() const
+{
+   return m_items;
+}
+
+void Collection::setLabel(const QString &label)
+{
+   BackendReturn<void> rc = m_collection->setLabel(label);
+   if (rc.isError()) {
+      // TODO: generate D-Bus error
+   }
+}
+
+QString Collection::label() const
+{
+   BackendReturn<QString> rc = m_collection->label();
+   if (rc.isError()) {
+      // TODO: generate D-Bus error
+   }
+   return rc.value();
+}
+
+bool Collection::locked() const
+{
+   return m_collection->isLocked();
+}
+
+qulonglong Collection::created() const
+{
+   return m_collection->created().toTime_t();
+}
+
+qulonglong Collection::modified() const
+{
+   return m_collection->modified().toTime_t();
+}
+
+QDBusObjectPath Collection::deleteCollection()
+{
+   DeleteCollectionJob *dcj = m_collection->createDeleteJob();
+   if (dcj->isImmediate()) {
+      dcj->exec();
+      return QDBusObjectPath("/");
+   } else {
+      SingleJobPrompt *p = new SingleJobPrompt(m_service, dcj, this);
+      return p->objectPath();
+   }
+}
+
+QList<QDBusObjectPath> Collection::searchItems(const QMap<QString, QString> \
&attributes) +{
+   QList<QDBusObjectPath> rc;
+   BackendReturn<QList<BackendItem*> > br = m_collection->searchItems(attributes);
+   if (br.isError()) {
+      // TODO: generate D-Bus error
+   }
+   else {
+      Q_FOREACH(BackendItem *item, br.value()) {
+         rc.append(QDBusObjectPath(m_objectPath.path() + "/" + item->id()));
+      }
+   }
+   return rc;
+}
+
+QDBusObjectPath Collection::createItem(const QMap<QString, QVariant> &properties,
+                                       const Secret &secret, bool replace,
+                                       QDBusObjectPath &prompt)
+{
+   // default label?
+   QString label;
+   QMap<QString, QString> attributes;
+   bool locked = false;
+
+   // get the session object
+   QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path()); +   \
Session *session; +   if (!(session = qobject_cast<Session*>(object))) {
+      // TODO: error, requires session
+   }
+   
+   if (properties.contains("Label")) {
+      label = properties["Label"].toString();
+   }
+   if (properties.contains("Locked")) {
+      locked = properties["Locked"].toBool();
+   }
+   if (properties.contains("Attributes")) {
+      attributes = qdbus_cast<StringStringMap>(properties["Attributes"].value<QDBusArgument>());
 +   }
+
+   // TODO: check the parameters before creating the prompt
+   bool ok;
+   QCA::SecureArray secretValue = session->decrypt(secret, ok);
+   if (!ok) {
+      // TODO: invalid session
+   }
+   CreateItemJob *cij = m_collection->createCreateItemJob(label, attributes, \
secretValue, +                                                          replace, \
locked); +   if (cij->isImmediate()) {
+      cij->exec();
+      if (cij->error() != NoError || !cij->item()) {
+         // TODO: error creating the item
+      }
+      
+      // the Item is already created inside slotItemCreated()
+      prompt.setPath("/");
+      QDBusObjectPath itemPath(m_objectPath.path() + "/" + cij->item()->id());
+      return itemPath;
+   } else {
+      SingleJobPrompt *p = new SingleJobPrompt(m_service, cij, this);
+      prompt = p->objectPath();
+      return QDBusObjectPath("/");
+   }
+}
+
+BackendCollection *Collection::backendCollection() const
+{
+   return m_collection;
+}
+
+void Collection::slotItemCreated(BackendItem *item)
+{
+   Q_ASSERT(item);
+   Item *itm = new Item(item, this);
+   m_items.append(itm->objectPath());
+   emit itemCreated(itm->objectPath());
+}
+
+void Collection::slotItemDeleted(BackendItem *item)
+{
+   Q_ASSERT(item);
+   QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
+   m_items.removeAll(itmPath);
+   emit itemDeleted(itmPath);
+}
+
+void Collection::slotItemChanged(BackendItem *item)
+{
+   Q_ASSERT(item);
+   QDBusObjectPath itmPath(m_objectPath.path() + "/" + item->id());
+   emit itemChanged(itmPath);
+}
+
+#include "collection.moc"
diff --git a/frontend/secret/collection.h b/frontend/secret/collection.h
new file mode 100644
index 0000000..f96b414
--- /dev/null
+++ b/frontend/secret/collection.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_COLLECTION_H
+#define DAEMON_COLLECTION_H
+
+#include "secret.h"
+
+#include <QtCore/QObject>
+#include <QtDBus/QDBusObjectPath>
+
+class BackendCollection;
+class BackendItem;
+
+class Service;
+class Item;
+   
+/**
+ * Represents a collection on the D-Bus implementing the \
org.freedesktop.Secret.Collection + * interface.
+ */
+class Collection : public QObject
+{
+   Q_OBJECT
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param collection Backend collection object
+    * @param service Parent service
+    */
+   Collection(BackendCollection *collection, Service *service);
+
+   /**
+    * Return the collection's path on the D-Bus.
+    *
+    * @return the Collection object's path
+    */
+   const QDBusObjectPath &objectPath() const;
+
+   /**
+    * Get the items stored inside this collection.
+    *
+    * @return a list of object paths of items inside the collection
+    */
+   const QList<QDBusObjectPath> &items() const;
+
+   /**
+    * Set the collection's label.
+    *
+    * @param label label to set for the collection
+    */
+   void setLabel(const QString &label);
+
+   /**
+    * Get the collection's label.
+    *
+    * @return the collection's label
+    */
+   QString label() const;
+
+   /**
+    * Check whether this collection is locked.
+    *
+    * @return true if the collection is locked, false if it is unlocked
+    */
+   bool locked() const;
+
+   /**
+    * Get the collection's creation time as a unix timestamp.
+    *
+    * @return collection's creation time
+    */
+   qulonglong created() const;
+
+   /**
+    * Get the collection's last modification time as a unix timestamp.
+    *
+    * @return collection's modification time
+    */
+   qulonglong modified() const;
+
+   /**
+    * Delete this collection.
+    *
+    * @return the object path of a Prompt object or special value "/" if the
+    *         collection was deleted without prompting
+    */
+   QDBusObjectPath deleteCollection();
+
+   /**
+    * Search items inside the collection.
+    *
+    * @param attributes search attributes to match items against
+    */
+   QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes);
+
+   /**
+    * Create a new item inside the collection.
+    *
+    * @param properties Properties for the new item
+    * @param secret Secret for the new item
+    * @param replace if true, an existing item with the same attributes will be \
replaced, +    *                if false and an item with the same attributes exists, \
no new item +    *                will be created
+    * @param prompt object path of a prompt object if prompting is necessary or "/" \
if +    *               the action could be completed without a prompt
+    * @return object path of the new item or "/" if prompting is necessary
+    */
+   QDBusObjectPath createItem(const QMap<QString, QVariant> &properties,
+                              const Secret &secret, bool replace, QDBusObjectPath \
&prompt); +                              
+   /**
+    * Get the backend collection linked to this object.
+    */
+   BackendCollection *backendCollection() const;
+
+Q_SIGNALS:
+   /**
+    * Signals the creation of a new item.
+    *
+    * @param item object path of the item that was created
+    */
+   void itemCreated(const QDBusObjectPath &item);
+
+   /**
+    * Signals the deletion of an item.
+    *
+    * @param item object path of the item that was deleted
+    */
+   void itemDeleted(const QDBusObjectPath &item);
+
+   /**
+    * Signals that an item inside the collection was changed.
+    *
+    * @param item object path of the item that was changed
+    */
+   void itemChanged(const QDBusObjectPath &item);
+
+private Q_SLOTS:
+   // handle itemCreated() calls from a backend collection
+   void slotItemCreated(BackendItem *item);
+   // handle itemDeleted() calls from a backend collection
+   void slotItemDeleted(BackendItem *item);
+   // handle itemChanged() calls from a backend collection
+   void slotItemChanged(BackendItem *item);
+   
+private:
+   Service *m_service; // parent service
+   BackendCollection *m_collection;
+   QDBusObjectPath m_objectPath;
+   QList<QDBusObjectPath> m_items; // cache for items' object paths
+};
+
+#endif
diff --git a/frontend/secret/item.cpp b/frontend/secret/item.cpp
new file mode 100644
index 0000000..1d09476
--- /dev/null
+++ b/frontend/secret/item.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "item.h"
+#include "collection.h"
+#include "adaptors/itemadaptor.h"
+#include "session.h"
+#include "secret.h"
+#include "prompt.h"
+
+#include <backend/backenditem.h>
+
+#include <QtDBus/QDBusConnection>
+
+Item::Item(BackendItem *item, Collection *collection)
+ : QObject(collection), m_item(item)
+{
+    Q_ASSERT(item);
+    m_objectPath.setPath(collection->objectPath().path() + "/" + item->id());
+
+    new orgFreedesktopSecret::ItemAdaptor(this);
+    QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+}
+
+const QDBusObjectPath &Item::objectPath() const
+{
+   return m_objectPath;
+}
+
+bool Item::locked() const
+{
+   return m_item->isLocked();
+}
+
+void Item::setAttributes(const QMap<QString, QString> &attributes)
+{
+   BackendReturn<void> rc = m_item->setAttributes(attributes);
+   if (rc.isError()) {
+      // TODO: set D-Bus error
+   }
+}
+
+QMap<QString, QString> Item::attributes() const
+{
+   BackendReturn<QMap<QString, QString> > rc = m_item->attributes();
+   if (rc.isError()) {
+      // TODO: set D-Bus error
+   }
+   return rc.value();
+}
+
+void Item::setLabel(const QString &label)
+{
+   BackendReturn<void> rc = m_item->setLabel(label);
+   if (rc.isError()) {
+      // TODO: set D-Bus error
+   }
+}
+
+QString Item::label() const
+{
+   BackendReturn<QString> rc = m_item->label();
+   if (rc.isError()) {
+      // TODO: set D-Bus error
+   }
+   return rc.value();
+}
+
+qulonglong Item::created() const
+{
+   return m_item->created().toTime_t();
+}
+
+qulonglong Item::modified() const
+{
+   return m_item->modified().toTime_t();
+}
+
+QDBusObjectPath Item::deleteItem()
+{
+   DeleteItemJob *dij = m_item->createDeleteJob();
+   if (dij->isImmediate()) {
+      dij->exec();
+      return QDBusObjectPath("/");
+   } else {
+      // FIXME: needs the service!
+      SingleJobPrompt *p = new SingleJobPrompt(0, dij, this);
+      return p->objectPath();
+   }
+}
+
+Secret Item::getSecret(const QDBusObjectPath &session)
+{
+   if (m_item->isLocked()) {
+      // TODO: error, requires unlocking
+      return Secret();
+   }
+   
+   QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(session.path()); +   Session \
*sessionObj; +   if (object && (sessionObj = qobject_cast<Session*>(object))) {
+      BackendReturn<QCA::SecureArray> br = m_item->secret();
+      if (br.isError()) {
+         // TODO: handle error
+         return Secret();
+      }
+      bool ok;
+      Secret secret = sessionObj->encrypt(br.value(), ok);
+      if (br.isError()) {
+         // TODO: error, invalid session
+         return Secret();
+      }
+      return secret;
+   } else {
+      // TODO: error, requires session
+      return Secret();
+   }
+}
+
+void Item::setSecret(const Secret &secret)
+{
+   if (m_item->isLocked()) {
+      // TODO: error, requires unlocking
+      return;
+   }
+   
+   QObject *object = \
QDBusConnection::sessionBus().objectRegisteredAt(secret.session().path()); +   \
Session *sessionObj; +   if (object && (sessionObj = qobject_cast<Session*>(object))) \
{ +      bool ok;
+      BackendReturn<QCA::SecureArray> br = sessionObj->decrypt(secret, ok);
+      if (!ok) {
+         // TODO: invalid session
+         return;
+      }
+      BackendReturn<void> rc = m_item->setSecret(br.value());
+      if (rc.isError()) {
+         // TODO: handle error
+         return;
+      }
+   }
+   
+   // TODO: error, invalid session
+   
+   return;
+}
+
+BackendItem *Item::backendItem() const
+{
+   return m_item;
+}
+
+#include "item.moc"
diff --git a/frontend/secret/item.h b/frontend/secret/item.h
new file mode 100644
index 0000000..b53df41
--- /dev/null
+++ b/frontend/secret/item.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_ITEM_H
+#define DAEMON_ITEM_H
+
+#include "secret.h"
+
+#include <QtCore/QObject>
+#include <QtDBus/QDBusContext>
+
+class BackendItem;
+class Collection;
+class Service;
+   
+/**
+ * Represents an item on the D-Bus implementing the org.freedesktop.Secret.Item
+ * interface.
+ */
+class Item : public QObject, protected QDBusContext
+{
+   Q_OBJECT
+
+public:
+   /**
+    * Constructor.
+    * 
+    * @param item Backend item object
+    * @param collection Parent collection
+    */
+   Item(BackendItem *item, Collection *collection);
+
+   /**
+    * Return the item's path on the D-Bus.
+    *
+    * @return the Item object's path
+    */
+   const QDBusObjectPath &objectPath() const;
+
+public: // called by D-Bus adaptors
+   
+   /**
+    * Check whether this item is locked.
+    *
+    * @return true if the item is locked, false if it is unlocked
+    */
+   bool locked() const;
+
+   /**
+    * Set the item's attributes.
+    *
+    * @param attributes the attributes to set for the item
+    */
+   void setAttributes(const QMap<QString, QString> &attributes);
+
+   /**
+    * Get the item's attributes.
+    *
+    * @return the attributes stored for this item
+    */
+   QMap<QString, QString> attributes() const;
+
+   /**
+    * Set the item's human-readable label.
+    *
+    * @param label label to assign to this item
+    */
+   void setLabel(const QString &label);
+
+   /**
+    * Get the human-readable label assigned to this item.
+    *
+    * @return the item assigned to this item
+    */
+   QString label() const;
+
+   /**
+    * Retrieve the item's time of creation as a unix timestamp.
+    *
+    * @return item's time of creation
+    */
+   qulonglong created() const;
+
+   /**
+    * Retrieve the item's last modification date as a unix timestamp.
+    *
+    * @return item's last time of modification
+    */
+   qulonglong modified() const;
+
+   /**
+    * Delete the item from the collection it's in.
+    *
+    * @return the object path of a prompt object for the operation or "/" if the
+    *         item was deleted without a prompt.
+    */
+   QDBusObjectPath deleteItem();
+
+   /**
+    * Get the secret stored withing the item.
+    *
+    * @param session Session to use for securing the D-Bus transport
+    * @return the (possibly encrypted) Secret structure
+    */
+   Secret getSecret(const QDBusObjectPath &session);
+
+   /**
+    * Set the secret stored within the item.
+    *
+    * @param secret Secret to store inside the item
+    */
+   void setSecret(const Secret &secret);
+
+public:
+   /**
+    * Get the backend item associated with this frontend item.
+    *
+    * @return the backend item belonging to this frontend item
+    * @remarks called by other frontend objects
+    */
+   BackendItem *backendItem() const;
+
+private:
+   BackendItem *m_item;
+   QDBusObjectPath m_objectPath;
+};
+
+#endif
diff --git a/frontend/secret/prompt.cpp b/frontend/secret/prompt.cpp
new file mode 100644
index 0000000..66c1b76
--- /dev/null
+++ b/frontend/secret/prompt.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "prompt.h"
+#include "service.h"
+#include "adaptors/promptadaptor.h"
+
+#include <backend/backendcollection.h>
+#include <backend/backenditem.h>
+#include <secrettool.h>
+
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusObjectPath>
+
+PromptBase::PromptBase(Service *service, QObject *parent)
+ : QObject(parent), m_serviceObjectPath(service->objectPath())
+{
+   Q_ASSERT(service);
+   m_objectPath.setPath(service->objectPath().path() + "/prompts/" + createId());
+
+   new orgFreedesktopSecret::PromptAdaptor(this);
+   QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+}
+
+PromptBase::~PromptBase()
+{
+}
+
+const QDBusObjectPath &PromptBase::objectPath() const
+{
+   return m_objectPath;
+}
+
+const QDBusObjectPath &PromptBase::serviceObjectPath() const
+{
+   return m_serviceObjectPath;
+}
+
+void PromptBase::emitCompleted(bool dismissed, const QVariant &result)
+{
+   emit completed(dismissed, result);
+}
+
+SingleJobPrompt::SingleJobPrompt(Service* service, BackendJob* job, QObject* parent)
+ : PromptBase(service, parent), m_prompted(false), m_job(job)
+{
+   connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
+}
+
+SingleJobPrompt::~SingleJobPrompt()
+{
+   // TODO: delete the job?
+}
+
+void SingleJobPrompt::prompt(const QString &windowId)
+{
+   Q_UNUSED(windowId);
+   if (m_prompted) {
+      return;
+   }
+   m_prompted = true;
+   
+   // TODO: convert windowId to a WId and pass it to the job
+   m_job->enqueue();
+}
+
+void SingleJobPrompt::dismiss()
+{
+   if (m_prompted) {
+      return;
+   }
+   m_prompted = true;
+
+   m_job->dismiss();
+}
+
+void SingleJobPrompt::jobResult(QueuedJob *job)
+{
+   Q_ASSERT(job == m_job);
+   // check for errors first
+   if (m_job->isDismissed()) {
+      emit completed(true, QVariant(""));
+   } else if (m_job->error() != NoError) {
+      // TODO: figure out how to handle errors gracefully.      
+      emit completed(false, QVariant(""));
+   } else {
+      switch (m_job->type()) {
+         
+      case BackendJob::TypeUnlockCollection:
+      case BackendJob::TypeLockCollection:
+      case BackendJob::TypeDeleteCollection:
+      case BackendJob::TypeChangeAuthenticationCollection:
+      case BackendJob::TypeDeleteItem:
+      case BackendJob::TypeLockItem:
+      case BackendJob::TypeUnlockItem:
+      case BackendJob::TypeChangeAuthenticationItem:
+         {
+            BooleanResultJob *brj = qobject_cast<BooleanResultJob*>(m_job);
+            Q_ASSERT(brj);
+            emitCompleted(false, QVariant(brj->result()));
+         }
+         break;
+         
+      case BackendJob::TypeCreateCollectionMaster:
+         {
+            CreateCollectionMasterJob *ccmj = \
qobject_cast<CreateCollectionMasterJob*>(m_job); +            Q_ASSERT(ccmj);
+            QDBusObjectPath result("/");
+            if (ccmj->collection()) {
+               BackendCollection *coll = ccmj->collection();
+               result.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); +            }
+            
+            emitCompleted(false, qVariantFromValue(result));
+         }
+         break;
+         
+      case BackendJob::TypeCreateCollection:
+         {
+            CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(m_job);
+            Q_ASSERT(ccj);
+            QDBusObjectPath result("/");
+            if (ccj->collection()) {
+               BackendCollection *coll = ccj->collection();
+               result.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); +            }
+            
+            emitCompleted(false, qVariantFromValue(result));
+         }
+         break;
+         
+      case BackendJob::TypeCreateItem:
+         {
+            CreateItemJob *cij = qobject_cast<CreateItemJob*>(m_job);
+            Q_ASSERT(cij);
+            QDBusObjectPath result("/");
+            if (cij->item()) {
+               BackendItem *item = cij->item();
+               result.setPath(serviceObjectPath().path() + "/collection/" +
+                  cij->collection()->id() + "/" + item->id());
+            }
+            
+            emitCompleted(false, qVariantFromValue(result));
+         }
+         break;
+         
+      default:
+         // should not happen!
+         Q_ASSERT(false);
+      }
+   }
+   
+   deleteLater();
+}
+
+ServiceMultiPrompt::ServiceMultiPrompt(Service *service, const QSet<BackendJob*> \
jobs, +                                     QObject *parent)
+ : PromptBase(service, parent), m_prompted(false), m_jobs(jobs)
+{
+   bool jobTypeDetermined = false;
+   bool jobTypeUnlock = false;
+   
+   Q_FOREACH(BackendJob *job, m_jobs) {
+      // make sure the subjobs are either all unlock or all lock calls
+      bool currentJobTypeUnlock = (job->type() == BackendJob::TypeUnlockCollection \
|| +                                   job->type() == BackendJob::TypeUnlockItem);
+      if (jobTypeDetermined && jobTypeUnlock != currentJobTypeUnlock) {
+         Q_ASSERT(false);
+      } else if (!jobTypeDetermined) {
+         jobTypeUnlock = currentJobTypeUnlock;
+         jobTypeDetermined = true;
+      }
+      connect(job, SIGNAL(result(QueuedJob*)), SLOT(jobResult(QueuedJob*)));
+   }
+}
+
+ServiceMultiPrompt::~ServiceMultiPrompt()
+{
+   // TODO: delete jobs if not started?
+}
+
+void ServiceMultiPrompt::prompt(const QString &windowId)
+{
+   Q_UNUSED(windowId);
+   if (m_prompted) {
+      return;
+   }
+   m_prompted = true;
+   
+   // TODO: convert windowId to a WId and pass it to the job
+   Q_FOREACH(BackendJob *job, m_jobs) {
+      job->enqueue();
+   }
+}
+
+void ServiceMultiPrompt::dismiss()
+{
+   if (m_prompted) {
+      return;
+   }
+   m_prompted = true;
+   
+   Q_FOREACH(BackendJob *job, m_jobs) {
+      disconnect(job, SIGNAL(result(QueuedJob*)), this, \
SLOT(jobResult(QueuedJob*))); +      job->dismiss();
+   }
+
+   // emit result right away so we don't have to catch all result() signals
+   // from individual jobs.
+   emitCompleted(true, qVariantFromValue(QList<QDBusObjectPath>()));
+   deleteLater();
+}
+
+void ServiceMultiPrompt::jobResult(QueuedJob *job)
+{
+   BackendJob *bj = qobject_cast<BackendJob*>(job);
+   Q_ASSERT(bj);
+   Q_ASSERT(m_jobs.contains(bj));
+   // remove job from the set of jobs we're waiting for
+   m_jobs.remove(bj);
+   if (bj->error() != NoError) {
+      // TODO: figure out what to do with erroneous jobs
+   } else {
+      switch (bj->type()) {
+         
+      case BackendJob::TypeUnlockCollection:
+         {
+            UnlockCollectionJob *ucj = qobject_cast<UnlockCollectionJob*>(bj);
+            Q_ASSERT(ucj);
+            if (ucj->result()) {
+               BackendCollection *coll = ucj->collection();
+               QDBusObjectPath path;
+               path.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); +               m_result.append(path);
+            }
+         }
+         break;
+
+      case BackendJob::TypeLockCollection:
+         {
+            LockCollectionJob *lcj = qobject_cast<LockCollectionJob*>(bj);
+            Q_ASSERT(lcj);
+            if (lcj->result()) {
+               BackendCollection *coll = lcj->collection();
+               QDBusObjectPath path;
+               path.setPath(serviceObjectPath().path() + "/collection/" + \
coll->id()); +               m_result.append(path);
+            }
+         }
+         break;
+         
+      case BackendJob::TypeUnlockItem:
+         {
+            UnlockItemJob *uij = qobject_cast<UnlockItemJob*>(bj);
+            Q_ASSERT(uij);
+            if (uij->result()) {
+               BackendItem *item = uij->item();
+               BackendCollection *coll = 0;
+               // TODO: I NEED THE COLLECTION DAMMIT
+               QDBusObjectPath path;
+               path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
+ +                            "/" + item->id());
+               m_result.append(path);
+            }
+         }
+         break;
+
+      case BackendJob::TypeLockItem:
+         {
+            LockItemJob *lij = qobject_cast<LockItemJob*>(bj);
+            Q_ASSERT(lij);
+            if (lij->result()) {
+               BackendItem *item = lij->item();
+               BackendCollection *coll = 0;
+               // TODO: I NEED THE COLLECTION DAMMIT
+               QDBusObjectPath path;
+               path.setPath(serviceObjectPath().path() + "/collection/" + coll->id() \
+ +                            "/" + item->id());
+               m_result.append(path);
+            }
+         }
+         break;
+         
+      default:
+         Q_ASSERT(false);
+      }
+   }
+   
+   if (m_jobs.isEmpty()) {
+      // all jobs finished
+      emitCompleted(false, qVariantFromValue(m_result));
+      deleteLater();
+   }
+}
+
+#include "prompt.moc"
diff --git a/frontend/secret/prompt.h b/frontend/secret/prompt.h
new file mode 100644
index 0000000..b5aac66
--- /dev/null
+++ b/frontend/secret/prompt.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_PROMPT_H
+#define DAEMON_PROMPT_H
+
+#include <backend/backendjob.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QSet>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusContext>
+
+class Service;
+
+/**
+ * Implementation of prompt objects according to the org.freedesktop.Secret.Prompt
+ * interface.
+ */
+class PromptBase : public QObject, protected QDBusContext
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    *
+    * @param service Service object (used to derive the object path of the prompt)
+    * @param job the job encapsulated by the prompt
+    * @param parent Parent object
+    */
+   PromptBase(Service *service, QObject *parent);
+   
+   /**
+    * Destructor.
+    */
+   virtual ~PromptBase();
+   
+   /**
+    * Return the prompt's path on the D-Bus.
+    *
+    * @return the Prompt object's path
+    */
+   const QDBusObjectPath &objectPath() const;
+   
+   /**
+    * Return the service object's path on the D-Bus.
+    *
+    * @return the Service object's path
+    */
+   const QDBusObjectPath &serviceObjectPath() const;
+   
+   /**
+    * Perform the prompt.
+    *
+    * @param windowId Platform specific window handle to use for showing the prompt
+    * @todo implement window handle handling
+    */
+   virtual void prompt(const QString &windowId) = 0;
+   
+   /**
+    * Dismiss the prompt.
+    */
+   virtual void dismiss() = 0;
+   
+Q_SIGNALS:
+   /**
+    * Emitted when the operation performed by the prompt was completed
+    *
+    * @param dismissed if true the prompt was dismissed, if false it was completed
+    * @param result result of the operation encapulated by the prompt object
+    */
+   void completed(bool dismissed, QVariant result);
+   
+protected:
+   /**
+    * Used to emit completed() signals in derived classes.
+    *
+    * @param dismissed if true the prompt was dismissed, if false it was completed
+    * @param result result of the operation encapsulated by the prompt object
+    */
+   void emitCompleted(bool dismissed, const QVariant &result);
+   
+private:
+   QDBusObjectPath m_objectPath; // the prompt object's objectpath
+   QDBusObjectPath m_serviceObjectPath; // the service's objectpath
+};
+
+/**
+ * Prompt object encapsulating a single BackendJob.
+ */
+class SingleJobPrompt : public PromptBase
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    *
+    * @param service Service object (used to derive the object path of the prompt)
+    * @param job the job encapsulated by the prompt
+    * @param parent Parent object
+    */
+   SingleJobPrompt(Service *service, BackendJob *job, QObject *parent = 0);
+   
+   /**
+    * Destructor.
+    */
+   virtual ~SingleJobPrompt();
+   
+   /**
+    * Perform the prompt.
+    *
+    * @param windowId Platform specific window handle to use for showing the prompt
+    * @todo implement window handle handling
+    */
+   virtual void prompt(const QString &windowId);
+   
+   /**
+    * Dismiss the prompt.
+    */
+   virtual void dismiss();
+   
+private Q_SLOTS:
+   /**
+    * Connected to the backend job's result() signal this notifies about
+    * the job's completion.
+    *
+    * @param job the job that finished
+    */
+   void jobResult(QueuedJob *job);
+
+private:
+   bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
already +   BackendJob *m_job; // the encapulated job
+};
+
+/**
+ * Prompt object encapsulating a Service.Unlock or a Service.Lock call with multiple \
targets. + */
+class ServiceMultiPrompt : public PromptBase
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    *
+    * @param service Service object (used to derive the object path of the prompt)
+    * @param jobs the unlock jobs to encapsulate
+    * @param parent parent object
+    */
+   ServiceMultiPrompt(Service *service, const QSet<BackendJob*> jobs, QObject \
*parent = 0); +   
+   /**
+    * Destructor.
+    */
+   virtual ~ServiceMultiPrompt();
+   
+   /**
+    * Perform the prompt.
+    *
+    * @pararm windowId Platform specific window handle to use for showing the prompt
+    * @todo implement window handling
+    */
+   virtual void prompt(const QString &windowId);
+   
+   /**
+    * Dismiss this prompt.
+    */
+   virtual void dismiss();
+   
+private Q_SLOTS:
+   /**
+    * Connected to the backend jobs' result() signals this notifies about a
+    * job's completion.
+    *
+    * @param job the job that finished
+    */
+   void jobResult(QueuedJob *job);
+   
+private:
+   bool m_prompted; // true if one of the prompt()/dismiss() methods has been called \
already +   QList<QDBusObjectPath> m_result; // resulting unlocked/locked object \
paths +   QSet<BackendJob*> m_jobs; // encapsulated jobs
+};
+
+#endif
diff --git a/frontend/secret/secret.cpp b/frontend/secret/secret.cpp
new file mode 100644
index 0000000..6639f90
--- /dev/null
+++ b/frontend/secret/secret.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "secret.h"
+
+#include <QtCore/QSharedData>
+
+Secret::Secret() : d(new SecretData)
+{
+}
+
+Secret::Secret(const Secret &other) : d(other.d)
+{
+}
+
+Secret::~Secret()
+{
+}
+
+void Secret::setSession(const QDBusObjectPath &session)
+{
+   d->m_session = session;
+}
+
+const QDBusObjectPath &Secret::session() const
+{
+   return d->m_session;
+}
+
+void Secret::setParameters(const QByteArray &parameters)
+{
+   d->m_parameters = parameters;
+}
+
+const QByteArray &Secret::parameters() const
+{
+   return d->m_parameters;
+}
+
+void Secret::setValue(const QByteArray &value)
+{
+   // TODO: encryption
+   d->m_value = value;
+}
+
+const QByteArray &Secret::value() const
+{
+   // TODO: decryption
+   return d->m_value;
+}
+
+QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret)
+{
+   argument.beginStructure();
+   argument << secret.session() << secret.parameters() << secret.value();
+   argument.endStructure();
+   return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret)
+{
+   QDBusObjectPath session;
+   QByteArray parameters;
+   QByteArray value;
+   
+   argument.beginStructure();
+   argument >> session >> parameters >> value;
+   argument.endStructure();
+
+   secret.setSession(session);
+   secret.setParameters(parameters);
+   secret.setValue(value);
+
+   return argument;
+}
diff --git a/frontend/secret/secret.h b/frontend/secret/secret.h
new file mode 100644
index 0000000..8173faf
--- /dev/null
+++ b/frontend/secret/secret.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_SECRET_H
+#define DAEMON_SECRET_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QByteArray>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusArgument>
+#include <QtCrypto/QtCrypto>
+
+/**
+ * This class represents secret (possibly encrypted) for transfer on the
+ * D-Bus. Encryption and decryption is handled by the respective session.
+ *
+ * @remarks Objects of this class are implicitly shared
+ */
+class Secret
+{
+   // TODO: this should actually be inside secret.cpp but I'm getting strange
+   //       errors if I put it there. investigate.
+   class SecretData : public QSharedData
+   {
+   public:
+      SecretData() {}
+      SecretData(const SecretData &other)
+         : QSharedData(other), m_session(other.m_session), \
m_parameters(other.m_parameters), +         m_value(other.m_value) {}
+      ~SecretData() {}
+      QDBusObjectPath m_session;
+      QByteArray m_parameters;
+      QByteArray m_value;
+   };
+   
+public:
+   /**
+    * Constructs an empty Secret.
+    */
+   Secret();
+
+   /**
+    * Copy constructor.
+    */
+   Secret(const Secret &other);
+
+   /**
+    * Destructor.
+    */
+   ~Secret();
+
+   /**
+    * Set the session object D-Bus path.
+    */
+   void setSession(const QDBusObjectPath &session);
+
+   /**
+    * Get the session object D-Bus path.
+    */
+   const QDBusObjectPath &session() const;
+
+   /**
+    * Set the encryption parameters.
+    */
+   void setParameters(const QByteArray &parameters);
+
+   /**
+    * Get the encryption parameters.
+    */
+   const QByteArray &parameters() const;
+
+   /**
+    * Set the secret's encrypted value
+    */
+   void setValue(const QByteArray &value);
+
+   /**
+    * Get the secret's encrypted value
+    */
+   const QByteArray &value() const;
+
+private:
+   class SecretData;
+   QSharedDataPointer<SecretData> d;
+};
+
+Q_DECLARE_METATYPE(Secret)
+
+QDBusArgument &operator<<(QDBusArgument &argument, const Secret &secret);
+const QDBusArgument &operator>>(const QDBusArgument &argument, Secret &secret);
+
+#endif
diff --git a/frontend/secret/service.cpp b/frontend/secret/service.cpp
new file mode 100644
index 0000000..d08ce12
--- /dev/null
+++ b/frontend/secret/service.cpp
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "service.h"
+#include "adaptors/serviceadaptor.h"
+#include "collection.h"
+#include "prompt.h"
+#include "session.h"
+#include "secret.h"
+#include "item.h"
+
+#include <backend/backendcollection.h>
+#include <backend/backenditem.h>
+
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMetaType>
+#include <QtDBus/QDBusMessage>
+
+Service::Service(BackendMaster *master, QObject *parent)
+ : QObject(parent), m_master(master), m_basePath("/org/freedesktop/secrets")
+{
+   Q_ASSERT(master);
+   
+   new orgFreedesktopSecret::ServiceAdaptor(this);
+   QDBusConnection::sessionBus().registerObject(m_basePath.path(), this);
+
+   // TODO: make master singleton so we can get a KWallet-compatible interface
+   //       on top of it as well.
+
+   connect(m_master, SIGNAL(collectionCreated(BackendCollection*)),
+                     SLOT(slotCollectionCreated(BackendCollection*)));
+   connect(m_master, SIGNAL(collectionDeleted(BackendCollection*)),
+                     SLOT(slotCollectionDeleted(BackendCollection*)));
+   connect(m_master, SIGNAL(collectionChanged(BackendCollection*)),
+                     SLOT(slotCollectionChanged(BackendCollection*)));
+
+   // TODO: add managers to master
+}
+
+const QDBusObjectPath &Service::objectPath() const
+{
+   return m_basePath;
+}
+
+const QList<QDBusObjectPath> &Service::collections() const
+{
+   return m_collections;
+}
+
+QVariant Service::openSession(const QString &algorithm, const QVariant &input,
+                              QDBusObjectPath &result)
+{
+   QVariant output;
+   QString peer;
+   if (calledFromDBus()) {
+      peer = message().service();
+   }
+   Session *session = Session::create(algorithm, input, output, peer, this);
+   if (session) {
+      result = session->objectPath();
+   } else {
+      result = QDBusObjectPath("/");
+      if (calledFromDBus()) {
+         sendErrorReply("org.freedesktop.Secret.Error.NotSupported");
+      }
+   }
+   return output;
+}
+
+QDBusObjectPath Service::createCollection(const QMap<QString, QVariant> &properties,
+                                          QDBusObjectPath &prompt)
+{
+   // TODO: default label
+   QString label;
+   bool locked = false;
+
+   if (properties.contains("Label")) {
+      label = properties["Label"].toString();
+   }
+   if (properties.contains("Locked")) {
+      locked = properties["Locked"].toBool();
+   }
+   
+   CreateCollectionMasterJob *job = m_master->createCreateCollectionMasterJob(label, \
locked); +   if (job->isImmediate()) {
+      job->exec();
+      if (job->error() != NoError || !job->collection()) {
+         // TODO: error creating the collection
+         return QDBusObjectPath("/");
+      } else {
+         BackendCollection *coll = job->collection();
+         prompt.setPath("/");
+         QDBusObjectPath collPath(m_basePath.path() + "/collection/" + coll->id());
+         return collPath;
+      }
+   } else {
+      PromptBase *p = new SingleJobPrompt(this, job, this);
+      prompt = p->objectPath();
+      return QDBusObjectPath("/");
+   }
+}
+
+QList<QDBusObjectPath> Service::searchItems(const QMap<QString, QString> \
&attributes, +                                            QList<QDBusObjectPath> \
&locked) +{
+   // TODO: check if session exists
+   // TODO: should this rather be implemented using Daemon::Collection?
+   QList<QDBusObjectPath> unlocked;
+   Q_FOREACH(BackendCollection* collection, m_master->collections()) {
+      QString collPath = m_basePath.path() + "/collection/" + collection->id();
+      BackendReturn<QList<BackendItem*> > rc = collection->searchItems(attributes);
+      if (!rc.isError()) {
+         QList<BackendItem*> items = rc.value();
+         Q_FOREACH(BackendItem *item, items) {
+            if (item->isLocked()) {
+               locked.append(QDBusObjectPath(collPath + "/" + item->id()));
+            } else {
+               unlocked.append(QDBusObjectPath(collPath + "/" + item->id()));
+            }
+         }
+      }
+   }
+   return unlocked;
+}
+
+QList<QDBusObjectPath> Service::unlock(const QList<QDBusObjectPath> &objects,
+                                       QDBusObjectPath &prompt)
+{
+   // TODO: check is session exists
+   // TODO: bypass prompt
+
+   // objects already unlocked
+   QList<QDBusObjectPath> rc;
+   // jobs to call asynchronously
+   QSet<BackendJob*> unlockJobs;
+   QObject *object;
+   Item *item;
+   Collection *collection;
+   BackendItem *bi;
+   BackendCollection *bc;
+   
+   Q_FOREACH(const QDBusObjectPath &path, objects) {
+      object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
+      if (!object) {
+         continue;
+      }
+      if ((collection = qobject_cast<Collection*>(object))) {
+         bc = collection->backendCollection();
+         if (bc) {
+            if (!bc->isLocked()) {
+               rc.append(path);
+            } else {
+               UnlockCollectionJob *ucj = bc->createUnlockJob();
+               if (ucj->isImmediate()) {
+                  ucj->exec();
+                  if (ucj->error() != NoError || !ucj->result()) {
+                     // not unlocked, maybe due to an error.
+                     // There's not much to do about it. Silently ignore.
+                  } else {
+                     rc.append(path);
+                  }
+               } else {
+                  unlockJobs.insert(ucj);
+               }
+            }
+         }
+      } else if ((item = qobject_cast<Item*>(object))) {
+         bi = item->backendItem();
+         if (bi) {
+            if (!bi->isLocked()) {
+               rc.append(path);
+            } else {
+               UnlockItemJob *uij = bi->createUnlockJob();
+               if (uij->isImmediate()) {
+                  uij->exec();
+                  if (uij->error() != NoError ||!uij->result()) {
+                     // not unlocked, maybe due to an error.
+                     // There's not much to do about it. Silently ignore.
+                  } else {
+                     rc.append(path);
+                  }
+               } else {
+                  unlockJobs.insert(uij);
+               }
+            }
+         }
+      }
+      // NOTE: objects which either don't exist or whose type is wrong are silently \
ignored. +   }
+
+   if (!unlockJobs.isEmpty()) {
+      ServiceMultiPrompt *p = new ServiceMultiPrompt(this, unlockJobs, this);
+      prompt = p->objectPath();
+   } else {
+      prompt.setPath("/");
+   }
+
+   return rc;
+}
+
+QList<QDBusObjectPath> Service::lock(const QList<QDBusObjectPath> &objects,
+                                     QDBusObjectPath &prompt)
+{
+   // TODO: check is session exists
+   
+   // objects already locked
+   QList<QDBusObjectPath> rc;
+   // jobs to call asynchronously
+   QSet<BackendJob*> lockJobs;
+   QObject *object;
+   Item *item;
+   Collection *collection;
+   BackendItem *bi;
+   BackendCollection *bc;
+   
+   Q_FOREACH(const QDBusObjectPath &path, objects) {
+      object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
+      if (!object) {
+         continue;
+      }
+      if ((collection = qobject_cast<Collection*>(object))) {
+         bc = collection->backendCollection();
+         if (bc) {
+            if (bc->isLocked()) {
+               rc.append(path);
+            } else {
+               LockCollectionJob *lcj = bc->createLockJob();
+               if (lcj->isImmediate()) {
+                  lcj->exec();
+                  if (lcj->error() != NoError || !lcj->result()) {
+                     // not locked, maybe due to an error.
+                     // There's not much to do about it. Silently ignore.
+                  } else {
+                     rc.append(path);
+                  }
+               } else {
+                  lockJobs.insert(lcj);
+               }
+            }
+         }
+      } else if ((item = qobject_cast<Item*>(object))) {
+         bi = item->backendItem();
+         if (bi) {
+            if (bi->isLocked()) {
+               rc.append(path);
+            } else {
+               LockItemJob *lij = bi->createLockJob();
+               if (lij->isImmediate()) {
+                  lij->exec();
+                  if (lij->error() != NoError || !lij->result()) {
+                     // not locked, maybe due to an error.
+                     // There's not much to do about it. Silently ignore.
+                  } else {
+                     rc.append(path);
+                  }
+               } else {
+                  lockJobs.insert(lij);
+               }
+            }
+         }
+      }
+      // NOTE: objects which either don't exist or whose type is wrong are silently \
ignored. +   }
+
+   if (!lockJobs.isEmpty()) {
+      ServiceMultiPrompt *p = new ServiceMultiPrompt(this, lockJobs, this);
+      prompt = p->objectPath();
+   } else {
+      prompt.setPath("/");
+   }
+
+   return rc;
+}
+
+QMap<QDBusObjectPath, Secret> Service::getSecrets(const QList<QDBusObjectPath> \
&items, +                                                  const QDBusObjectPath \
&session) +{
+   QMap<QDBusObjectPath, Secret> rc;
+   QObject *object;
+   Session *sessionObj;
+   Item *item;
+   bool ok;
+   Secret secret;
+   
+   object = QDBusConnection::sessionBus().objectRegisteredAt(session.path());
+   if (!object || !(sessionObj = qobject_cast<Session*>(object))) {
+      if (calledFromDBus()) {
+         sendErrorReply("org.freedesktop.Secret.Error.NoSession");
+      }
+      return rc;
+   }
+   
+   Q_FOREACH(const QDBusObjectPath &path, items) {
+      object = QDBusConnection::sessionBus().objectRegisteredAt(path.path());
+      if (object && (item = qobject_cast<Item*>(object))) {
+         BackendItem *bi = item->backendItem();
+         if (bi && !bi->isLocked()) {
+            BackendReturn<QCA::SecureArray> be = bi->secret();
+            // TODO: what should this do if getting the secret failed?
+            if (!be.isError()) {
+               secret = sessionObj->encrypt(be.value(), ok);
+               // TODO: what should this do if encrypting failed?
+               if (ok) {
+                  rc.insert(path, secret);
+               }
+            }
+         }
+      }
+   }
+
+   return rc;
+}
+
+void Service::slotCollectionCreated(BackendCollection *collection)
+{
+   Q_ASSERT(collection);
+   Collection *coll = new Collection(collection, this);
+   m_collections.append(coll->objectPath());
+   emit collectionCreated(coll->objectPath());
+}
+
+void Service::slotCollectionDeleted(BackendCollection *collection)
+{
+   Q_ASSERT(collection);
+   QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
+   m_collections.removeAll(collPath);
+   // TODO: make sure Daemon::Collection gets destroyed
+   emit collectionDeleted(collPath);
+}
+
+void Service::slotCollectionChanged(BackendCollection *collection)
+{
+   Q_ASSERT(collection);
+   QDBusObjectPath collPath(m_basePath.path() + "/collection/" + collection->id());
+   emit collectionChanged(collPath);
+}
+
+#include "service.moc"
diff --git a/frontend/secret/service.h b/frontend/secret/service.h
new file mode 100644
index 0000000..29a8a98
--- /dev/null
+++ b/frontend/secret/service.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_SERVICE_H
+#define DAEMON_SERVICE_H
+
+#include <backend/backendmaster.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QMultiMap>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusContext>
+
+class Secret;
+class Collection;
+
+class _TypeRegistrar;
+   
+/**
+ * Main entry point of the secret service D-Bus daemon implementing the
+ * org.freedesktop.Secret.Service interface.
+ * 
+ * @todo Implement proper session handling
+ */
+class Service : public QObject, protected QDBusContext
+{
+   Q_OBJECT
+
+public:
+   /**
+    * Constructor.
+    *
+    * @param master Backend master to use
+    * @param parent Parent object
+    */
+   Service(BackendMaster *master, QObject *parent = 0);
+
+   /**
+    * Return the service's path on the D-Bus.
+    *
+    * @return the Service object's path
+    */
+   const QDBusObjectPath &objectPath() const;
+
+   /**
+    * Accessor for the list of known collections.
+    *
+    * @return all collections known to the service.
+    */
+   const QList<QDBusObjectPath> &collections() const;
+
+   /**
+    * Open a unique session for the caller application.
+    *
+    * @param algorithm the algorithm the caller wishes to use
+    * @param input input arguments for the algorithm
+    * @param result the object path of the session, if session was created
+    * @return output of the session algorithm negotiation
+    */
+   QVariant openSession(const QString &algorithm, const QVariant &input, \
QDBusObjectPath &result); +   
+   /**
+    * Create a new collection with the specified properties.
+    *
+    * @param properties properties for the new collection
+    * @param prompt a prompt object if prompting is necessary, or "/" if no prompt \
was needed +    * @return the new collection object or "/" if prompting is necessary
+    */
+   QDBusObjectPath createCollection(const QMap<QString, QVariant> &properties,
+                                    QDBusObjectPath &prompt);
+
+   /**
+    * Find items in any collection.
+    *
+    * @param attributes the attributes an item has to match in order to be found
+    * @param locked items found that require authentication
+    * @return items found that are already unlocked
+    */
+   QList<QDBusObjectPath> searchItems(const QMap<QString, QString> &attributes,
+                                      QList<QDBusObjectPath> &locked);
+                                      
+   /**
+    * Unlock the specified items or collections.
+    *
+    * @param objects objects to unlock
+    * @param prompt a prompt object which can be used to unlock the remaining \
objects or +    *               "/" if no prompt is necessary.
+    * @return objects that were unlocked without a prompt
+    */
+   QList<QDBusObjectPath> unlock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+   /**
+    * Lock the specified items or collections.
+    *
+    * @param objects objects to lock
+    * @param prompt a prompt to lock the objects or "/" if no prompt is necessary
+    * @return objects that were locked without a prompt
+    */
+   QList<QDBusObjectPath> lock(const QList<QDBusObjectPath> &objects, \
QDBusObjectPath &prompt); +
+   /**
+    * Retrieve multiple secrets from different items.
+    *
+    * @param items items to get secrets for
+    * @param session the session to use to encode the secrets
+    * @return the secrets for the items.
+    */
+   QMap<QDBusObjectPath, Secret> getSecrets(const QList<QDBusObjectPath> &items,
+                                            const QDBusObjectPath &session);
+   
+Q_SIGNALS:
+   /**
+    * Emitted when a new collection is discovered or created.
+    *
+    * @param collection Objectpath of the collection that was discovered/created
+    */
+   void collectionCreated(const QDBusObjectPath &collection);
+
+   /**
+    * Emitted when an existing collection was deleted or disappeared.
+    *
+    * @param collection Objectpath of the collection that was deleted
+    */
+   void collectionDeleted(const QDBusObjectPath &collection);
+
+   /**
+    * Emitted when an existing collection changed.
+    *
+    * @param collection Objectpath of the collection that changed
+    */
+   void collectionChanged(const QDBusObjectPath &collection);
+   
+private Q_SLOTS:
+   // handle collectionCreated() calls from master
+   void slotCollectionCreated(BackendCollection *collection);
+   // handle collectionDeleted() calls from master
+   void slotCollectionDeleted(BackendCollection *collection);
+   // handle collectionChanged() calls from master
+   void slotCollectionChanged(BackendCollection *collection);
+   
+private:
+   BackendMaster *m_master;
+   QList<QDBusObjectPath> m_collections; // cache object paths of collections
+   const QDBusObjectPath m_basePath;
+};
+
+#endif
diff --git a/frontend/secret/session.cpp b/frontend/secret/session.cpp
new file mode 100644
index 0000000..704aa67
--- /dev/null
+++ b/frontend/secret/session.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "session.h"
+#include "adaptors/sessionadaptor.h"
+#include "service.h"
+
+#include <secrettool.h>
+
+#include <QtDBus/QDBusConnection>
+#include <QtCore/QRegExp>
+
+#include <QtCore/QDebug>
+
+Session::Session(Service *parent)
+ : QObject(parent),
+   m_objectPath(parent->objectPath().path() + "/session/" + createId()),
+   m_cipher(0)
+{
+   // register on the bus
+   new orgFreedesktopSecret::SessionAdaptor(this);
+   QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
+}
+
+Session::~Session()
+{
+   delete m_cipher;
+}
+
+const QDBusObjectPath &Session::objectPath() const
+{
+   return m_objectPath;
+}
+
+Session *Session::create(const QString &algorithm, const QVariant &input,
+                         QVariant &output, const QString &peer, Service *parent)
+{
+   static QRegExp rxAlgorithm("^dh-ietf(\\d+)-([^-]+)-([^-]+)-([^-]+)$",
+                              Qt::CaseInsensitive);
+   
+   Session *session = 0;
+   
+   if (algorithm == "plain") {
+      session = new Session(parent);
+      session->m_encrypted = false;
+      output.setValue(QString(""));
+   } else if (rxAlgorithm.exactMatch(algorithm) &&
+              input.type() == QVariant::ByteArray) {
+      QString encalgo = rxAlgorithm.cap(2).toLower();
+      QString blockmode = rxAlgorithm.cap(3).toLower();
+      QString padding = rxAlgorithm.cap(4).toLower();
+
+      QCA::KeyGenerator keygen;
+      
+      // determine the discrete logarithm group to use
+      QCA::DLGroupSet groupnum;
+      switch (rxAlgorithm.cap(1).toInt()) {
+      case 768:
+         groupnum = QCA::IETF_768;
+         break;
+      case 1024:
+         groupnum = QCA::IETF_1024;
+         break;
+      case 1536:
+         groupnum = QCA::IETF_1536;
+         break;
+      case 2048:
+         groupnum = QCA::IETF_2048;
+         break;
+      case 3072:
+         groupnum = QCA::IETF_3072;
+         break;
+      case 4096:
+         groupnum = QCA::IETF_4096;
+         break;
+      case 6144:
+         groupnum = QCA::IETF_6144;
+         break;
+      case 8192:
+         groupnum = QCA::IETF_8192;
+         break;
+      default:
+         // no known discrete logarithm group
+         return 0;
+      }
+      QCA::DLGroup dlgroup(keygen.createDLGroup(groupnum));
+      if (dlgroup.isNull()) {
+         return 0;
+      }
+      
+      // determine if we support (or want to support)
+      // the encryption algorithm.
+      if ((encalgo == "blowfish" || encalgo == "twofish" ||
+           encalgo == "aes128" || encalgo == "aes192" ||
+           encalgo == "aes256") &&
+           QCA::isSupported(QString("%1-%2-%3").arg(encalgo, blockmode, padding)
+                           .toLatin1().constData())) {
+         
+         // get client's public key
+         QCA::DHPublicKey clientKey(dlgroup,
+                                    \
QCA::BigInteger(QCA::SecureArray(input.toByteArray()))); +         // generate own \
private key +         QCA::PrivateKey privKey(keygen.createDH(dlgroup));
+         // generate the shared symmetric key
+         QCA::SymmetricKey sharedKey(privKey.deriveKey(clientKey));
+
+         QCA::Cipher::Mode cbm;
+         if (blockmode == "cbc") {
+            cbm = QCA::Cipher::CBC;
+         } else {
+            return 0;
+         }
+         
+         QCA::Cipher::Padding cp;
+         if (padding == "pkcs7") {
+            cp = QCA::Cipher::PKCS7;
+         } else if (padding == "default") {
+            cp = QCA::Cipher::DefaultPadding;
+         } else {
+            return 0;
+         }
+         
+         QCA::Cipher *cipher = new QCA::Cipher(encalgo, cbm, cp);
+         
+         // check if creating the cipher worked and if our shared
+         // key is longer than the minimum length required.
+         if (sharedKey.size() >= cipher->keyLength().minimum()) {
+            // generate the response to the client so it can derive
+            // the key as well.
+            session = new Session(parent);
+            session->m_encrypted = true;
+            session->m_cipher = cipher;
+            session->m_symmetricKey = sharedKey;
+            output.setValue(privKey.toPublicKey().toDH().y().toArray().toByteArray());
 +         } else {
+            return 0;
+         }
+      }
+   } else {
+      return 0;
+   }
+
+   // creating the session was successful
+   session->m_peer = peer;
+   return session;
+}
+
+Secret Session::encrypt(const QCA::SecureArray &value, bool &ok)
+{
+   ok = false;
+
+   Secret s;
+   s.setSession(m_objectPath);
+   if (m_encrypted) {
+      Q_ASSERT(m_cipher);
+      QCA::InitializationVector iv(m_cipher->blockSize());
+      m_cipher->setup(QCA::Encode, m_symmetricKey, iv);
+      QCA::SecureArray encval = m_cipher->update(value);
+      if (!m_cipher->ok()) {
+         return s;
+      }
+      encval += m_cipher->final();
+      if (m_cipher->ok()) {
+         return s;
+      }
+      s.setValue(encval.toByteArray());
+      s.setParameters(iv.toByteArray());
+   } else {
+      s.setValue(value.toByteArray());      
+   }
+
+
+   ok = true;
+   return s;
+}
+
+QCA::SecureArray Session::decrypt(const Secret &secret, bool &ok)
+{
+   // make sure this is really meant for us
+   Q_ASSERT(secret.session() == m_objectPath);
+   ok = false;
+   
+   QCA::SecureArray value;
+   if (m_encrypted) {
+      Q_ASSERT(m_cipher);
+      if (!secret.parameters().size() == m_cipher->blockSize()) {
+         return value;
+      }
+      QCA::InitializationVector iv(secret.parameters());
+      m_cipher->setup(QCA::Decode, m_symmetricKey, iv);
+      value = m_cipher->update(secret.value());
+      if (!m_cipher->ok()) {
+         return value;
+      }
+      value += m_cipher->final();
+      if (!m_cipher->ok()) {
+         return value;
+      }
+   } else {
+      value = secret.value();
+   }
+
+   ok = true;
+   return value;
+}
+
+void Session::close()
+{
+   deleteLater();
+}
+
+const QString &Session::peer() const
+{
+   return m_peer;
+}
+
+#include "session.moc"
diff --git a/frontend/secret/session.h b/frontend/secret/session.h
new file mode 100644
index 0000000..e2cb335
--- /dev/null
+++ b/frontend/secret/session.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAEMON_SESSION_H
+#define DAEMON_SESSION_H
+
+#include "secret.h"
+
+#include <QtCore/QObject>
+#include <QtCrypto/QtCrypto>
+
+class Service;
+
+/**
+ * Represents an open session of a client on the D-Bus implementing the
+ * org.freedesktop.Secret.Session interface.
+ *
+ * @todo stub implementation, currently only supports plain (no encryption)
+ */
+class Session : public QObject
+{
+   Q_OBJECT
+
+private:
+   /**
+    * Constructor.
+    *
+    * @param parent Parent Service object
+    */
+   Session(Service *parent);
+
+public:
+   /**
+    * Destructor.
+    */
+   ~Session();
+   
+   /**
+    * Get the session's object path.
+    */
+   const QDBusObjectPath &objectPath() const;
+   
+   /**
+    * Try to create a (possibly encrypted) session for the use of transferring
+    * secrets.
+    *
+    * @param algorithm the negotiation/encryption algorithm to use
+    * @param input negotiation algorithm input
+    * @param output negotiation algorithm output
+    * @param parent Parent Service object
+    * @return a session object if negotiation was successful, 0 if the algorithm \
isn't +    *         supported or an error occurred
+    */
+   static Session *create(const QString &algorithm, const QVariant &input,
+                          QVariant &output, const QString &peer, Service *parent);
+
+   /**
+    * Encrypt a secret value using this session.
+    *
+    * @param value value to encrypt
+    * @param ok set to true if encrypting succeeds, set to false else
+    * @return the secret encrypted for transport
+    */
+   Secret encrypt(const QCA::SecureArray &value, bool &ok);
+
+   /**
+    * Decrypt a secret value using this session.
+    *
+    * @param secret Secret received on the D-Bus
+    * @param ok set to true if decrypting succeeds, set to false else
+    * @return the unencryped value
+    */
+   QCA::SecureArray decrypt(const Secret &secret, bool &ok);
+                             
+   /**
+    * Close this session.
+    */
+   void close();
+   
+   /**
+    * Get the session's D-Bus peer (the client requesting the session).
+    */
+   const QString &peer() const;
+
+private:
+   QDBusObjectPath m_objectPath;
+   QString m_peer; // D-Bus address of the application that requested this session
+   
+   // if true, use encryption, if false, use plaintext
+   bool m_encrypted;
+   
+   // the cipher and the symmetric key used for encryption
+   QCA::Cipher *m_cipher;
+   QCA::SymmetricKey m_symmetricKey;
+};
+
+#endif
diff --git a/frontend/tests/CMakeLists.txt b/frontend/tests/CMakeLists.txt
new file mode 100644
index 0000000..3d8f298
--- /dev/null
+++ b/frontend/tests/CMakeLists.txt
@@ -0,0 +1,24 @@
+SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+INCLUDE_DIRECTORIES (
+   ${KDE4_INCLUDES}
+   ${QCA2_INCLUDE_DIR}
+   ${CMAKE_SOURCE_DIR}
+   ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+KDE4_ADD_EXECUTABLE (ksecretservice_frontend_test
+   servicetest.cpp
+   tempblockingcollectionmanager.cpp
+   tempblockingcollection.cpp
+   tempblockingitem.cpp
+   tempblockingjobs.cpp
+)
+TARGET_LINK_LIBRARIES (ksecretservice_frontend_test
+   ksecretservicebackend
+   ksecretservicefrontend
+   ksecretservicelib
+   ${QT_QTTEST_LIBRARIES}
+)
+
+ADD_TEST (FrontendSessionTest ksecretservice_frontend_test)
diff --git a/frontend/tests/servicetest.cpp b/frontend/tests/servicetest.cpp
new file mode 100644
index 0000000..8b76a0d
--- /dev/null
+++ b/frontend/tests/servicetest.cpp
@@ -0,0 +1,707 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "servicetest.h"
+
+#include "backend/backendmaster.h"
+#include "backend/temporary/temporarycollectionmanager.h"
+#include "tempblockingcollectionmanager.h"
+#include "secret/service.h"
+#include "secret/adaptors/dbustypes.h"
+
+#include <qtest_kde.h>
+
+#include <QtTest/QTest>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusConnectionInterface>
+#include <QtCrypto/QtCrypto>
+
+#include <QtCore/QDebug>
+
+void ServiceTest::initTestCase()
+{
+   QVERIFY(QDBusConnection::sessionBus().registerService("org.freedesktop.Secret"));
+
+   QCA::init();
+   
+   m_master = new BackendMaster;
+   m_tempCollMan = new TemporaryCollectionManager(m_master);
+   m_master->addManager(m_tempCollMan);
+   m_service = new Service(m_master);
+}
+
+void ServiceTest::dbusService()
+{
+   // make sure the service is available
+   QDBusConnectionInterface *ifaceConn = QDBusConnection::sessionBus().interface();
+   QVERIFY(ifaceConn && ifaceConn->isValid());
+
+   QDBusReply<bool> registered = \
ifaceConn->isServiceRegistered("org.freedesktop.Secret"); +   \
QVERIFY(registered.isValid()); +   QVERIFY(registered.value());
+}
+
+void ServiceTest::session()
+{
+   QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); +   QVERIFY(ifaceService.isValid());
+   QCA::KeyGenerator keygen;
+   
+   // "unsupported" session algorithm
+   QList<QVariant> unsuppInput;
+   unsuppInput << QString("unsupported") << \
QVariant::fromValue(QDBusVariant(QString(""))); +   QDBusMessage unsuppReply = \
ifaceService.callWithArgumentList(QDBus::Block, "OpenSession", +                      \
unsuppInput); +   QCOMPARE(unsuppReply.type(), QDBusMessage::ErrorMessage);
+   QCOMPARE(unsuppReply.errorName(),
+            QLatin1String("org.freedesktop.Secret.Error.NotSupported"));
+
+   // "plain" session algorithm
+   QDBusObjectPath plainPath;
+   QList<QVariant> plainInput;
+   plainInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+   QDBusMessage plainReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", +                                                               \
plainInput); +   QCOMPARE(plainReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> plainArgs = plainReply.arguments();
+   QCOMPARE(plainArgs.size(), 2);
+   QCOMPARE(plainArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
+   QCOMPARE(plainArgs.at(0).value<QString>(), QLatin1String(""));
+   QCOMPARE(plainArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+   plainPath = plainArgs.at(1).value<QDBusObjectPath>();
+   QVERIFY(plainPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
 +   QDBusInterface plainIface("org.freedesktop.Secret", plainPath.path(),
+                             "org.freedesktop.Secret.Session");
+   QVERIFY(plainIface.isValid());
+   QDBusMessage plainReply2 = plainIface.call("Close");
+   QCOMPARE(plainReply2.type(), QDBusMessage::ReplyMessage);
+   QCOMPARE(plainIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+   // "dh-ietf1024-aes128-cbc-pkcs7" encryption
+   QDBusObjectPath dhPath;
+   QList<QVariant> dhInput;
+   QCA::DLGroup dhDlgroup(keygen.createDLGroup(QCA::IETF_1024));
+   QVERIFY(!dhDlgroup.isNull());
+   QCA::PrivateKey dhPrivkey(keygen.createDH(dhDlgroup));
+   QCA::PublicKey dhPubkey(dhPrivkey);
+   QByteArray dhBytePub(dhPubkey.toDH().y().toArray().toByteArray());
+   dhInput << QString("dh-ietf1024-aes128-cbc-pkcs7")
+           << QVariant::fromValue(QDBusVariant(dhBytePub));
+   QDBusMessage dhReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", +                                                            dhInput);
+   QCOMPARE(dhReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> dhArgs = dhReply.arguments();
+   QCOMPARE(dhArgs.size(), 2);
+   QCOMPARE(dhArgs.at(0).userType(), qMetaTypeId<QDBusVariant>());
+   QVariant dhOutputVar = dhArgs.at(0).value<QDBusVariant>().variant();
+   QCOMPARE(dhOutputVar.type(), QVariant::ByteArray);
+   QByteArray dhOutput = dhOutputVar.toByteArray();
+   QCA::DHPublicKey dhServiceKey(dhDlgroup,
+                                 QCA::BigInteger(QCA::SecureArray(dhOutput)));
+   QCA::SymmetricKey dhSharedKey(dhPrivkey.deriveKey(dhServiceKey));
+   QCA::Cipher *dhCipher = new QCA::Cipher("aes128", QCA::Cipher::CBC, \
QCA::Cipher::PKCS7); +   QVERIFY(dhSharedKey.size() >= \
dhCipher->keyLength().minimum()); +   QCOMPARE(plainArgs.at(1).userType(), \
qMetaTypeId<QDBusObjectPath>()); +   dhPath = dhArgs.at(1).value<QDBusObjectPath>();
+   QVERIFY(dhPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/session/")));
 +   QDBusInterface dhIface("org.freedesktop.Secret", dhPath.path(),
+                          "org.freedesktop.Secret.Session");
+   QVERIFY(dhIface.isValid());
+   QDBusMessage dhReply2 = dhIface.call("Close");
+   QCOMPARE(dhReply2.type(), QDBusMessage::ReplyMessage);
+   QCOMPARE(dhIface.call("Introspect").type(), QDBusMessage::ErrorMessage);
+}
+
+void ServiceTest::nonBlockingCollection()
+{
+   QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); +   QVERIFY(ifaceService.isValid());
+
+   // create a session
+   QDBusObjectPath sessionPath;
+   QList<QVariant> sessionInput;
+   sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+   QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", +                                                                 \
sessionInput); +   sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +
+   // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
+   ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath))); +   QVERIFY(createdSpy.isValid());
+   ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath))); +   QVERIFY(deletedSpy.isValid());
+   ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath))); +   QVERIFY(changedSpy.isValid());
+   
+   // create a collection
+   QDBusObjectPath collectionPath;
+   QMap<QString, QVariant> createProperties;
+   QList<QVariant> createInput;
+   createProperties["Label"] = "test";
+   createProperties["Locked"] = false; // create collection unlocked
+   createInput << QVariant::fromValue(createProperties);
+   QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", +                                                                \
createInput); +                                                                
+   QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> createArgs = createReply.arguments();
+   QCOMPARE(createArgs.size(), 2);
+   QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+   // CreateCollection is blocking, so the first output (path) should be "/".
+   QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+   QDBusObjectPath promptPath = createArgs.at(1).value<QDBusObjectPath>();
+   QVERIFY(promptPath.path().startsWith(
+           QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+   // prompt and wait for the result.
+   ClientPrompt *prompt = new ClientPrompt(promptPath);
+   prompt->promptAndWait(5000);
+   QVERIFY(prompt->completed());
+   QVERIFY(!prompt->dismissed());
+   QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
+   collectionPath = prompt->result().value<QDBusObjectPath>();
+   QVERIFY(collectionPath.path().startsWith(
+           QLatin1String("/org/freedesktop/secrets/collection/")));
+   QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
+                                  "org.freedesktop.Secret.Collection");
+   QVERIFY(ifaceCollection.isValid());
+   delete prompt;
+
+   // make sure the CollectionCreated signal was sent
+   if (createdSpy.size() < 1) {
+      createdSpy.waitForSignal(5000);
+   }
+   QCOMPARE(createdSpy.size(), 1);
+   QCOMPARE(createdSpy.takeFirst(), collectionPath);
+
+   // read collection properties
+   QVariant propItems = ifaceCollection.property("Items");
+   QVERIFY(propItems.isValid());
+   QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+   QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); +   QVERIFY(propItemsList.isEmpty());
+   QVariant propLabel = ifaceCollection.property("Label");
+   QVERIFY(propLabel.isValid());
+   QCOMPARE(propLabel.type(), QVariant::String);
+   QCOMPARE(propLabel.value<QString>(), QString("test"));
+   QVariant propLocked = ifaceCollection.property("Locked");
+   QVERIFY(propLocked.isValid());
+   QCOMPARE(propLocked.value<bool>(), false);
+   QVariant propCreated = ifaceCollection.property("Created");
+   QVERIFY(propCreated.isValid());
+   QCOMPARE(propCreated.type(), QVariant::ULongLong);
+   qulonglong propCreatedUll = propCreated.value<qulonglong>();
+   QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+   QVariant propModified = ifaceCollection.property("Modified");
+   QVERIFY(propModified.isValid());
+   QCOMPARE(propModified.type(), QVariant::ULongLong);
+   QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+   
+   // set the label and re-read it.
+   ifaceCollection.setProperty("Label", QString("test2"));
+   propLabel = ifaceCollection.property("Label");
+   QVERIFY(propLabel.isValid());
+   QCOMPARE(propLabel.type(), QVariant::String);
+   QCOMPARE(propLabel.value<QString>(), QString("test2"));
+   
+   // make sure the CollectionChanged signal was sent
+   if (changedSpy.size() < 1) {
+      changedSpy.waitForSignal(5000);
+   }
+   QCOMPARE(changedSpy.size(), 1);
+   QCOMPARE(changedSpy.takeFirst(), collectionPath);
+
+   // delete the collection
+   QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> deleteArgs = deleteReply.arguments();
+   QCOMPARE(deleteArgs.size(), 1);
+   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TemporaryCollection is non-blocking, so the output (prompt) should be "/".
+   QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+   // make sure the collection is gone
+   QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
+   
+   // make sure the CollectionDeleted signal was sent
+   if (deletedSpy.size() < 1) {
+      deletedSpy.waitForSignal(5000);
+   }
+   QCOMPARE(deletedSpy.size(), 1);
+   QCOMPARE(deletedSpy.takeFirst(), collectionPath);
+   
+   // close the session
+   QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::nonBlockingItem()
+{
+   QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); +
+   // create a session
+   QDBusObjectPath sessionPath;
+   QList<QVariant> sessionInput;
+   sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+   QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", +                                                                 \
sessionInput); +   sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +   
+   // create a collection
+   QDBusObjectPath collectionPath;
+   QMap<QString, QVariant> collProperties;
+   QList<QVariant> collInput;
+   collProperties["Label"] = "test3";
+   collProperties["Locked"] = false;
+   collInput << QVariant::fromValue(collProperties);
+   QDBusMessage collReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", +                                                              \
collInput); +   QDBusObjectPath promptPath = \
collReply.arguments().at(1).value<QDBusObjectPath>(); +   ClientPrompt *prompt = new \
ClientPrompt(promptPath); +   prompt->promptAndWait(5000);
+   QVERIFY(prompt->completed());
+   collectionPath = prompt->result().value<QDBusObjectPath>();
+   delete prompt;
+   QDBusInterface ifaceColl("org.freedesktop.Secret", collectionPath.path());
+   
+   ObjectPathSignalSpy createdSpy(&ifaceColl, SIGNAL(ItemCreated(QDBusObjectPath)));
+   QVERIFY(createdSpy.isValid());
+   ObjectPathSignalSpy deletedSpy(&ifaceColl, SIGNAL(ItemDeleted(QDBusObjectPath)));
+   QVERIFY(deletedSpy.isValid());
+   ObjectPathSignalSpy changedSpy(&ifaceColl, SIGNAL(ItemChanged(QDBusObjectPath)));
+   QVERIFY(changedSpy.isValid());
+   
+   // create an item
+   QDBusObjectPath itemPath;
+   StringStringMap itemAttributes;
+   itemAttributes["attribute1"] = "value1";
+   itemAttributes["attribute2"] = "value2";
+   QMap<QString, QVariant> itemProperties;
+   itemProperties["Attributes"] = QVariant::fromValue(itemAttributes);
+   itemProperties["Label"] = "item1";
+   itemProperties["Locked"] = false;
+   QList<QVariant> itemInput;
+   Secret secret;
+   secret.setSession(sessionPath);
+   secret.setValue(QByteArray("mysecret"));
+   itemInput << QVariant::fromValue(itemProperties);
+   itemInput << QVariant::fromValue(secret);
+   itemInput << false;
+   QDBusMessage itemReply = ifaceColl.callWithArgumentList(QDBus::Block, \
"CreateItem", +                                                           itemInput);
+   QCOMPARE(itemReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> itemArgs = itemReply.arguments();
+   QCOMPARE(itemArgs.size(), 2);
+   QCOMPARE(itemArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   QCOMPARE(itemArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TemporaryItem is non-blocking, so the second output (prompt) should be "/"
+   QCOMPARE(itemArgs.at(1).value<QDBusObjectPath>().path(), QLatin1String("/"));
+   itemPath = itemArgs.at(0).value<QDBusObjectPath>();
+   QVERIFY(itemPath.path().startsWith(collectionPath.path() + "/"));
+   QDBusInterface ifaceItem("org.freedesktop.Secret", itemPath.path(),
+                            "org.freedesktop.Secret.Item");
+   QVERIFY(ifaceItem.isValid());
+   
+   // make sure the ItemCreated signal was sent
+   if (createdSpy.size() < 1) {
+      createdSpy.waitForSignal(5000);
+   }
+   QCOMPARE(createdSpy.size(), 1);
+   QCOMPARE(createdSpy.takeFirst(), itemPath);
+   
+   // check if the collection's Items property contains the item.
+   QVariant propItems = ifaceColl.property("Items");
+   QVERIFY(propItems.isValid());
+   QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+   QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); +   QCOMPARE(propItemsList.count(), 1);
+   QCOMPARE(propItemsList.at(0), itemPath);
+
+   // read item properties
+   QVariant propLocked = ifaceItem.property("Locked");
+   QVERIFY(propLocked.isValid());
+   QCOMPARE(propLocked.type(), QVariant::Bool);
+   QCOMPARE(propLocked.value<bool>(), false);
+   QVariant propLabel = ifaceItem.property("Label");
+   QVERIFY(propLabel.isValid());
+   QCOMPARE(propLabel.type(), QVariant::String);
+   QCOMPARE(propLabel.value<QString>(), QLatin1String("item1"));
+   QVariant propCreated = ifaceItem.property("Created");
+   QVERIFY(propCreated.isValid());
+   QCOMPARE(propCreated.type(), QVariant::ULongLong);
+   qulonglong propCreatedUll = propCreated.value<qulonglong>();
+   QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+   QVariant propModified = ifaceItem.property("Modified");
+   QVERIFY(propModified.isValid());
+   QCOMPARE(propModified.type(), QVariant::ULongLong);
+   QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+   QVariant propAttributes = ifaceItem.property("Attributes");
+   QVERIFY(propAttributes.isValid());
+   QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
+   StringStringMap propAttributesMap = propAttributes.value<StringStringMap>();
+   QCOMPARE(propAttributesMap.size(), 2);
+   QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("value1"));
+   QCOMPARE(propAttributesMap.value("attribute2"), QLatin1String("value2"));
+   
+   // read the secret
+   QDBusMessage secretReply = ifaceItem.call(QDBus::Block, "GetSecret",
+                                             \
QVariant::fromValue<QDBusObjectPath>(sessionPath)); +   QCOMPARE(secretReply.type(), \
QDBusMessage::ReplyMessage); +   QList<QVariant> secretOutput = \
secretReply.arguments(); +   QCOMPARE(secretOutput.count(), 1);
+   Secret outsecret = qdbus_cast<Secret>(secretOutput.at(0));
+   QCOMPARE(outsecret.session(), sessionPath);
+   QCOMPARE(outsecret.value(), QByteArray("mysecret"));
+   
+   // set and re-read item properties
+   ifaceItem.setProperty("Label", QString("item2"));
+   propLabel = ifaceItem.property("Label");
+   QVERIFY(propLabel.isValid());
+   QCOMPARE(propLabel.type(), QVariant::String);
+   QCOMPARE(propLabel.value<QString>(), QLatin1String("item2"));
+   propAttributesMap["attribute3"] = "value3";
+   propAttributesMap["attribute1"] = "othervalue";
+   propAttributesMap.remove("attribute2");
+   ifaceItem.setProperty("Attributes", \
QVariant::fromValue<StringStringMap>(propAttributesMap)); +   propAttributes = \
ifaceItem.property("Attributes"); +   QVERIFY(propAttributes.isValid());
+   QCOMPARE(propAttributes.userType(), qMetaTypeId<StringStringMap>());
+   propAttributesMap = propAttributes.value<StringStringMap>();
+   QCOMPARE(propAttributesMap.size(), 2);
+   QCOMPARE(propAttributesMap.value("attribute1"), QLatin1String("othervalue"));
+   QCOMPARE(propAttributesMap.value("attribute3"), QLatin1String("value3"));
+   
+   // set and re-read the secret
+   secret.setValue("mysecret2");
+   secretReply = ifaceItem.call(QDBus::Block, "SetSecret", \
QVariant::fromValue<Secret>(secret)); +   QCOMPARE(secretReply.type(), \
QDBusMessage::ReplyMessage); +   secretReply = ifaceItem.call(QDBus::Block, \
"GetSecret", +                                \
QVariant::fromValue<QDBusObjectPath>(sessionPath)); +   QCOMPARE(secretReply.type(), \
QDBusMessage::ReplyMessage); +   secretOutput = secretReply.arguments();
+   QCOMPARE(secretOutput.count(), 1);
+   outsecret = qdbus_cast<Secret>(secretOutput.at(0));
+   QCOMPARE(outsecret.session(), sessionPath);
+   QCOMPARE(outsecret.value(), QByteArray("mysecret2"));
+   
+
+   // we should have received 2 ItemChanged signals
+   if (changedSpy.size() < 3) {
+      changedSpy.waitForSignals(3, 5000);
+   }
+   QCOMPARE(changedSpy.size(), 3);
+   QCOMPARE(changedSpy.takeFirst(), itemPath);
+   QCOMPARE(changedSpy.takeFirst(), itemPath);
+   QCOMPARE(changedSpy.takeFirst(), itemPath);
+   
+   // delete the item
+   QDBusMessage deleteReply = ifaceItem.call(QDBus::Block, "Delete");
+   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> deleteArgs = deleteReply.arguments();
+   QCOMPARE(deleteArgs.size(), 1);
+   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TemporaryItem is non-blocking, so the output (prompt) should be "/"
+   QCOMPARE(deleteArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+   // make sure the item is gone
+   QCOMPARE(ifaceItem.call("Introspect").type(), QDBusMessage::ErrorMessage);
+   
+   // make sure the ItemDeleted signal was sent
+   if (deletedSpy.size() < 1) {
+      deletedSpy.waitForSignal(5000);
+   }
+   QCOMPARE(deletedSpy.size(), 1);
+   QCOMPARE(deletedSpy.takeFirst(), itemPath);
+   
+   // delete the collection
+   ifaceColl.call(QDBus::Block, "Delete");
+   // close the session
+   QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::reInitTestCase()
+{
+   // remove the TemporaryCollectionManager and replace it with a \
TempBlockingCollectionManager +   m_master->removeManager(m_tempCollMan);
+   delete m_tempCollMan;
+   m_tempBlockCollMan = new TempBlockingCollectionManager(m_master);
+   m_master->addManager(m_tempBlockCollMan);
+}
+
+void ServiceTest::blockingCollection()
+{
+   ClientPrompt *prompt = 0;
+   
+   QDBusInterface ifaceService("org.freedesktop.Secret", \
"/org/freedesktop/secrets"); +   QVERIFY(ifaceService.isValid());
+
+   // create a session
+   // create a session
+   QDBusObjectPath sessionPath;
+   QList<QVariant> sessionInput;
+   sessionInput << QString("plain") << QVariant::fromValue(QDBusVariant(""));
+   QDBusMessage sessionReply = ifaceService.callWithArgumentList(QDBus::Block, \
"OpenSession", +                                                                 \
sessionInput); +   sessionPath = \
sessionReply.arguments().at(1).value<QDBusObjectPath>(); +
+   // listen to CollectionCreated/CollectionDeleted/CollectionChanged signals
+   ObjectPathSignalSpy createdSpy(&ifaceService, \
SIGNAL(CollectionCreated(QDBusObjectPath))); +   QVERIFY(createdSpy.isValid());
+   ObjectPathSignalSpy deletedSpy(&ifaceService, \
SIGNAL(CollectionDeleted(QDBusObjectPath))); +   QVERIFY(deletedSpy.isValid());
+   ObjectPathSignalSpy changedSpy(&ifaceService, \
SIGNAL(CollectionChanged(QDBusObjectPath))); +   QVERIFY(changedSpy.isValid());
+
+   // create a collection
+   QDBusObjectPath promptPath;
+   QMap<QString, QVariant> createProperties;
+   QList<QVariant> createInput;
+   createProperties["Label"] = "test";
+   createProperties["Locked"] = false; // create collection unlocked
+   createInput << QVariant::fromValue(createProperties);
+   QDBusMessage createReply = ifaceService.callWithArgumentList(QDBus::Block, \
"CreateCollection", +                                                                \
createInput); +   QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> createArgs = createReply.arguments();
+   QCOMPARE(createArgs.size(), 2);
+   QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TempBlockingCollection is blocking, so the first output (path) should be "/".
+   QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+   promptPath = createArgs.at(1).value<QDBusObjectPath>();
+   QVERIFY(promptPath.path().startsWith(
+           QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+   // dismiss the prompt and wait for the result.
+   prompt = new ClientPrompt(promptPath);
+   prompt->dismissAndWait(5000);
+   QVERIFY(prompt->completed());
+   QVERIFY(prompt->dismissed());
+   delete prompt;
+
+   createReply = ifaceService.callWithArgumentList(QDBus::Block, "CreateCollection",
+                                                   createInput);
+   QCOMPARE(createReply.type(), QDBusMessage::ReplyMessage);
+   createArgs = createReply.arguments();
+   QCOMPARE(createArgs.size(), 2);
+   QCOMPARE(createArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   QCOMPARE(createArgs.at(1).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TempBlockingCollection is blocking, so the first output (path) should be "/".
+   QCOMPARE(createArgs.at(0).value<QDBusObjectPath>().path(), QLatin1String("/"));
+   promptPath = createArgs.at(1).value<QDBusObjectPath>();
+   QVERIFY(promptPath.path().startsWith(
+           QLatin1String("/org/freedesktop/secrets/prompts/")));
+
+   // prompt and wait for the result.
+   prompt = new ClientPrompt(promptPath);
+   prompt->promptAndWait(5000);
+   QVERIFY(prompt->completed());
+   QVERIFY(!prompt->dismissed());
+   QCOMPARE(prompt->result().userType(), qMetaTypeId<QDBusObjectPath>());
+   QDBusObjectPath collectionPath = prompt->result().value<QDBusObjectPath>();
+   QVERIFY(collectionPath.path().startsWith(
+           QLatin1String("/org/freedesktop/secrets/collection/")));
+   QDBusInterface ifaceCollection("org.freedesktop.Secret", collectionPath.path(),
+                                  "org.freedesktop.Secret.Collection");
+   QVERIFY(ifaceCollection.isValid());
+   delete prompt;
+
+   // make sure the CollectionCreated signal was sent
+   if (createdSpy.size() < 1) {
+      createdSpy.waitForSignal(5000);
+   }
+   QCOMPARE(createdSpy.size(), 1);
+   QCOMPARE(createdSpy.takeFirst(), collectionPath);
+
+   // read collection properties
+   QVariant propItems = ifaceCollection.property("Items");
+   QVERIFY(propItems.isValid());
+   QVERIFY(propItems.canConvert<QList<QDBusObjectPath> >());
+   QList<QDBusObjectPath> propItemsList = propItems.value<QList<QDBusObjectPath> \
>(); +   QVERIFY(propItemsList.isEmpty());
+   QVariant propLabel = ifaceCollection.property("Label");
+   QVERIFY(propLabel.isValid());
+   QCOMPARE(propLabel.type(), QVariant::String);
+   QCOMPARE(propLabel.value<QString>(), QString("test"));
+   QVariant propLocked = ifaceCollection.property("Locked");
+   QVERIFY(propLocked.isValid());
+   QCOMPARE(propLocked.value<bool>(), false);
+   QVariant propCreated = ifaceCollection.property("Created");
+   QVERIFY(propCreated.isValid());
+   QCOMPARE(propCreated.type(), QVariant::ULongLong);
+   qulonglong propCreatedUll = propCreated.value<qulonglong>();
+   QVERIFY(QDateTime::currentDateTime().toTime_t() - propCreatedUll < 60);
+   QVariant propModified = ifaceCollection.property("Modified");
+   QVERIFY(propModified.isValid());
+   QCOMPARE(propModified.type(), QVariant::ULongLong);
+   QCOMPARE(propModified.value<qulonglong>(), propCreatedUll);
+
+   // set the label and re-read it.
+   ifaceCollection.setProperty("Label", QString("test2"));
+   propLabel = ifaceCollection.property("Label");
+   QVERIFY(propLabel.isValid());
+   QCOMPARE(propLabel.type(), QVariant::String);
+   QCOMPARE(propLabel.value<QString>(), QString("test2"));
+
+   // make sure the CollectionChanged signal was sent
+   if (changedSpy.size() < 1) {
+      changedSpy.waitForSignal(5000);
+   }
+   QCOMPARE(changedSpy.size(), 1);
+   QCOMPARE(changedSpy.takeFirst(), collectionPath);
+
+   // delete the collection
+   QDBusMessage deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+   QList<QVariant> deleteArgs = deleteReply.arguments();
+   QCOMPARE(deleteArgs.size(), 1);
+   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one. +   promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
+   QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
 +
+   // dismiss the prompt and wait for the result.
+   prompt = new ClientPrompt(promptPath);
+   prompt->dismissAndWait(5000);
+   QVERIFY(prompt->completed());
+   QVERIFY(prompt->dismissed());
+   delete prompt;
+
+   // retry and complete the prompt this time
+   deleteReply = ifaceCollection.call(QDBus::Block, "Delete");
+   QCOMPARE(deleteReply.type(), QDBusMessage::ReplyMessage);
+   deleteArgs = deleteReply.arguments();
+   QCOMPARE(deleteArgs.size(), 1);
+   QCOMPARE(deleteArgs.at(0).userType(), qMetaTypeId<QDBusObjectPath>());
+   // TempBlockingCollection is blocking, so the output (prompt) should be a valid \
one. +   promptPath = deleteArgs.at(0).value<QDBusObjectPath>();
+   QVERIFY(promptPath.path().startsWith(QLatin1String("/org/freedesktop/secrets/prompts/")));
 +   prompt = new ClientPrompt(promptPath);
+   prompt->promptAndWait(5000);
+   QVERIFY(prompt->completed());
+   QVERIFY(!prompt->dismissed());
+   delete prompt;
+
+   // make sure the collection is gone
+   QCOMPARE(ifaceCollection.call("Introspect").type(), QDBusMessage::ErrorMessage);
+
+   // make sure the CollectionDeleted signal was sent
+   if (deletedSpy.size() < 1) {
+      deletedSpy.waitForSignal(5000);
+   }
+   QCOMPARE(deletedSpy.size(), 1);
+   QCOMPARE(deletedSpy.takeFirst(), collectionPath);
+
+   // close the session
+   QDBusInterface("org.freedesktop.Secret", sessionPath.path()).call("Close");
+}
+
+void ServiceTest::blockingItem()
+{
+   // TODO: test
+}
+
+void ServiceTest::cleanupTestCase()
+{
+   delete m_service;
+   delete m_master;
+
+   QCA::deinit();
+}
+
+QTEST_KDEMAIN_CORE(ServiceTest)
+
+ObjectPathSignalSpy::ObjectPathSignalSpy(QDBusAbstractInterface *iface,
+                                         const char *signal)
+{
+   m_valid = connect(iface, signal, SLOT(slotReceived(QDBusObjectPath)));
+}
+
+bool ObjectPathSignalSpy::isValid() const
+{
+   return m_valid;
+}
+
+void ObjectPathSignalSpy::waitForSignal(int time)
+{
+   waitForSignals(1, time);
+}
+
+void ObjectPathSignalSpy::waitForSignals(int num, int time)
+{
+   m_numWaiting = num;
+   if (count() < m_numWaiting)
+   {
+      QEventLoop loop;
+      loop.connect(this, SIGNAL(doneWaiting()), SLOT(quit()));
+      QTimer::singleShot(time, &loop, SLOT(quit()));
+      loop.exec();
+   }
+}
+
+void ObjectPathSignalSpy::slotReceived(const QDBusObjectPath &objectPath)
+{
+   append(objectPath);
+   if (count() >= m_numWaiting) {
+      emit doneWaiting();
+   }
+}
+
+ClientPrompt::ClientPrompt(QDBusObjectPath promptPath)
+ : m_completed(false), m_dismissed(false),
+   m_interface("org.freedesktop.Secret", promptPath.path())
+{
+   Q_ASSERT(m_interface.isValid());
+   connect(&m_interface, SIGNAL(Completed(bool, QDBusVariant)),
+                         SLOT(slotCompleted(bool, QDBusVariant)));
+}
+
+void ClientPrompt::promptAndWait(int time)
+{
+   QDBusMessage reply = m_interface.call(QDBus::Block, "Prompt", QString(""));
+   Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
+   justWait(time);
+}
+
+void ClientPrompt::dismissAndWait(int time)
+{
+   QDBusMessage reply = m_interface.call(QDBus::Block, "Dismiss");
+   Q_ASSERT(reply.type() == QDBusMessage::ReplyMessage);
+   justWait(time);
+}
+
+void ClientPrompt::slotCompleted(bool dismissed, const QDBusVariant &result)
+{
+   m_completed = true;
+   m_dismissed = dismissed;
+   m_result = result.variant();
+   m_loop.quit();
+}
+
+void ClientPrompt::justWait(int time)
+{
+   if (time > 0) {
+      QTimer::singleShot(time, &m_loop, SLOT(quit()));
+   }
+   m_loop.exec();
+}
+
+#include "servicetest.moc"
diff --git a/frontend/tests/servicetest.h b/frontend/tests/servicetest.h
new file mode 100644
index 0000000..4f9dbb3
--- /dev/null
+++ b/frontend/tests/servicetest.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SERVICETEST_H
+#define SERVICETEST_H
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QVariant>
+#include <QtCore/QEventLoop>
+#include <QtDBus/QDBusVariant>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusInterface>
+
+class BackendMaster;
+class TemporaryCollectionManager;
+class TempBlockingCollectionManager;
+class Service;
+class QDBusAbstractInterface;
+
+/**
+ * Unit-test for the fd.o Secret daemon
+ */
+class ServiceTest : public QObject
+{
+   Q_OBJECT
+
+private:
+   BackendMaster *m_master;
+   TemporaryCollectionManager *m_tempCollMan;
+   TempBlockingCollectionManager *m_tempBlockCollMan;
+   Service *m_service;
+
+private Q_SLOTS:
+   // create services and collections needed for testing
+   void initTestCase();
+
+   // check if Service is registered with D-Bus
+   void dbusService();
+
+   // open various sessions, make sure they are available on the bus, then close \
them. +   void session();
+
+   // create and remove collections
+   void nonBlockingCollection();
+   
+   // create and remove items
+   void nonBlockingItem();
+
+   // change some of the parameters of the testcase needed for the tests to come
+   void reInitTestCase();
+   
+   // create and remove blocking collections
+   void blockingCollection();
+
+   // create and remove blocking items
+   void blockingItem();
+
+   // cleanup
+   void cleanupTestCase();
+};
+
+/**
+ * Listens to D-Bus signals which only have an object-path
+ * as only argument.
+ */
+class ObjectPathSignalSpy : public QObject, public QList<QDBusObjectPath>
+{
+   Q_OBJECT
+
+public:
+   // constructor. similar to QSignalSpy's constructor.
+   ObjectPathSignalSpy(QDBusAbstractInterface *iface, const char *signal);
+   
+   // return true if the connection to the signal was successful
+   bool isValid() const;
+   
+   // wait a specified number of ms for the signal to be received.
+   void waitForSignal(int time);
+   
+   // wait a specified number of ms for multiple signals to be received
+   void waitForSignals(int num, int time);
+
+Q_SIGNALS:
+   // stop waiting for the signal.
+   void doneWaiting();
+   
+private Q_SLOTS:
+   // Single slot which receives all of the various signals.
+   void slotReceived(const QDBusObjectPath &objectPath);
+   
+private:
+   bool m_valid;
+   int m_numWaiting;
+};
+
+/**
+ * Client mini-stub for org.freedesktop.Secret.Prompt.
+ */
+class ClientPrompt : public QObject
+{
+   Q_OBJECT
+
+public:
+   // constructor. wraps around the prompt at promptPath.
+   ClientPrompt(QDBusObjectPath promptPath);
+
+   // Call the Prompt method and wait some time for completion
+   // (sends bogus window-id)
+   void promptAndWait(int time);
+
+   // Call the Dismiss method and wait some time for completion
+   void dismissAndWait(int time);
+
+   // check if the call has been completed
+   bool completed() const {
+      return m_completed;
+   }
+
+   // check if the call was dismissed
+   bool dismissed() const {
+      return m_dismissed;
+   }
+
+   // get the call's result
+   const QVariant &result() const {
+      return m_result;
+   }
+
+private Q_SLOTS:
+   // listens for Completed signals of the D-Bus prompt.
+   void slotCompleted(bool dismissed, const QDBusVariant &result);
+
+private:
+   // just wait (called by *AndWait methods)
+   void justWait(int time);
+   
+   bool m_completed;
+   bool m_dismissed;
+   QVariant m_result;
+   QDBusInterface m_interface;
+   QEventLoop m_loop;
+};
+
+#endif
diff --git a/frontend/tests/tempblockingcollection.cpp \
b/frontend/tests/tempblockingcollection.cpp new file mode 100644
index 0000000..8169aaa
--- /dev/null
+++ b/frontend/tests/tempblockingcollection.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingcollection.h"
+#include "tempblockingitem.h"
+#include "tempblockingjobs.h"
+
+#include <secrettool.h>
+
+TempBlockingCollection::TempBlockingCollection(const QString &id, \
BackendCollectionManager *parent) + : BackendCollection(parent)
+{
+   m_id = id;
+   QDateTime now = QDateTime::currentDateTime();
+   m_created = now;
+   m_modified = now;
+}
+
+TempBlockingCollection::~TempBlockingCollection()
+{
+}
+
+QString TempBlockingCollection::id() const
+{
+   return m_id;
+}
+
+BackendReturn<QString> TempBlockingCollection::label() const
+{
+   return m_label;
+}
+
+BackendReturn<void> TempBlockingCollection::setLabel(const QString &label)
+{
+   m_label = label;
+   emit collectionChanged(this);
+   return BackendReturn<void>();
+}
+
+QDateTime TempBlockingCollection::created() const
+{
+   return m_created;
+}
+
+QDateTime TempBlockingCollection::modified() const
+{
+   return m_modified;
+}
+
+bool TempBlockingCollection::isLocked() const
+{
+   return false;
+}
+
+BackendReturn<QList<BackendItem*> > TempBlockingCollection::items() const
+{
+   return m_items;
+}
+
+BackendReturn<QList<BackendItem*> > TempBlockingCollection::searchItems(
+   const QMap<QString, QString> &attributes) const
+{
+   TempBlockingItem *titem;
+   QList<BackendItem*> foundItems;
+   Q_FOREACH(BackendItem *item, m_items) {
+      titem = qobject_cast<TempBlockingItem*>(item);
+      if (titem && titem->matches(attributes)) {
+         foundItems.append(item);
+      }
+   }
+   return foundItems;
+}
+
+UnlockCollectionJob *TempBlockingCollection::createUnlockJob()
+{
+   return new TempBlockingUnlockCollectionJob(this);
+}
+
+LockCollectionJob *TempBlockingCollection::createLockJob()
+{
+   return new TempBlockingLockCollectionJob(this);
+}
+
+DeleteCollectionJob *TempBlockingCollection::createDeleteJob()
+{
+   TempBlockingDeleteCollectionJob *job = new TempBlockingDeleteCollectionJob(this);
+   connect(job, SIGNAL(result(QueuedJob*)),
+                SLOT(deleteCollectionJobResult(QueuedJob*)));
+   return job;
+}
+
+CreateItemJob *TempBlockingCollection::createCreateItemJob(const QString &label,
+                                                           const QMap<QString, \
QString> &attributes, +                                                           \
const QCA::SecureArray &secret, +                                                     \
bool locked, bool replace) +{
+   return new TempBlockingCreateItemJob(label, attributes, secret, locked, replace, \
this); +}
+
+ChangeAuthenticationCollectionJob \
*TempBlockingCollection::createChangeAuthenticationJob() +{
+   return new TempBlockingChangeAuthenticationCollectionJob(this);
+}
+
+BackendReturn<BackendItem*> TempBlockingCollection::createItem(const QString &label,
+                                                               const QMap<QString, \
QString> &attributes, +                                                               \
const QCA::SecureArray &secret, +                                                     \
bool locked, bool replace) +{
+   Q_UNUSED(locked);
+
+   TempBlockingItem *item = 0;
+   bool replacing = false;
+
+   // check for duplicates
+   BackendReturn<QList<BackendItem*> > foundItems = searchItems(attributes);
+   if (!foundItems.isError() && foundItems.value().size() > 0) {
+      QList<BackendItem*> oldlist = foundItems.value();
+      Q_FOREACH(BackendItem* olditem, oldlist) {
+         if (olditem->attributes().value() == attributes) {
+            if (replace) {
+               // replacing an existing item
+               item = qobject_cast<TempBlockingItem*>(olditem);
+               replacing = true;
+            } else {
+               // item existing but should not be replaced
+               return BackendReturn<BackendItem*>(0, ErrorAlreadyExists);
+            }
+            break;
+         }
+      }
+   }
+
+   if (!item) {
+      item = new TempBlockingItem(createId(), this);
+   }
+   item->blockSignals(true);
+   item->setLabel(label);
+   item->setAttributes(attributes);
+   item->setSecret(secret);
+   item->blockSignals(false);
+
+   if (replacing) {
+      emit itemChanged(item);
+   } else {
+      m_items.append(item);
+      // new item, signals need to be wired
+      connect(item, SIGNAL(itemDeleted(BackendItem*)), \
SLOT(slotItemDeleted(BackendItem*))); +      connect(item, \
SIGNAL(itemChanged(BackendItem*)), SIGNAL(itemChanged(BackendItem*))); +      emit \
itemCreated(item); +   }
+
+   return item;
+}
+
+void TempBlockingCollection::slotItemDeleted(BackendItem *item)
+{
+   m_items.removeAll(item);
+   emit itemDeleted(item);
+}
+
+void TempBlockingCollection::deleteCollectionJobResult(QueuedJob *job)
+{
+   TempBlockingDeleteCollectionJob * dcj = \
qobject_cast<TempBlockingDeleteCollectionJob*>(job); +   Q_ASSERT(dcj);
+   if (!dcj->result()) {
+      return;
+   }
+   emit collectionDeleted(this);
+}
+
+#include "tempblockingcollection.moc"
diff --git a/frontend/tests/tempblockingcollection.h \
b/frontend/tests/tempblockingcollection.h new file mode 100644
index 0000000..7a71c2b
--- /dev/null
+++ b/frontend/tests/tempblockingcollection.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGCOLLECTION_H
+#define TEMPBLOCKINGCOLLECTION_H
+
+#include "backend/backendcollection.h"
+
+// implement a temporary collection that blocks every call.
+class TempBlockingCollection : public BackendCollection
+{
+   Q_OBJECT
+
+public:
+   TempBlockingCollection(const QString &id, BackendCollectionManager *parent);
+   virtual ~TempBlockingCollection();
+   virtual QString id() const;
+   virtual BackendReturn<QString> label() const;
+   virtual BackendReturn<void> setLabel(const QString &label);
+   virtual QDateTime created() const;
+   virtual QDateTime modified() const;
+   virtual bool isLocked() const;
+   virtual BackendReturn<QList<BackendItem*> > items() const;
+   virtual BackendReturn<QList<BackendItem*> > searchItems(const QMap<QString, \
QString> &attributes) const; +   virtual UnlockCollectionJob *createUnlockJob();
+   virtual LockCollectionJob *createLockJob();
+   virtual DeleteCollectionJob *createDeleteJob();
+   virtual CreateItemJob *createCreateItemJob(const QString &label,
+                                              const QMap<QString, QString> \
&attributes, +                                              const QCA::SecureArray \
&secret, bool locked, +                                              bool replace);
+   virtual ChangeAuthenticationCollectionJob *createChangeAuthenticationJob();
+
+protected:
+   BackendReturn<BackendItem*> createItem(const QString &label,
+                                          const QMap<QString, QString> &attributes,
+                                          const QCA::SecureArray &secret, bool \
locked, +                                          bool replace);
+
+private Q_SLOTS:
+   void slotItemDeleted(BackendItem *item);
+   void deleteCollectionJobResult(QueuedJob *job);
+
+private:
+   friend class TempBlockingCreateItemJob;
+   
+   QString m_id;
+   QString m_label;
+   QDateTime m_created;
+   QDateTime m_modified;
+
+   QList<BackendItem*> m_items;
+};
+
+#endif
diff --git a/frontend/tests/tempblockingcollectionmanager.cpp \
b/frontend/tests/tempblockingcollectionmanager.cpp new file mode 100644
index 0000000..3c57fad
--- /dev/null
+++ b/frontend/tests/tempblockingcollectionmanager.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingcollectionmanager.h"
+#include "tempblockingcollection.h"
+#include "tempblockingjobs.h"
+
+#include <secrettool.h>
+
+TempBlockingCollectionManager::TempBlockingCollectionManager(QObject *parent)
+ : BackendCollectionManager(parent)
+{
+}
+
+TempBlockingCollectionManager::~TempBlockingCollectionManager()
+{
+}
+
+CreateCollectionJob *TempBlockingCollectionManager::createCreateCollectionJob(const \
QString &label, +                                                                     \
bool locked) +{
+   TempBlockingCreateCollectionJob *job = new TempBlockingCreateCollectionJob(label,
+                                                                              \
locked, +                                                                             \
this); +   connect(job, SIGNAL(result(QueuedJob*)),
+                SLOT(createCollectionJobResult(QueuedJob*)));
+   return job;
+}
+
+void TempBlockingCollectionManager::createCollectionJobResult(QueuedJob *job)
+{
+   CreateCollectionJob *ccj = qobject_cast<CreateCollectionJob*>(job);
+   Q_ASSERT(ccj);
+   
+   if (!ccj->collection()) {
+      return;
+   }
+   
+   // connect signals
+   connect(ccj->collection(), SIGNAL(collectionDeleted(BackendCollection*)),
+                              SIGNAL(collectionDeleted(BackendCollection*)));
+   emit collectionCreated(ccj->collection());
+}
+
+#include "tempblockingcollectionmanager.moc"
diff --git a/frontend/tests/tempblockingcollectionmanager.h \
b/frontend/tests/tempblockingcollectionmanager.h new file mode 100644
index 0000000..4272d29
--- /dev/null
+++ b/frontend/tests/tempblockingcollectionmanager.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGCOLLECTIONMANAGER_H
+#define TEMPBLOCKINGCOLLECTIONMANAGER_H
+
+#include "backend/backendcollectionmanager.h"
+
+class TempBlockingCollection;
+
+// implement a temporary collection manager that blocks every call.
+class TempBlockingCollectionManager : public BackendCollectionManager
+{
+   Q_OBJECT
+
+public:
+   friend class TempBlockingCollection;
+
+public:
+   TempBlockingCollectionManager(QObject *parent = 0);
+   virtual ~TempBlockingCollectionManager();
+   virtual CreateCollectionJob *createCreateCollectionJob(const QString &label,
+                                                          bool locked);
+                                                          
+private Q_SLOTS:
+   void createCollectionJobResult(QueuedJob *job);
+};
+
+#endif
diff --git a/frontend/tests/tempblockingitem.cpp \
b/frontend/tests/tempblockingitem.cpp new file mode 100644
index 0000000..b819bd3
--- /dev/null
+++ b/frontend/tests/tempblockingitem.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingitem.h"
+#include "tempblockingcollection.h"
+#include "tempblockingjobs.h"
+
+TempBlockingItem::TempBlockingItem(const QString &id, TempBlockingCollection \
*parent) + : BackendItem(parent), m_id(id)
+{
+   QDateTime now = QDateTime::currentDateTime();
+   m_created = now;
+   m_modified = now;
+}
+
+TempBlockingItem::~TempBlockingItem()
+{
+}
+
+QString TempBlockingItem::id() const
+{
+   return m_id;
+}
+
+BackendReturn<QString> TempBlockingItem::label() const
+{
+   return m_label;
+}
+
+BackendReturn<void> TempBlockingItem::setLabel(const QString &label)
+{
+   m_label = label;
+   markAsModified();
+   return BackendReturn<void>();
+}
+
+BackendReturn<QCA::SecureArray> TempBlockingItem::secret() const
+{
+   return m_secret;
+}
+
+BackendReturn<void> TempBlockingItem::setSecret(const QCA::SecureArray &secret)
+{
+   m_secret = secret;
+   markAsModified();
+   return BackendReturn<void>();
+}
+
+BackendReturn<QMap<QString, QString> > TempBlockingItem::attributes() const
+{
+   return m_attributes;
+}
+
+BackendReturn<void> TempBlockingItem::setAttributes(const QMap<QString, QString> \
&attributes) +{
+   m_attributes = attributes;
+   markAsModified();
+   return BackendReturn<void>();
+}
+
+QDateTime TempBlockingItem::created() const
+{
+   return m_created;
+}
+
+QDateTime TempBlockingItem::modified() const
+{
+   return m_modified;
+}
+
+bool TempBlockingItem::isLocked() const
+{
+   return false;
+}
+
+UnlockItemJob *TempBlockingItem::createUnlockJob()
+{
+   return new TempBlockingUnlockItemJob(this);
+}
+
+LockItemJob *TempBlockingItem::createLockJob()
+{
+   return new TempBlockingLockItemJob(this);
+}
+
+DeleteItemJob *TempBlockingItem::createDeleteJob()
+{
+   TempBlockingDeleteItemJob *job = new TempBlockingDeleteItemJob(this);
+   connect(job, SIGNAL(result(QueuedJob*)), SLOT(deleteItemJobResult(QueuedJob*)));
+   return job;
+}
+
+ChangeAuthenticationItemJob *TempBlockingItem::createChangeAuthenticationJob()
+{
+   return new TempBlockingChangeAuthenticationItemJob(this);
+}
+
+bool TempBlockingItem::matches(const QMap<QString, QString> &attributes)
+{
+   QMap<QString, QString>::const_iterator it = attributes.constBegin();
+   QMap<QString, QString>::const_iterator end = attributes.constEnd();
+   for ( ; it != end; ++it) {
+      if (!m_attributes.contains(it.key()) ||
+          m_attributes.value(it.key()) != it.value()) {
+         return false;
+      }
+   }
+   
+   return true;
+}
+
+void TempBlockingItem::deleteItemJobResult(QueuedJob *job)
+{
+   TempBlockingDeleteItemJob *dij = qobject_cast<TempBlockingDeleteItemJob*>(job);
+   Q_ASSERT(dij);
+   if (!dij->result()) {
+      return;
+   }
+   emit itemDeleted(this);
+}
+
+void TempBlockingItem::markAsModified()
+{
+   m_modified = QDateTime::currentDateTime();
+   emit itemChanged(this);
+}
+
+#include "tempblockingitem.moc"
diff --git a/frontend/tests/tempblockingitem.h b/frontend/tests/tempblockingitem.h
new file mode 100644
index 0000000..1b16a0c
--- /dev/null
+++ b/frontend/tests/tempblockingitem.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGITEM_H
+#define TEMPBLOCKINGITEM_H
+
+#include "backend/backenditem.h"
+
+class TempBlockingCollection;
+
+// temporary item that blocks every call
+class TempBlockingItem : public BackendItem
+{
+   Q_OBJECT
+
+public:
+   friend class TempBlockingCollection;
+
+   TempBlockingItem(const QString &id, TempBlockingCollection *parent);
+   ~TempBlockingItem();
+   virtual QString id() const;
+   virtual BackendReturn<QString> label() const;
+   virtual BackendReturn<void> setLabel(const QString &label);
+   virtual BackendReturn<QCA::SecureArray> secret() const;
+   virtual BackendReturn<void> setSecret(const QCA::SecureArray &secret);
+   virtual BackendReturn<QMap<QString, QString> > attributes() const;
+   virtual BackendReturn<void> setAttributes(const QMap<QString, QString> \
&attributes); +   virtual QDateTime created() const;
+   virtual QDateTime modified() const;
+   virtual bool isLocked() const;
+   virtual UnlockItemJob *createUnlockJob();
+   virtual LockItemJob *createLockJob();
+   virtual DeleteItemJob *createDeleteJob();
+   virtual ChangeAuthenticationItemJob *createChangeAuthenticationJob();
+   bool matches(const QMap<QString, QString> &attributes);
+   
+private Q_SLOTS:
+   void deleteItemJobResult(QueuedJob *job);
+   
+private:
+   void markAsModified();
+   
+   QString m_id;
+   QString m_label;
+   QDateTime m_created;
+   QDateTime m_modified;
+   QMap<QString, QString> m_attributes;
+   
+   QCA::SecureArray m_secret;
+};
+
+#endif
diff --git a/frontend/tests/tempblockingjobs.cpp \
b/frontend/tests/tempblockingjobs.cpp new file mode 100644
index 0000000..47382e2
--- /dev/null
+++ b/frontend/tests/tempblockingjobs.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tempblockingjobs.h"
+
+#include <secrettool.h>
+
+#include <QtCore/QTimer>
+
+TempBlockingCreateCollectionJob::TempBlockingCreateCollectionJob(const QString \
&label, bool locked, +                                                                \
TempBlockingCollectionManager *manager) + : CreateCollectionJob(label, locked, \
manager) +{
+}
+
+void TempBlockingCreateCollectionJob::perform()
+{
+   TempBlockingCollection *coll = new TempBlockingCollection(createId(), manager());
+   coll->setLabel(label());
+   
+   setCollection(coll);
+   emitResult();
+}
+
+TempBlockingUnlockCollectionJob::TempBlockingUnlockCollectionJob(BackendCollection* \
coll) + : UnlockCollectionJob(coll)
+{
+}
+
+void TempBlockingUnlockCollectionJob::perform()
+{
+   setResult(true);
+   emitResult();
+}
+
+TempBlockingLockCollectionJob::TempBlockingLockCollectionJob(BackendCollection* \
coll) + : LockCollectionJob(coll)
+{
+}
+
+void TempBlockingLockCollectionJob::perform()
+{
+   setError(ErrorNotSupported);
+   setResult(false);
+   emitResult();
+}
+
+TempBlockingDeleteCollectionJob::TempBlockingDeleteCollectionJob(BackendCollection* \
coll) + : DeleteCollectionJob(coll)
+{
+}
+
+void TempBlockingDeleteCollectionJob::perform()
+{
+   setResult(true);
+   collection()->deleteLater();
+   emitResult();
+}
+
+TempBlockingChangeAuthenticationCollectionJob::TempBlockingChangeAuthenticationCollectionJob(BackendCollection* \
coll) + : ChangeAuthenticationCollectionJob(coll)
+{
+}
+
+void TempBlockingChangeAuthenticationCollectionJob::perform()
+{
+   setError(ErrorNotSupported);
+   setResult(false);
+   emitResult();
+}
+
+TempBlockingCreateItemJob::TempBlockingCreateItemJob(const QString& label,
+                                                     const QMap< QString, QString >& \
attributes, +                                                     const \
QCA::SecureArray& secret, bool locked, +                                              \
bool replace, +                                                     \
TempBlockingCollection* collection) + : CreateItemJob(label, attributes, secret, \
locked, replace, collection), +   m_tempColl(collection)
+{
+}
+
+void TempBlockingCreateItemJob::perform()
+{
+   BackendReturn<BackendItem*> rc = m_tempColl->createItem(label(), attributes(),
+                                                           secret(), locked(),
+                                                           replace());
+                                                           
+   if (rc.isError()) {
+      setError(rc.error(), rc.errorMessage());
+   } else {
+      setItem(rc.value());
+   }
+   emitResult();
+}
+
+TempBlockingUnlockItemJob::TempBlockingUnlockItemJob(BackendItem* item)
+ : UnlockItemJob(item)
+{
+}
+
+void TempBlockingUnlockItemJob::perform()
+{
+   setResult(true);
+   emitResult();
+}
+
+TempBlockingLockItemJob::TempBlockingLockItemJob(BackendItem* item)
+ : LockItemJob(item)
+{
+}
+
+void TempBlockingLockItemJob::perform()
+{
+   setError(ErrorNotSupported);
+   setResult(false);
+   emitResult();
+}
+
+TempBlockingDeleteItemJob::TempBlockingDeleteItemJob(BackendItem* item)
+ : DeleteItemJob(item)
+{
+}
+
+void TempBlockingDeleteItemJob::perform()
+{
+   setResult(true);
+   item()->deleteLater();
+   emitResult();
+}
+
+TempBlockingChangeAuthenticationItemJob::TempBlockingChangeAuthenticationItemJob(BackendItem* \
item) + : ChangeAuthenticationItemJob(item)
+{
+}
+
+void TempBlockingChangeAuthenticationItemJob::perform()
+{
+   setError(ErrorNotSupported);
+   setResult(false);
+   emitResult();
+}
+
+#include "tempblockingjobs.moc"
diff --git a/frontend/tests/tempblockingjobs.h b/frontend/tests/tempblockingjobs.h
new file mode 100644
index 0000000..bf04014
--- /dev/null
+++ b/frontend/tests/tempblockingjobs.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEMPBLOCKINGJOBS_H
+#define TEMPBLOCKINGJOBS_H
+
+#include "tempblockingcollectionmanager.h"
+#include "tempblockingcollection.h"
+#include "tempblockingitem.h"
+
+#include <QtCore/QTimer>
+
+class TempBlockingCreateCollectionJob : public CreateCollectionJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingCreateCollectionJob(const QString &label, bool locked,
+                                   TempBlockingCollectionManager *manager);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+   
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingUnlockCollectionJob : public UnlockCollectionJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingUnlockCollectionJob(BackendCollection *coll);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+   
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingDeleteCollectionJob : public DeleteCollectionJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingDeleteCollectionJob(BackendCollection *coll);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingLockCollectionJob : public LockCollectionJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingLockCollectionJob(BackendCollection *coll);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingChangeAuthenticationCollectionJob : public \
ChangeAuthenticationCollectionJob +{
+   Q_OBJECT
+   
+public:
+   TempBlockingChangeAuthenticationCollectionJob(BackendCollection *coll);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingCreateItemJob : public CreateItemJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingCreateItemJob(const QString &label, const QMap<QString, QString> \
&attributes, +                             const QCA::SecureArray &secret, bool \
locked, bool replace, +                             TempBlockingCollection \
*collection); +   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+   
+private:
+   TempBlockingCollection* m_tempColl;
+};
+
+class TempBlockingUnlockItemJob : public UnlockItemJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingUnlockItemJob(BackendItem *item);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingLockItemJob : public LockItemJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingLockItemJob(BackendItem *item);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingDeleteItemJob : public DeleteItemJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingDeleteItemJob(BackendItem *item);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+class TempBlockingChangeAuthenticationItemJob : public ChangeAuthenticationItemJob
+{
+   Q_OBJECT
+   
+public:
+   TempBlockingChangeAuthenticationItemJob(BackendItem *item);
+   virtual bool isImmediate() const { return false; }
+   virtual void exec() { Q_ASSERT(false); }
+   virtual void start() { QTimer::singleShot(0, this, SLOT(perform())); }
+
+private Q_SLOTS:
+   void perform();
+};
+
+#endif
diff --git a/main.cpp b/main.cpp
index 0d9dd92..3088e10 100644
--- a/main.cpp
+++ b/main.cpp
@@ -27,7 +27,7 @@
 
 #include "backend/backendmaster.h"
 #include "backend/temporary/temporarycollectionmanager.h"
-#include "daemon/service.h"
+#include "frontend/secret/service.h"
 
 int main(int argc, char **argv)
 {
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
new file mode 100644
index 0000000..fdf1d61
--- /dev/null
+++ b/ui/CMakeLists.txt
@@ -0,0 +1,10 @@
+INCLUDE_DIRECTORIES (${CMAKE_CURRENT_SOURCE_DIR})
+ADD_SUBDIRECTORY (tests)
+
+SET (ksecretservice_ui_SRCS
+   abstractuijobs.cpp
+   dialoguifactory.cpp
+)
+
+KDE4_ADD_LIBRARY (ksecretserviceui STATIC ${ksecretservice_ui_SRCS})
+TARGET_LINK_LIBRARIES (ksecretserviceui ${KDE4_KDEUI_LIBS} ${QCA2_LIBRARIES})
diff --git a/ui/abstractuijobs.cpp b/ui/abstractuijobs.cpp
new file mode 100644
index 0000000..b8304b0
--- /dev/null
+++ b/ui/abstractuijobs.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "abstractuijobs.h"
+#include "abstractuimanager.h"
+
+#include <QtCore/QEventLoop>
+#include <QtCore/QTimer>
+
+AbstractUiJob::AbstractUiJob(AbstractUiManager *manager) : QueuedJob(manager)
+{
+}
+
+AbstractUiJob::~AbstractUiJob()
+{
+}
+
+void AbstractUiJob::exec()
+{
+   Q_ASSERT(false);
+}
+
+AbstractAskPasswordJob::AbstractAskPasswordJob(AbstractUiManager *manager,
+                                               const QString &collection,
+                                               bool secondTry)
+ : AbstractUiJob(manager), m_collection(collection), m_secondTry(secondTry)
+{
+}
+
+AbstractAskPasswordJob::~AbstractAskPasswordJob()
+{
+}
+
+const QString &AbstractAskPasswordJob::collection() const
+{
+   return m_collection;
+}
+
+bool AbstractAskPasswordJob::isSecondTry() const
+{
+   return m_secondTry;
+}
+
+bool AbstractAskPasswordJob::result() const
+{
+   return m_result;
+}
+
+const QCA::SecureArray &AbstractAskPasswordJob::password() const
+{
+   return m_password;
+}
+
+void AbstractAskPasswordJob::setResult(bool result)
+{
+   m_result = result;
+}
+
+void AbstractAskPasswordJob::setPassword(const QCA::SecureArray &password)
+{
+   m_password = password;
+}
+
+#include "abstractuijobs.moc"
diff --git a/ui/abstractuijobs.h b/ui/abstractuijobs.h
new file mode 100644
index 0000000..c9ad9aa
--- /dev/null
+++ b/ui/abstractuijobs.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ABSTRACTUIJOBS_H
+#define ABSTRACTUIJOBS_H
+
+#include <queuedjob.h>
+#include <jobqueue.h>
+
+#include <QtCore/QQueue>
+#include <QtCrypto/QtCrypto>
+#include <kglobal.h>
+#include <kjob.h>
+
+class AbstractUiManager;
+
+/*
+ * Abstract master-class of user interface jobs.
+ */
+class AbstractUiJob : public QueuedJob
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    *
+    * @param manager user interface job manager and parent object
+    */
+   explicit AbstractUiJob(AbstractUiManager *manager);
+   
+   /**
+    * Destructor.
+    */
+   virtual ~AbstractUiJob();
+   
+   /**
+    * Default implementation for user interface jobs. As a ui job can rarely be
+    * run synchronously, exec() crashes.
+    */
+   virtual void exec();
+   
+private:
+   friend class UiJobManager;
+};
+
+/**
+ * Job that asks a user for a password to unlock a collection.
+ */
+class AbstractAskPasswordJob : public AbstractUiJob
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    *
+    * @param manager ui job manager and parent object
+    * @param collection label of the collection that should be opened
+    * @param secondTry set to true if this is not the user's first try to enter
+    *                  the password correctly
+    */
+   AbstractAskPasswordJob(AbstractUiManager *manager, const QString &collection,
+                          bool secondTry);
+
+   /**
+    * Destructor.
+    */
+   virtual ~AbstractAskPasswordJob();
+   
+   /**
+    * Get the label of the collection that's about to be unlocked.
+    */
+   const QString &collection() const;
+   
+   /**
+    * Check whether this is not the user's first try to enter the password.
+    */
+   bool isSecondTry() const;
+   
+   /**
+    * Get the result of the operation.
+    *
+    * @return true if the user entered a password, false if not
+    */
+   bool result() const;
+   
+   /**
+    * Get the password the user entered.
+    *
+    * @return the password entered by the user or an empty array if the user
+    *         didn't enter a password
+    */
+   const QCA::SecureArray &password() const;
+   
+protected:
+   /**
+    * Set the result of the operation.
+    *
+    * @remarks this is used by derived classes
+    * @param result result of the operation
+    */
+   void setResult(bool result);
+   
+   /**
+    * Set the password entered by the user.
+    *
+    * @remarks This is used by derived classes
+    * @param password password entered by the user
+    */
+   void setPassword(const QCA::SecureArray &password);
+   
+private:
+   QString m_collection;         // name of the collection to be unlocked
+   bool m_secondTry;              // true if this is not the first try
+   bool m_result;                // the result of the operation
+   QCA::SecureArray m_password;  // the password entered by the user
+};
+
+#endif
diff --git a/ui/abstractuimanager.h b/ui/abstractuimanager.h
new file mode 100644
index 0000000..24e0d06
--- /dev/null
+++ b/ui/abstractuimanager.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ABSTRACTUIMANAGER_H
+#define ABSTRACTUIMANAGER_H
+
+#include "abstractuijobs.h"
+
+/**
+ * Abstract factory that provides means to create a user interface for the various
+ * backend classes.
+ *
+ * This class can be reimplemented to provide a standard UI, a stripped-down UI
+ * (probably for mobile devices) or even a bogus UI which can be used inside
+ * unit-tests.
+ */
+class AbstractUiManager : public JobQueue 
+{
+public:
+   virtual ~AbstractUiManager()
+   {
+      // TODO: clean-up
+   };
+   
+   /**
+    * Create a job for asking for user's password for unlocking a collection.
+    *
+    * @param collection label of the collection to be unlocked
+    * @param secondTry set to true if the user already entered a wrong password \
before +    * @return a job which can be enqueued to ask the user for the unlock \
password +    */
+   virtual AbstractAskPasswordJob *createAskPasswordJob(const QString &collection,
+                                                        bool secondTry) = 0;
+};
+
+#endif
diff --git a/ui/dialoguifactory.cpp b/ui/dialoguifactory.cpp
new file mode 100644
index 0000000..ae12429
--- /dev/null
+++ b/ui/dialoguifactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dialoguifactory.h"
+
+#include <QtCore/QTimer>
+#include <kpassworddialog.h>
+
+AbstractAskPasswordJob* DialogUiFactory::createAskPasswordJob(const QString& \
collection, +                                                              bool \
secondTry) +{
+   return new DialogAskPasswordJob(this, collection, secondTry);
+}
+
+DialogAskPasswordJob::DialogAskPasswordJob(AbstractUiManager *manager,
+                                           const QString& collection,
+                                           bool secondTry)
+ : AbstractAskPasswordJob(manager, collection, secondTry), m_dialog(0)
+{
+}
+
+DialogAskPasswordJob::~DialogAskPasswordJob()
+{
+}
+
+void DialogAskPasswordJob::start()
+{
+   Q_ASSERT(!m_dialog);
+   // TODO: provide parent widget!
+   m_dialog = new KPasswordDialog;
+   m_dialog->setAttribute(Qt::WA_DeleteOnClose, true);
+   // TODO: needs proper string
+   m_dialog->setPrompt("Collection " + collection() + " wants password.");
+   connect(m_dialog, SIGNAL(finished(int)), this, SLOT(dialogFinished(int)));
+   m_dialog->show();
+}
+
+void DialogAskPasswordJob::dialogFinished(int result)
+{
+   Q_ASSERT(m_dialog);
+   if (result == QDialog::Accepted) {
+      setPassword(QCA::SecureArray(m_dialog->password().toUtf8()));
+      setResult(true);
+   } else {
+      setResult(false);
+   }
+   emitResult();
+}
+
+#include "dialoguifactory.moc"
diff --git a/ui/dialoguifactory.h b/ui/dialoguifactory.h
new file mode 100644
index 0000000..f3c4dc0
--- /dev/null
+++ b/ui/dialoguifactory.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIALOGUIFACTORY_H
+#define DIALOGUIFACTORY_H
+
+#include "abstractuijobs.h"
+#include "abstractuimanager.h"
+
+class KPasswordDialog;
+
+class DialogAskPasswordJob : public AbstractAskPasswordJob
+{
+   Q_OBJECT
+   
+public:
+   /**
+    * Constructor.
+    */
+   DialogAskPasswordJob(AbstractUiManager *manager, const QString& collection, bool \
secondTry); +   
+   /**
+    * Destructor.
+    */
+   ~DialogAskPasswordJob();
+
+   /**
+    * Contains the actual workload of showing the dialog.
+    */
+   virtual void start();
+   
+private Q_SLOTS:
+   /**
+    * Called when the dialog shown is either accepted or rejected.
+    */
+   void dialogFinished(int result);
+   
+private:
+   KPasswordDialog *m_dialog;
+};
+
+/**
+ * Implement AbstractUiFactory to provide a user interface using dialogs.
+ */
+class DialogUiFactory : public AbstractUiManager
+{
+public:
+   /**
+    * Destructor.
+    */
+   virtual ~DialogUiFactory() {};
+   
+   /**
+    * Create a job to ask for a user's password to unlock a collection.
+    */
+   virtual AbstractAskPasswordJob* createAskPasswordJob(const QString& collection,
+                                                        bool secondTry);
+};
+
+#endif
diff --git a/ui/tests/CMakeLists.txt b/ui/tests/CMakeLists.txt
new file mode 100644
index 0000000..4faed32
--- /dev/null
+++ b/ui/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+INCLUDE_DIRECTORIES (${CMAKE_CURRENT_BINARY_DIR})
+
+# involves dialogs, thus not an automatic test
+KDE4_ADD_EXECUTABLE (dialoguifactory_test dialoguifactorytest.cpp)
+TARGET_LINK_LIBRARIES (dialoguifactory_test
+   ksecretservicelib
+   ksecretserviceui
+   ${QT_QTTEST_LIBRARIES}
+   ${KDE4_KDEUI_LIBS}
+)
diff --git a/ui/tests/dialoguifactorytest.cpp b/ui/tests/dialoguifactorytest.cpp
new file mode 100644
index 0000000..73f1a02
--- /dev/null
+++ b/ui/tests/dialoguifactorytest.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dialoguifactorytest.h"
+
+#include <QtCrypto/QtCrypto>
+#include <qtest_kde.h>
+
+#include "../dialoguifactory.h"
+
+void DialogUiFactoryTest::initTestCase()
+{
+   QCA::init();
+}
+
+void DialogUiFactoryTest::testAskPassword()
+{
+   DialogUiFactory fact;
+   
+   // ask for a password (asynchronously)
+   AbstractAskPasswordJob *asyncJob1 = \
fact.createAskPasswordJob("TESTCOLLECTION-ASYNC1", false); +   AbstractAskPasswordJob \
*asyncJob2 = fact.createAskPasswordJob("TESTCOLLECTION-ASYNC2", false); +   \
QEventLoop loop; +   connect(asyncJob2, SIGNAL(result(QueuedJob*)), &loop, \
SLOT(quit())); +   asyncJob1->enqueue();
+   asyncJob2->enqueue();
+   loop.exec();
+}
+
+void DialogUiFactoryTest::cleanupTestCase()
+{
+}
+
+QTEST_KDEMAIN(DialogUiFactoryTest, GUI)
+#include "dialoguifactorytest.moc"
diff --git a/ui/tests/dialoguifactorytest.h b/ui/tests/dialoguifactorytest.h
new file mode 100644
index 0000000..d862ea7
--- /dev/null
+++ b/ui/tests/dialoguifactorytest.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010, Michael Leupold <lemma@confuego.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) 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 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIALOGUIFACTORYTEST_H
+#define DIALOGUIFACTORYTEST_H
+
+#include <QtTest>
+
+class DialogUiFactoryTest : public QObject
+{
+   Q_OBJECT
+   
+private Q_SLOTS:
+   void initTestCase();
+
+   void testAskPassword();
+
+   void cleanupTestCase();
+};
+
+#endif // BACKENDTEST_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic