[meego-commits] 10381: Changes to Trunk/qmf

Rolla Selbak no_reply at build.meego.com
Tue Nov 30 04:30:10 UTC 2010


Hi,
I have made the following changes to qmf in project Trunk. Please review and accept ASAP.

Thank You,
Rolla Selbak

[This message was auto-generated]

---

Request #10381:

  submit:   Trunk:Testing/qmf(r9) -> Trunk/qmf


Message:
    Trunk promotion

State:   new          2010-11-29T20:30:08 rolla
Comment: None



changes files:
--------------
--- qmf.changes
+++ qmf.changes
@@ -0,0 +1,5 @@
+* Fri Nov 26 2010 Fathi Boudra <fathi.boudra at nokia.com> - 1.0.7~2010w46
+- Update to 1.0.7~2010w46 (BMC#10519)
+- Revert CONFIG+=syslog
+- Use ExtraSources to install files
+

old:
----
  qmf-1.0.7~2010w43.tar.gz

new:
----
  qmf-1.0.7~2010w46.tar.gz

spec files:
-----------
--- qmf.spec
+++ qmf.spec
@@ -7,13 +7,13 @@
 
 Name:       qmf
 Summary:    Qt Messaging Framework (QMF)
-Version:    1.0.7~2010w43
+Version:    1.0.7~2010w46
 Release:    1
 Group:      System/Libraries
 License:    LGPLv2.1 with exception or GPLv3
 URL:        http://meego.gitorious.org/meego-middleware/messagingframework
 Source0:    %{name}-%{version}.tar.gz
-Source1:    %{name}.sh
+Source1:    qmf.sh
 Source2:    messageserver.desktop
 Source100:  qmf.yaml
 Patch0:     fix_docs_installation.patch
@@ -188,7 +188,8 @@
 # << build pre
 
 %qmake  \
-    QMF_INSTALL_ROOT=%{_prefix}
+    QMF_INSTALL_ROOT=%{_prefix} \
+    CONFIG+=syslog
 
 make %{?jobs:-j%jobs}
 
@@ -199,12 +200,13 @@
 # >> install pre
 # << install pre
 %qmake_install
+mkdir -p %{buildroot}%{_sysconfdir}/profile.d
+cp -a %{SOURCE1} %{buildroot}%{_sysconfdir}/profile.d
+mkdir -p %{buildroot}%{_sysconfdir}/xdg/autostart
+cp -a %{SOURCE2} %{buildroot}%{_sysconfdir}/xdg/autostart
+
 
 # >> install post
-install -D -p -m 0644 %{_sourcedir}/%{name}.sh \
-%{buildroot}%{_sysconfdir}/profile.d/%{name}.sh
-install -D -p -m 0644 %{_sourcedir}/messageserver.desktop \
-%{buildroot}%{_sysconfdir}/xdg/autostart/messageserver.desktop
 # << install post
 %fdupes  %{buildroot}/%{_includedir}
 

other changes:
--------------

++++++ qmf-1.0.7~2010w43.tar.gz -> qmf-1.0.7~2010w46.tar.gz
--- CHANGES
+++ CHANGES
@@ -1,6 +1,15 @@
 Latest Changes
 ---------------
 
+201045
+  * Fixes: NB#203241 Can't receive/fetch emails
+  * Fixes: NB#189791 Message content preview as metadata
+  * Fixes: NB#203640 Unable to detect whether IMAP server supports IDLE mode or not
+
+201042
+  * Fixes: NB#194441 QMailRetrievalAction::retrieveMessagePart() does not check for already downloaded parts
+  * Fixes: QTSOL-166 Make disable and enabling accounts robust
+
 201041
   * Fixes: NB#167708 IMAP: Message(s) marked as read/unread on Server not updated on Client 
 
--- debian/changelog
+++ debian/changelog
@@ -1,3 +1,27 @@
+qt4-messagingframework (2010W46-0maemo1) unstable; urgency=low
+
+  * Baseline has been changed to upstream tag 2010W46:
+
+  * Fixes: NB#203241 Can't receive/fetch emails
+  * Fixes: NB#189791 Message content preview as metadata
+  * Fixes: NB#203640 Unable to detect whether IMAP server supports IDLE mode or not
+  * Fixes: NB#194441 QMailRetrievalAction::retrieveMessagePart() does not check for already downloaded parts
+  * Fixes: QTSOL-166 Make disable and enabling accounts robust
+
+ -- Sergejs Kovrovs <sergejs.kovrovs at accenture.com>  Thu, 18 Nov 2010 11:46:42 +0200
+
+qt4-messagingframework (2010W43-0maemo3) unstable; urgency=low
+
+  * Relation comparator is added to QMailMessageKey::sender().
+
+ -- Mikhail Pozdnyakov <mikhail.ex.pozdnyakov at teleca.com>  Thu, 11 Nov 2010 15:12:59 +0200
+
+qt4-messagingframework (2010W43-0maemo2) unstable; urgency=low
+
+  * Fixes: NB#199852 -  Mail fetching not started until device reboot or messageserver restart when first account defined through "Service accounts" (on behalf of Mikhael Limanskii)
+
+ -- Mikhail Pozdnyakov <mikhail.ex.pozdnyakov at teleca.com>  Thu, 04 Nov 2010 16:46:28 +0200
+
 qt4-messagingframework (2010W43-0maemo1) unstable; urgency=low
 
   * Fixes: NB#184969 - Email still can be sent and received normally
--- examples/qtmail/app/editaccount.cpp
+++ examples/qtmail/app/editaccount.cpp
@@ -58,6 +58,7 @@
 {
     setObjectName(name);
     setWindowTitle("Edit account");
+    enabledCheckbox->setChecked(true);
 
     QTabWidget* tabWidget = new QTabWidget;
     connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
--- examples/qtmail/app/emailclient.cpp
+++ examples/qtmail/app/emailclient.cpp
@@ -1064,19 +1064,29 @@
     retrievalAccountIds.clear();
 
     if (isSending()) {
-        m_transmitAction->cancelOperation();
+        if ((m_transmitAction->activity() == QMailServiceAction::InProgress)
+            || (m_transmitAction->activity() == QMailServiceAction::Pending)) {
+            m_transmitAction->cancelOperation();
+        }
         setSendingInProgress( false );
     }
     if (isRetrieving()) {
-        m_retrievalAction->cancelOperation();
+        if ((m_retrievalAction->activity() == QMailServiceAction::InProgress)
+            || (m_retrievalAction->activity() == QMailServiceAction::Pending)) {
+            m_retrievalAction->cancelOperation();
+        }
         setRetrievalInProgress( false );
     }
 
-    if (m_flagRetrievalAction && m_flagRetrievalAction->activity() == QMailServiceAction::InProgress) {
+    if (m_flagRetrievalAction
+        && ((m_flagRetrievalAction->activity() == QMailServiceAction::InProgress)
+            || (m_flagRetrievalAction->activity() == QMailServiceAction::Pending))) {
         m_flagRetrievalAction->cancelOperation();
     }
 
-    if (m_exportAction && m_exportAction->activity() == QMailServiceAction::InProgress) {
+    if (m_exportAction
+        && ((m_exportAction->activity() == QMailServiceAction::InProgress)
+            || (m_exportAction->activity() == QMailServiceAction::Pending))) {
         m_exportAction->cancelOperation();
     }
 }
@@ -1312,6 +1322,12 @@
 
 void EmailClient::getAllNewMail()
 {
+    if (isRetrieving()) {
+        QString msg(tr("Cannot synchronize accounts because a synchronize operation is currently in progress"));
+        QMessageBox::warning(0, tr("Synchronize in progress"), msg, tr("OK") );
+        return;
+    }
+
     retrievalAccountIds.clear();
 
     QMailAccountKey retrieveKey(QMailAccountKey::status(QMailAccount::CanRetrieve, QMailDataComparator::Includes));
@@ -1324,6 +1340,12 @@
 
 void EmailClient::getAccountMail()
 {
+    if (isRetrieving()) {
+        QString msg(tr("Cannot synchronize account because a synchronize operation is currently in progress"));
+        QMessageBox::warning(0, tr("Synchronize in progress"), msg, tr("OK") );
+        return;
+    }
+
     retrievalAccountIds.clear();
 
     if (const QAction* action = static_cast<const QAction*>(sender())) {
@@ -1444,7 +1466,7 @@
 
     // Try the next account if we're working through a set of accounts
     if (!retrievalAccountIds.isEmpty())
-        getNextNewMail();
+        QTimer::singleShot(0, this, SLOT(getNextNewMail()));
 
     Q_UNUSED(accountId)
 }
--- examples/qtmail/plugins/viewers/generic/attachmentoptions.cpp
+++ examples/qtmail/plugins/viewers/generic/attachmentoptions.cpp
@@ -505,7 +505,7 @@
             display.setImage(_decodedData);
             display.exec();
         }
-    } else if (_part->contentType().content() == "message/rfc822") {
+    } else if (_part->contentType().content().toLower() == "message/rfc822") {
         QDialog display(this);
         QGridLayout *gl = new QGridLayout(&display);
         GenericViewer *viewer = new GenericViewer(&display);
--- src/libraries/qmfclient/CHANGES.qdoc
+++ src/libraries/qmfclient/CHANGES.qdoc
@@ -134,6 +134,19 @@
 
 38. Remove unintentionally exported QMailId that should not have been included in the public API.
 
+39. Move Location inner class from QMailMessagePart to QMailMessagePartContainer
+
+    Added following functions to QMailMessagePartContainer:
+    'QMailMessagePartContainer* findPlainTextContainer() const'
+    'QMailMessagePartContainer* findHtmlContainer() const'
+    'QList<QMailMessagePartContainer::Location> findAttachmentLocations() const'
+    'bool hasPlainTextBody() const'
+    'bool hasHtmlBody() const'
+    'bool hasAttachments() const'
+    'void setPlainTextBody(const QMailMessageBody& plainTextBody)'
+    'void setHtmlAndPlainTextBody(const QMailMessageBody& htmlBody, const QMailMessageBody& plainTextBody)'
+    'void setAttachments(const QStringList& attachments)'
+    'void setAttachments(const QList<const QMailMessagePart*> attachments)'
 
 
 *****************************************************************************
--- src/libraries/qmfclient/qmailmessage.cpp
+++ src/libraries/qmfclient/qmailmessage.cpp
@@ -3493,7 +3493,7 @@
 }
 
 
-class QMailMessagePart::LocationPrivate
+class QMailMessagePartContainer::LocationPrivate
 {
 public:
     QMailMessageId _messageId;
@@ -5054,7 +5054,7 @@
     Creates an empty part location object.
 */
 QMailMessagePartContainer::Location::Location()
-    : d(new QMailMessagePart::LocationPrivate)
+    : d(new QMailMessagePartContainer::LocationPrivate)
 {
 }
 
@@ -5064,7 +5064,7 @@
     \sa toString()
 */
 QMailMessagePartContainer::Location::Location(const QString& description)
-    : d(new QMailMessagePart::LocationPrivate)
+    : d(new QMailMessagePartContainer::LocationPrivate)
 {
     QString indices;
 
@@ -5089,7 +5089,7 @@
     Creates a part location object containing a copy of \a other.
 */
 QMailMessagePartContainer::Location::Location(const Location& other)
-    : d(new QMailMessagePart::LocationPrivate)
+    : d(new QMailMessagePartContainer::LocationPrivate)
 {
     *this = other;
 }
@@ -5098,7 +5098,7 @@
     Creates a location object containing the location of \a part.
 */
 QMailMessagePartContainer::Location::Location(const QMailMessagePart& part)
-    : d(new QMailMessagePart::LocationPrivate)
+    : d(new QMailMessagePartContainer::LocationPrivate)
 {
     const QMailMessagePartContainerPrivate* partImpl = part.impl<const QMailMessagePartContainerPrivate>();
 
@@ -5804,6 +5804,7 @@
       _listId(""),
       _rfcId(""),
       _responseType(QMailMessage::NoResponse),
+      _preview(""),
       _customFieldsModified(false),
       _dirty(false)
 {
@@ -5963,6 +5964,11 @@
     updateMember(_responseType, type);
 }
 
+void QMailMessageMetaDataPrivate::setPreview(const QString &s)
+{
+    updateMember(_preview, s);
+}
+
 uint QMailMessageMetaDataPrivate::indicativeSize() const
 {
     uint size = (_size / QMailMessageBodyPrivate::IndicativeSizeUnit);
@@ -6083,6 +6089,7 @@
     stream << customFields();
     stream << _customFieldsModified;
     stream << _dirty;
+    stream << _preview;
 }
 
 template <typename Stream> 
@@ -6123,7 +6130,7 @@
     _customFields = customFields;
     stream >> _customFieldsModified;
     stream >> _dirty;
-
+    stream >> _preview;
 }
 
 
@@ -6951,8 +6958,7 @@
 */  
 QString QMailMessageMetaData::preview() const
 {
-    //TODO implement this
-    return QString();
+    return impl(this)->_preview;
 }
 
 /*!
@@ -6962,8 +6968,7 @@
 */
 void QMailMessageMetaData::setPreview(const QString &s)
 {
-    //TODO implement this
-    Q_UNUSED(s)
+    impl(this)->setPreview(s);
 }
 
 /*!
@@ -7904,6 +7909,29 @@
     return; // Normal Priority
 }
 
+static void setMessagePreview(QMailMessage *mail) 
+{
+    const int maxPreviewLength = 280;
+    QMailMessagePartContainer *plainTextContainer = mail->findPlainTextContainer();
+    if (plainTextContainer) {
+        mail->setPreview(plainTextContainer->body().data().left(maxPreviewLength));
+        return;
+    }
+    QMailMessagePartContainer *htmlContainer = mail->findHtmlContainer();
+    if (htmlContainer) {
+        QString markup = htmlContainer->body().data();
+        markup.remove(QRegExp("<\\s*(style|head|form|script)[^<]*<\\s*/\\s*\\1\\s*>", Qt::CaseInsensitive));
+        markup.remove(QRegExp("<(.)[^>]*>"));
+        markup.replace(""", "\"");
+        markup.replace(" ", " ");
+        markup.replace("&", "*");
+        markup.replace("<", "<");
+        markup.replace(">", "<");
+        mail->setPreview(markup.simplified().left(maxPreviewLength));
+        return;
+    }
+}
+
 /*! \internal */
 QMailMessage QMailMessage::fromRfc2822(LongString& ls)
 {
@@ -7925,6 +7953,7 @@
     }
 
     setMessagePriorityFromHeaderFields(&mail);
+    setMessagePreview(&mail);
     return mail;
 }
 
--- src/libraries/qmfclient/qmailmessage_p.h
+++ src/libraries/qmfclient/qmailmessage_p.h
@@ -393,6 +393,8 @@
     void setInResponseTo(const QMailMessageId &id);
     void setResponseType(QMailMessage::ResponseType type);
 
+    void setPreview(const QString &s);
+
     uint indicativeSize() const;
 
     bool dataModified() const;
@@ -438,6 +440,7 @@
 
     QMailMessageId _responseId;
     QMailMessage::ResponseType _responseType;
+    QString _preview;
 
     mutable Maybe< QMap<QString, QString> > _customFields;
     bool _customFieldsModified;
--- src/libraries/qmfclient/qmailmessagekey.cpp
+++ src/libraries/qmfclient/qmailmessagekey.cpp
@@ -482,6 +482,14 @@
 }
 
 /*!
+    Return a key matching messages whose sender is alphabetically
+*/
+QMailMessageKey QMailMessageKey::sender(const QString &value, QMailDataComparator::RelationComparator cmp)
+{
+    return QMailMessageKey(Sender, value, QMailKey::comparator(cmp));
+}
+
+/*!
     Returns a key matching messages whose recipients include \a value, according to \a cmp.
 
     \sa QMailMessage::to(), QMailMessage::cc(), QMailMessage::bcc()
--- src/libraries/qmfclient/qmailmessagekey.h
+++ src/libraries/qmfclient/qmailmessagekey.h
@@ -91,7 +91,8 @@
         CopyServerUid = (1 << 21),
         RestoreFolderId = (1 << 22),
         ListId = (1 << 23),
-        RfcId = (1 << 24)
+        RfcId = (1 << 24),
+        Preview = (1 << 25)
     };
     Q_DECLARE_FLAGS(Properties,Property)
 
@@ -142,6 +143,7 @@
 
     static QMailMessageKey sender(const QString &value, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
     static QMailMessageKey sender(const QString &value, QMailDataComparator::InclusionComparator cmp);
+    static QMailMessageKey sender(const QString &value, QMailDataComparator::RelationComparator cmp);
     static QMailMessageKey sender(const QStringList &values, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
 
     static QMailMessageKey recipients(const QString &value, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
--- src/libraries/qmfclient/qmailmessageserver.cpp
+++ src/libraries/qmfclient/qmailmessageserver.cpp
@@ -764,10 +764,12 @@
 
 /*!
     Requests that the MessageServer cancel any pending search operations for the request identified by \a action.
+
+    This method is obsolete, use cancel transfer instead.
 */
 void QMailMessageServer::cancelSearch(quint64 action)
 {
-    emit d->cancelSearch(action);
+    emit d->cancelTransfer(action);
 }
 
 /*!
--- src/libraries/qmfclient/qmailmessageset.cpp
+++ src/libraries/qmfclient/qmailmessageset.cpp
@@ -1202,11 +1202,11 @@
 {
     if (parentIndex.isValid()) {
         if (QMailMessageSetContainer *parent = itemFromIndex(parentIndex))
-            if (parent->count() > row)
+            if ((parent->count() > row) && (row >= 0))
                 return createIndex(row, column, parent->at(row));
     } else {
         // From the top level
-        if (count() > row)
+        if ((count() > row) && (row >= 0))
             return createIndex(row, column, at(row));
     }
 
--- src/libraries/qmfclient/qmailserviceaction.cpp
+++ src/libraries/qmfclient/qmailserviceaction.cpp
@@ -96,6 +96,7 @@
 
 void QMailServiceActionPrivate::cancelOperation()
 {
+    Q_ASSERT(_action != 0 && _isValid);
     if (_isValid) {
         clearSubActions();
         _server->cancelTransfer(_action);
@@ -1435,22 +1436,14 @@
 
 void QMailSearchActionPrivate::searchMessages(const QMailMessageKey &filter, const QString &bodyText, QMailSearchAction::SearchSpecification spec, const QMailMessageSortKey &sort)
 {
-    if ((spec == QMailSearchAction::Remote) || !bodyText.isEmpty()) {
-        _server->searchMessages(newAction(), filter, bodyText, spec, sort);
-    } else {
-        // An action value is necessary, even if we're not communicating with the server
-        newAction();
-
-        // This search can be performed in the local process
-        _matchingIds = QMailStore::instance()->queryMessages(filter, sort);
-        setActivity(QMailServiceAction::InProgress);
-        QTimer::singleShot(0, this, SLOT(finaliseSearch()));
-    }
+    _server->searchMessages(newAction(), filter, bodyText, spec, sort);
+    emitChanges();
 }
 
 void QMailSearchActionPrivate::cancelOperation()
 {
-    if (_action != 0)
+    Q_ASSERT(_isValid && _action != 0);
+    if (_isValid)
         _server->cancelSearch(_action);
 }
 
--- src/libraries/qmfclient/qmailstore.cpp
+++ src/libraries/qmfclient/qmailstore.cpp
@@ -1207,8 +1207,8 @@
     metaData.setRestoreFolderId(message->restoreFolderId());
     metaData.setRfcId(message->rfcId());
     metaData.setCopyServerUid(message->copyServerUid());
-
     metaData.setStatus(QMailMessage::UnloadedData, true);
+    metaData.setPreview(message->preview());
     metaData.setUnmodified();
 
     return metaData;
--- src/libraries/qmfclient/qmailstore_p.cpp
+++ src/libraries/qmfclient/qmailstore_p.cpp
@@ -325,6 +325,8 @@
     QVariant inResponseTo() const { return _data.inResponseTo().toULongLong(); }
 
     QVariant responseType() const { return static_cast<int>(_data.responseType()); }
+
+    QVariant preview() const { return _data.preview(); }
 };
 
 // Class to extract QMailMessageMetaData properties from QVariant object
@@ -377,6 +379,8 @@
     QString listId() const { return QMailStorePrivate::extractValue<QString>(_value); }
 
     QString rfcId() const { return QMailStorePrivate::extractValue<QString>(_value); }
+
+    QString preview() const { return QMailStorePrivate::extractValue<QString>(_value); }
 };
 
 
@@ -408,6 +412,7 @@
     map.insert(QMailMessageKey::RestoreFolderId, "restorefolderid");
     map.insert(QMailMessageKey::ListId, "listid");
     map.insert(QMailMessageKey::RfcId, "rfcid");
+    map.insert(QMailMessageKey::Preview, "preview");
     return map;
 }
 
@@ -893,6 +898,8 @@
 
     QString rfcId() const { return value<QString>(QMailMessageKey::RfcId); }
 
+    QString preview() const { return value<QString>(QMailMessageKey::Preview); }
+
 private:
     int fieldIndex(const QString &field, QMailMessageKey::Properties props) const
     {
@@ -989,6 +996,8 @@
     QVariantList restoreFolderId() const { return idValues<QMailFolderKey>(); }
 
     QVariantList rfcId() const { return stringValues(); }
+
+    QVariantList preview() const { return stringValues(); }
 };
 
 template<>
@@ -1105,6 +1114,9 @@
     case QMailMessageKey::RfcId:
         values += extractor.rfcId();
         break;
+
+    case QMailMessageKey::Preview:
+        values += extractor.preview();
     }
 }
 
@@ -1688,6 +1700,7 @@
         case QMailMessageKey::ResponseType:
         case QMailMessageKey::ListId:
         case QMailMessageKey::RfcId:
+        case QMailMessageKey::Preview:
             q << expression;
             break;
         }
@@ -2499,7 +2512,8 @@
                                            QMailMessageKey::CopyServerUid |
                                            QMailMessageKey::RestoreFolderId |
                                            QMailMessageKey::ListId |
-                                           QMailMessageKey::RfcId;
+                                           QMailMessageKey::RfcId |
+                                           QMailMessageKey::Preview;
     return p;
 }
 
@@ -2630,7 +2644,7 @@
                                             << tableInfo("mailfolders", 105)
                                             << tableInfo("mailfoldercustom", 100)
                                             << tableInfo("mailfolderlinks", 100)
-                                            << tableInfo("mailmessages", 111)
+                                            << tableInfo("mailmessages", 112)
                                             << tableInfo("mailmessagecustom", 101)
                                             << tableInfo("mailstatusflags", 101)
                                             << tableInfo("mailmessageidentifiers", 101)
@@ -3183,18 +3197,26 @@
             case QMailMessageKey::ResponseType:
                 metaData->setResponseType(messageRecord.responseType());
                 break;
+
             case QMailMessageKey::CopyServerUid:
                 metaData->setCopyServerUid(messageRecord.copyServerUid());
                 break;
-        case QMailMessageKey::RestoreFolderId:
+
+            case QMailMessageKey::RestoreFolderId:
                 metaData->setRestoreFolderId(messageRecord.restoreFolderId());
                 break;
-        case QMailMessageKey::ListId:
+
+            case QMailMessageKey::ListId:
                 metaData->setListId(messageRecord.listId());
                 break;
-        case QMailMessageKey::RfcId:
+
+            case QMailMessageKey::RfcId:
                 metaData->setRfcId(messageRecord.rfcId());
                 break;
+
+            case QMailMessageKey::Preview:
+                metaData->setPreview(messageRecord.preview());
+                break;
         }
     }
     
@@ -3434,6 +3456,10 @@
             case QMailMessageKey::RfcId:
                 values.append(extractor.rfcId());
                 break;
+
+            case QMailMessageKey::Preview:
+                values.append(extractor.preview());
+                break;
         }
     }
 
@@ -3540,15 +3566,23 @@
             case QMailMessageKey::CopyServerUid:
                 metaData.setCopyServerUid(extractor.copyServerUid());
                 break;
+
             case QMailMessageKey::RestoreFolderId:
                 metaData.setRestoreFolderId((extractor.restoreFolderId()));
                 break;
+
             case QMailMessageKey::ListId:
                 metaData.setListId(extractor.listId());
                 break;
+
             case QMailMessageKey::RfcId:
                 metaData.setRfcId(extractor.rfcId());
                 break;
+
+            case QMailMessageKey::Preview:
+                metaData.setPreview(extractor.preview());
+                break;
+
             default:
                 valueConsumed = false;
                 break;
@@ -5214,6 +5248,7 @@
         values.insert("restorefolderid", metaData->restoreFolderId().toULongLong());
         values.insert("listid", metaData->listId());
         values.insert("rfcID", metaData->rfcId());
+        values.insert("preview", metaData->preview());
 
         const QStringList &list(values.keys());
         QString columns = list.join(",");
--- src/libraries/qmfclient/qmf.qrc
+++ src/libraries/qmfclient/qmf.qrc
@@ -28,6 +28,7 @@
         <file alias="mailmessages-108-109">resources/mailmessages-108-109.sqlite.sql</file>
         <file alias="mailmessages-109-110">resources/mailmessages-109-110.sqlite.sql</file>
         <file alias="mailmessages-110-111">resources/mailmessages-110-111.sqlite.sql</file>
+        <file alias="mailmessages-111-112">resources/mailmessages-111-112.sqlite.sql</file>
         <file alias="mailmessagecustom">resources/mailmessagecustom.sqlite.sql</file>
         <file alias="mailmessagecustom-100-101">resources/mailmessagecustom-100-101.sqlite.sql</file>
         <file alias="deletedmessages">resources/deletedmessages.sqlite.sql</file>
--- src/libraries/qmfclient/resources/mailmessages-111-112.sqlite.sql
+++ src/libraries/qmfclient/resources/mailmessages-111-112.sqlite.sql
+ALTER TABLE mailmessages ADD COLUMN preview VARCHAR NOT NULL DEFAULT '';
+
--- src/libraries/qmfclient/resources/mailmessages.sqlite.sql
+++ src/libraries/qmfclient/resources/mailmessages.sqlite.sql
@@ -21,6 +21,7 @@
     restorefolderid INTEGER NOT NULL DEFAULT 0,
     listid VARCHAR NOT NULL DEFAULT '',
     rfcid VARCHAR NOT NULL DEFAULT '',
+    preview VARCHAR NOT NULL DEFAULT '',
     FOREIGN KEY (parentfolderid) REFERENCES mailfolders(id),
     FOREIGN KEY (parentaccountid) REFERENCES mailaccounts(id));
 
--- src/libraries/qmfclient/support/qloggers.h
+++ src/libraries/qmfclient/support/qloggers.h
@@ -327,6 +327,7 @@
     };
 };
 
+#ifndef Q_OS_WIN
 /**********************************************************************************************************/
 /************************************ SysLogger implementation ********************************************/
 /**********************************************************************************************************/
@@ -352,5 +353,6 @@
 {
     closelog();
 };
+#endif // Q_OS_WIN
 
 #endif // QLOGGERS_H
--- src/libraries/qmfmessageserver/qmailauthenticator.cpp
+++ src/libraries/qmfmessageserver/qmailauthenticator.cpp
@@ -120,16 +120,8 @@
 QByteArray QMailAuthenticator::getAuthentication(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QStringList &capabilities)
 {
     QMailServiceConfiguration configuration(svcCfg);
-    if (!configuration.value("smtpusername").isEmpty() 
-        && (configuration.value("authentication") == QString::number(QMail::CramMd5Mechanism))) {
-        // SMTP server CRAM-MD5 authentication
-        foreach(QString capa, capabilities) {
-            capa += " ";
-            if (capa.startsWith("AUTH") && capa.contains(" CRAM-MD5 ")) {
-                return "CRAM-MD5";
-            }
-        }
-    }
+    if (configuration.value("authentication") == QString::number(QMail::CramMd5Mechanism))
+        return "CRAM-MD5";
 
     // Unknown service type and/or authentication type
     return QByteArray();
@@ -151,6 +143,9 @@
         && (configuration.value("authentication") == QString::number(QMail::CramMd5Mechanism))) {
         // SMTP server CRAM-MD5 authentication
         return cramMd5Response(challenge, configuration.value("smtpusername").toUtf8(), QByteArray::fromBase64(configuration.value("smtppassword").toUtf8()));
+    } else if (configuration.value("authentication") == QString::number(QMail::CramMd5Mechanism)) {
+        // IMAP/POP server CRAM-MD5 authentication
+        return cramMd5Response(challenge, configuration.value("username").toUtf8(), QByteArray::fromBase64(configuration.value("password").toUtf8()));
     }
 
     // Unknown service type and/or authentication type
--- src/libraries/qmfmessageserver/qmailmessageservice.cpp
+++ src/libraries/qmfmessageserver/qmailmessageservice.cpp
@@ -829,11 +829,13 @@
 }
 
 /*!
-    Invoked by the message server to initiate a request to stop remote searching.
+    This method is obsolete. It is no longer invoked. QMailMessageService::cancelOperation is used instead.
+
+    Previously was invoked by the message server to initiate a request to stop remote searching.
 
     Searches in progress will be stopped, and no further results returned.
 
-    \sa searchMessages(), matchingMessageIds()
+    \sa QMailMessageService::cancelOperation
 */
 bool QMailMessageSource::cancelSearch()
 {
--- src/plugins/messageservices/imap/imapauthenticator.cpp
+++ src/plugins/messageservices/imap/imapauthenticator.cpp
@@ -46,7 +46,13 @@
 
 #include <qmailauthenticator.h>
 #include <qmailtransport.h>
+#include <qmailnamespace.h>
 
+namespace {
+
+QMap<QMailAccountId, QList<QByteArray> > gResponses;
+
+}
 
 bool ImapAuthenticator::useEncryption(const QMailAccountConfiguration::ServiceConfiguration &svcCfg, const QStringList &capabilities)
 {
@@ -80,6 +86,12 @@
 
     // If not handled by the authenticator, fall back to login
     ImapConfiguration imapCfg(svcCfg);
+    if (imapCfg.mailAuthentication() == QMail::PlainMechanism) {
+        QByteArray username(imapCfg.mailUserName().toAscii());
+        QByteArray password(imapCfg.mailPassword().toAscii());
+        return QByteArray("AUTHENTICATE PLAIN ") + QByteArray(username + '\0' + username + '\0' + password).toBase64();
+    }
+
     return QByteArray("LOGIN") + ' ' + ImapProtocol::quoteString(imapCfg.mailUserName().toAscii())
                                + ' ' + ImapProtocol::quoteString(imapCfg.mailPassword().toAscii());
 }
--- src/plugins/messageservices/imap/imapclient.cpp
+++ src/plugins/messageservices/imap/imapclient.cpp
@@ -671,12 +671,6 @@
                     _session->process(SessionData());
                 } else
                     _protocol.sendLogin(_config);
-
-                if (_protocol.capabilities().contains("QRESYNC")) {
-                    // pipeline enable command
-                    _protocol.sendEnable("QRESYNC CONDSTORE");
-                    _qresyncEnabled = true;
-                }
             }
             break;
         }
@@ -690,12 +684,6 @@
                 _session->process(SessionData());
             } else
                 _protocol.sendLogin(_config);
-
-            if (_protocol.capabilities().contains("QRESYNC")) {
-                // pipeline enable command
-                _protocol.sendEnable("QRESYNC CONDSTORE");
-                _qresyncEnabled = true;
-            }
             break;
         }
         
@@ -715,11 +703,17 @@
             bool supportsReferences(_protocol.capabilities().contains("URLAUTH"));
 
             QMailAccount account(_config.id());
+            ImapConfiguration imapCfg(_config);
             if (((account.status() & QMailAccount::CanReferenceExternalData) && !supportsReferences) ||
-                (!(account.status() & QMailAccount::CanReferenceExternalData) && supportsReferences)) {
+                (!(account.status() & QMailAccount::CanReferenceExternalData) && supportsReferences) ||
+                (imapCfg.pushCapable() != _protocol.supportsCapability("IDLE")) ||
+                (imapCfg.capabilities() != _protocol.capabilities())) {
                 account.setStatus(QMailAccount::CanReferenceExternalData, supportsReferences);
-                if (!QMailStore::instance()->updateAccount(&account)) {
-                    qWarning() << "Unable to update account" << account.id() << "to set CanReferenceExternalData";
+                imapCfg.setPushCapable(_protocol.supportsCapability("IDLE"));
+                imapCfg.setCapabilities(_protocol.capabilities());
+                if ((!QMailStore::instance()->updateAccount(&account)) ||
+                    (!QMailStore::instance()->updateAccount(&account, &_config))) {
+                    qWarning() << "Unable to update account" << account.id() << "to set imap4 configuration";
                 }
             }
 
--- src/plugins/messageservices/imap/imapconfiguration.cpp
+++ src/plugins/messageservices/imap/imapconfiguration.cpp
@@ -78,6 +78,11 @@
     return value("encryption", "0").toInt();
 }
 
+int ImapConfiguration::mailAuthentication() const
+{
+    return value("authentication", "0").toInt();
+}
+
 bool ImapConfiguration::canDeleteMail() const
 {
     return (value("canDelete", "1").toInt() != 0);
@@ -123,6 +128,25 @@
     return (value("intervalCheckRoamingEnabled", "0").toInt() != 0);
 }
 
+QStringList ImapConfiguration::capabilities() const
+{
+    return value("capabilities").split(QChar(' '), QString::SkipEmptyParts);
+}
+
+void ImapConfiguration::setCapabilities(const QStringList &s)
+{
+    setValue("capabilities", QString("") + s.join(QChar(' '))); // can't setValue to null string
+}
+
+bool ImapConfiguration::pushCapable() const
+{
+    return (value("pushCapable", "0").toInt() != 0);
+}
+
+void ImapConfiguration::setPushCapable(bool b)
+{
+    setValue("pushCapable", QString::number(b ? 1 : 0));
+}
 
 ImapConfigurationEditor::ImapConfigurationEditor(QMailAccountConfiguration *config)
     : ImapConfiguration(*config)
@@ -156,6 +180,11 @@
     setValue("encryption", QString::number(t));
 }
 
+void ImapConfigurationEditor::setMailAuthentication(int t)
+{
+    setValue("authentication", QString::number(t));
+}
+
 #endif
 
 void ImapConfigurationEditor::setDeleteMail(bool b)
--- src/plugins/messageservices/imap/imapconfiguration.h
+++ src/plugins/messageservices/imap/imapconfiguration.h
@@ -66,6 +66,7 @@
     QString mailServer() const;
     int mailPort() const;
     int mailEncryption() const;
+    int mailAuthentication() const;
 
     bool canDeleteMail() const;
     bool isAutoDownload() const;
@@ -80,6 +81,11 @@
 
     int checkInterval() const;
     bool intervalCheckRoamingEnabled() const;
+
+    QStringList capabilities() const;
+    void setCapabilities(const QStringList &s);
+    bool pushCapable() const;
+    void setPushCapable(bool b);
 };
 
 class PLUGIN_EXPORT ImapConfigurationEditor : public ImapConfiguration
@@ -93,6 +99,7 @@
     void setMailPort(int i);
 #ifndef QT_NO_OPENSSL
     void setMailEncryption(int t);
+    void setMailAuthentication(int t);
 #endif
 
     void setDeleteMail(bool b);
--- src/plugins/messageservices/imap/imapprotocol.cpp
+++ src/plugins/messageservices/imap/imapprotocol.cpp
@@ -48,6 +48,7 @@
 
 #include <QTemporaryFile>
 #include <QFileInfo>
+#include <QUrl>
 #include <qmaillog.h>
 #include <longstring_p.h>
 #include <qmailaccountconfiguration.h>
@@ -1660,7 +1661,7 @@
         subSearchKeys.append(searchKey);
     }
     if(!subSearchKeys.isEmpty()) {
-        result += (result.isEmpty() ? QString() : QString(' ')) + combine(subSearchKeys, combiner);
+        result += combine(subSearchKeys, combiner);
     }
 
     return result;
@@ -1687,9 +1688,12 @@
 
         return result;
     } else if(combiner == QMailKey::None) {
-        if(searchKeys.count() != 1)
+        if(searchKeys.count() != 1) {
             qWarning() << "Attempting to combine more than thing, without a combiner?";
             return QString();
+        } else {
+            return searchKeys.first();
+        }
     } else {
         qWarning() << "Unable to combine with an unknown combiner: " << combiner;
         return QString();
@@ -2874,7 +2878,6 @@
 void ImapProtocol::sendGenUrlAuth(const QMailMessagePart::Location &location, bool bodyOnly, const QString &mechanism)
 {
     QString dataUrl(url(location, true, bodyOnly));
-    dataUrl.append(";urlauth=anonymous");
 
     _fsm->genUrlAuthState.setUrl(dataUrl, mechanism);
     _fsm->setState(&_fsm->genUrlAuthState);
@@ -3310,19 +3313,19 @@
 
     QMailMessageId id(location.containingMessageId());
     QMailMessageMetaData metaData(id);
+    QMailAccountConfiguration config(metaData.parentAccountId());
+    ImapConfiguration imapCfg(config);
 
     if (metaData.parentAccountId().isValid()) {
         if (absolute) {
             result.append("imap://");
 
-            QMailAccountConfiguration config(metaData.parentAccountId());
-            ImapConfiguration imapCfg(config);
-
             if (!imapCfg.mailUserName().isEmpty()) {
-                result.append(imapCfg.mailUserName()).append('@');
+                result.append(QUrl::toPercentEncoding(imapCfg.mailUserName()));
+                result.append('@');
             }
-
             result.append(imapCfg.mailServer());
+            
             if (imapCfg.mailPort() != 143) {
                 result.append(':').append(QString::number(imapCfg.mailPort()));
             }
@@ -3343,6 +3346,13 @@
         } else if (bodyOnly) {
             result.append("/;section=TEXT");
         }
+        
+        if (!imapCfg.mailUserName().isEmpty()) {
+            result.append(";urlauth=submit+");
+            result.append(QUrl::toPercentEncoding(imapCfg.mailUserName()));
+        } else {
+            qWarning() << "url auth, no user name found";
+        }
     }
 
     return result;
--- src/plugins/messageservices/imap/imapservice.cpp
+++ src/plugins/messageservices/imap/imapservice.cpp
@@ -149,6 +149,8 @@
     void queueFlagsChangedCheck();
 
 private:
+    bool doDelete(const QMailMessageIdList & ids);
+
     virtual bool setStrategy(ImapStrategy *strategy, const char *signal = 0);
 
     virtual void appendStrategy(ImapStrategy *strategy, const char *signal = 0);
@@ -268,6 +270,14 @@
         return false;
     }
 
+    QMailMessage msg(partLocation.containingMessageId());
+    if (!msg.contains(partLocation) || msg.partAt(partLocation).contentAvailable()) {
+        // Already retrieved (or invalid)
+        if (!_unavailable)
+            QTimer::singleShot(0, this, SLOT(retrievalCompleted()));
+        return true;
+    }
+    
     _service->_client.strategyContext()->selectedStrategy.clearSelection();
     _service->_client.strategyContext()->selectedStrategy.setOperation(QMailRetrievalAction::Content);
     _service->_client.strategyContext()->selectedStrategy.selectedSectionsAppend(partLocation);
@@ -293,6 +303,14 @@
         return false;
     }
     
+    QMailMessage msg(messageId);
+    if (msg.contentAvailable()) {
+        // Already retrieved
+        if (!_unavailable)
+            QTimer::singleShot(0, this, SLOT(retrievalCompleted()));
+        return true;
+    }
+    
     QMailMessagePart::Location location;
     location.setContainingMessageId(messageId);
 
@@ -324,6 +342,14 @@
         return false;
     }
 
+    QMailMessage msg(partLocation.containingMessageId());
+    if (!msg.contains(partLocation) || msg.partAt(partLocation).contentAvailable()) {
+        // Already retrieved (or invalid)
+        if (!_unavailable)
+            QTimer::singleShot(0, this, SLOT(retrievalCompleted()));
+        return true;
+    }
+    
     _service->_client.strategyContext()->selectedStrategy.clearSelection();
     _service->_client.strategyContext()->selectedStrategy.setOperation(QMailRetrievalAction::Content);
     _service->_client.strategyContext()->selectedStrategy.selectedSectionsAppend(partLocation, minimum);
@@ -416,39 +442,73 @@
     return true;
 }
 
-bool ImapService::Source::deleteMessages(const QMailMessageIdList &ids)
+bool ImapService::Source::deleteMessages(const QMailMessageIdList &allIds)
 {
-    QMailMessageIdList messageIds;
-
     // If a server crash has occurred duplicate messages may exist in the store.
     // A duplicate message is one that refers to the same serverUid as another message in the same account & folder.
     // Ensure that when a duplicate message is deleted no message is deleted from the server.
-    QMailMessageIdList duplicateIds;
-    QMailMessageKey::Properties props(QMailMessageKey::Id | QMailMessageKey::ServerUid);
-    foreach (const QMailMessageMetaData &metaData, QMailStore::instance()->messagesMetaData(QMailMessageKey::id(ids), props)) {
-        QMailMessageKey uidKey(QMailMessageKey::serverUid(metaData.serverUid()));
-        QMailMessageKey accountKey(QMailMessageKey::parentAccountId(_service->accountId()));
-        if (QMailStore::instance()->countMessages(accountKey & uidKey) != 1) {
-            duplicateIds.append(metaData.id());
+
+    QMailMessageKey::Properties props(QMailMessageKey::ServerUid | QMailMessageKey::Id);
+    QStringList serverUids;
+    QMailMessageIdList ids;
+    QMailMessageIdList localIds;
+
+    foreach (const QMailMessageMetaData &metaData, QMailStore::instance()->messagesMetaData(QMailMessageKey::id(allIds), props)) {
+        if (!metaData.serverUid().isEmpty()) {
+            serverUids.push_back(metaData.serverUid());
+            ids.push_back(metaData.id());
         } else {
-            messageIds.append(metaData.id());
+            localIds.append(metaData.id());
+        }
+    }
+    if (!localIds.isEmpty()) {
+        if (!QMailMessageSource::deleteMessages(localIds)) {
+            _service->errorOccurred(QMailServiceAction::Status::ErrInvalidData, tr("Could not delete messages"));
+            return false;
         }
+        if (ids.isEmpty())
+            return true;
     }
-    if (!duplicateIds.isEmpty()) {
+
+    Q_ASSERT(serverUids.size() == ids.size());
+    QMailMessageKey accountKey(QMailMessageKey::parentAccountId(_service->accountId()));
+
+    int matching(QMailStore::instance()->countMessages(QMailMessageKey::serverUid(serverUids, QMailDataComparator::Includes) & accountKey));
+    Q_ASSERT(matching >= ids.size());
+
+    if (matching == ids.size()) { // no dupes, lets go
+        return doDelete(ids);
+    } else {
+        QMailMessageIdList duplicateIds;
+        QMailMessageIdList singularIds;
+
+        for (int i(0) ; i < ids.size() ; ++i) {
+            if (QMailStore::instance()->countMessages(QMailMessageKey::serverUid(serverUids[i]) & accountKey) > 1) {
+                duplicateIds.push_back(ids[i]);
+            } else {
+                singularIds.push_back(ids[i]);
+            }
+        }
+        Q_ASSERT(!duplicateIds.empty());
+
         if (!QMailMessageSource::deleteMessages(duplicateIds)) {
             _service->errorOccurred(QMailServiceAction::Status::ErrInvalidData, tr("Could not delete messages"));
             return false;
         }
+
+        return doDelete(singularIds);
     }
-    
-    // Proceed with normal deletion for non-duplicate messages
+}
+
+bool ImapService::Source::doDelete(const QMailMessageIdList &ids)
+{
     QMailAccountConfiguration accountCfg(_service->accountId());
     ImapConfiguration imapCfg(accountCfg);
     if (imapCfg.canDeleteMail()) {
         // Delete the messages from the server
         _service->_client.strategyContext()->deleteMessagesStrategy.clearSelection();
         _service->_client.strategyContext()->deleteMessagesStrategy.setLocalMessageRemoval(true);
-        _service->_client.strategyContext()->deleteMessagesStrategy.selectedMailsAppend(messageIds);
+        _service->_client.strategyContext()->deleteMessagesStrategy.selectedMailsAppend(ids);
         appendStrategy(&_service->_client.strategyContext()->deleteMessagesStrategy, SIGNAL(messagesDeleted(QMailMessageIdList)));
         if(!_unavailable)
             return initiateStrategy();
@@ -456,7 +516,7 @@
     }
 
     // Just delete the local copies
-    return QMailMessageSource::deleteMessages(messageIds);
+    return QMailMessageSource::deleteMessages(ids);
 }
 
 bool ImapService::Source::copyMessages(const QMailMessageIdList &messageIds, const QMailFolderId &destinationId)
--- src/plugins/messageservices/imap/imapsettings.cpp
+++ src/plugins/messageservices/imap/imapsettings.cpp
@@ -45,6 +45,7 @@
 #include <qmailaccount.h>
 #include <qmailaccountconfiguration.h>
 #include <qmailtransport.h>
+#include <qmailnamespace.h>
 #include <selectfolder.h>
 #include <QLineEdit>
 #include <QMessageBox>
@@ -395,6 +396,7 @@
         mailPortInput->setText(QString::number(imapConfig.mailPort()));
 #ifndef QT_NO_OPENSSL
         encryptionIncoming->setCurrentIndex(static_cast<int>(imapConfig.mailEncryption()));
+        authentication->setCurrentIndex(imapConfig.mailAuthentication());
 #endif
         deleteCheckBox->setChecked(imapConfig.canDeleteMail());
         maxSize->setValue(imapConfig.maxMailSize());
@@ -456,6 +458,9 @@
     imapConfig.setMailPort(port == -1 ? 143 : port);
 #ifndef QT_NO_OPENSSL
     imapConfig.setMailEncryption(static_cast<QMailTransport::EncryptType>(encryptionIncoming->currentIndex()));
+    int index(authentication->currentIndex());
+    Q_ASSERT(index >= 0);
+    imapConfig.setMailAuthentication(index);
 #endif
     imapConfig.setDeleteMail(deleteCheckBox->isChecked());
     imapConfig.setMaxMailSize(thresholdCheckBox->isChecked() ? maxSize->value() : -1);
--- src/plugins/messageservices/imap/imapsettings.ui
+++ src/plugins/messageservices/imap/imapsettings.ui
@@ -195,7 +195,53 @@
          </item>
         </widget>
        </item>
-       <item row="5" column="0" colspan="2">
+        <item row="5" column="0">
+          <widget class="QLabel" name="lblAuthentication">
+            <property name="sizePolicy">
+              <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+              </sizepolicy>
+            </property>
+            <property name="text">
+              <string>Authentication</string>
+            </property>
+            <property name="buddy">
+              <cstring>authentication</cstring>
+            </property>
+          </widget>
+        </item>
+        <item row="5" column="1">
+          <widget class="QComboBox" name="authentication">
+            <property name="sizePolicy">
+              <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+              </sizepolicy>
+            </property>
+            <item>
+              <property name="text">
+                <string>None</string>
+              </property>
+            </item>
+            <item>
+              <property name="text">
+                <string>Login</string>
+              </property>
+            </item>
+            <item>
+              <property name="text">
+                <string>Plain</string>
+              </property>
+            </item>
+            <item>
+              <property name="text">
+                <string>Cram MD5</string>
+              </property>
+            </item>
+          </widget>
+        </item>
+        <item row="6" column="0" colspan="2">
         <widget class="QCheckBox" name="deleteCheckBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
@@ -211,7 +257,7 @@
          </property>
         </widget>
        </item>
-       <item row="6" column="0">
+       <item row="7" column="0">
         <widget class="QCheckBox" name="thresholdCheckBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -233,7 +279,7 @@
          </property>
         </widget>
        </item>
-       <item row="6" column="1">
+       <item row="7" column="1">
         <widget class="QSpinBox" name="maxSize">
          <property name="enabled">
           <bool>true</bool>
@@ -261,14 +307,14 @@
          </property>
         </widget>
        </item>
-       <item row="7" column="0" colspan="2">
+       <item row="8" column="0" colspan="2">
         <widget class="QCheckBox" name="preferHtml">
          <property name="text">
           <string>Prefer HTML content over Plain</string>
          </property>
         </widget>
        </item>
-       <item row="8" column="0">
+       <item row="9" column="0">
         <widget class="QCheckBox" name="intervalCheckBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -287,7 +333,7 @@
          </property>
         </widget>
        </item>
-       <item row="8" column="1">
+       <item row="9" column="1">
         <widget class="QSpinBox" name="intervalPeriod">
          <property name="enabled">
           <bool>false</bool>
@@ -315,7 +361,7 @@
          </property>
         </widget>
        </item>
-       <item row="9" column="1">
+       <item row="10" column="1">
         <widget class="QCheckBox" name="roamingCheckBox">
          <property name="enabled">
           <bool>false</bool>
@@ -337,7 +383,7 @@
          </property>
         </widget>
        </item>
-       <item row="10" column="0">
+       <item row="11" column="0">
         <widget class="QLabel" name="baseFolderLabel">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -353,7 +399,7 @@
          </property>
         </widget>
        </item>
-       <item row="10" column="1">
+       <item row="11" column="1">
         <layout class="QHBoxLayout" name="_2a">
          <item>
           <widget class="QLineEdit" name="imapBaseDir">
@@ -402,7 +448,7 @@
          </item>
         </layout>
        </item>
-       <item row="12" column="0">
+       <item row="13" column="0">
         <widget class="QLabel" name="draftsFolderLabel">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -418,7 +464,7 @@
          </property>
         </widget>
        </item>
-       <item row="12" column="1">
+       <item row="13" column="1">
         <layout class="QHBoxLayout" name="_2b">
          <item>
           <widget class="QLineEdit" name="imapDraftsDir">
@@ -470,7 +516,7 @@
          </item>
         </layout>
        </item>
-       <item row="13" column="0">
+       <item row="14" column="0">
         <widget class="QLabel" name="sentFolderLabel">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -486,7 +532,7 @@
          </property>
         </widget>
        </item>
-       <item row="13" column="1">
+       <item row="14" column="1">
         <layout class="QHBoxLayout" name="_2c">
          <item>
           <widget class="QLineEdit" name="imapSentDir">
@@ -538,7 +584,7 @@
          </item>
         </layout>
        </item>
-       <item row="14" column="0">
+       <item row="15" column="0">
         <widget class="QLabel" name="trashFolderLabel">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -554,7 +600,7 @@
          </property>
         </widget>
        </item>
-       <item row="14" column="1">
+       <item row="15" column="1">
         <layout class="QHBoxLayout" name="_2d">
          <item>
           <widget class="QLineEdit" name="imapTrashDir">
@@ -606,7 +652,7 @@
          </item>
         </layout>
        </item>
-       <item row="15" column="0">
+       <item row="16" column="0">
         <widget class="QLabel" name="junkFolderLabel">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -622,7 +668,7 @@
          </property>
         </widget>
        </item>
-       <item row="15" column="1">
+       <item row="16" column="1">
         <layout class="QHBoxLayout" name="_2e">
          <item>
           <widget class="QLineEdit" name="imapJunkDir">
@@ -674,7 +720,7 @@
          </item>
         </layout>
        </item>
-       <item row="16" column="0" colspan="2">
+       <item row="17" column="0" colspan="2">
         <widget class="QCheckBox" name="pushCheckBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -705,6 +751,7 @@
   <tabstop>mailServerInput</tabstop>
   <tabstop>mailPortInput</tabstop>
   <tabstop>encryptionIncoming</tabstop>
+  <tabstop>authentication</tabstop>
   <tabstop>deleteCheckBox</tabstop>
   <tabstop>thresholdCheckBox</tabstop>
   <tabstop>maxSize</tabstop>
--- src/plugins/messageservices/imap/imapstrategy.cpp
+++ src/plugins/messageservices/imap/imapstrategy.cpp
@@ -348,7 +348,7 @@
 
             if (key.combiner() == QMailKey::None) {
                 Q_ASSERT(key.subKeys().size() == 0);
-                Q_ASSERT(key.arguments().size() == 1);
+                Q_ASSERT(key.arguments().size() <= 1);
             } else if (key.combiner() == QMailKey::Or) {
                 foreach (QMailMessageKey const& k, key.subKeys()) {
                     IncludedExcludedPair v(extractFolders(k));
@@ -435,12 +435,13 @@
     QMailMessageBuffer::instance()->flush();
 
     // Update the status on any folders we modified
-    foreach (const QMailFolderId &folderId, _modifiedFolders) {
-        QMailFolder folder(folderId);
+    for (QSet<QMailFolderId>::iterator it(_modifiedFolders.begin()) ; it != _modifiedFolders.end(); it = _modifiedFolders.erase(it))
+    {
+        QMailFolder folder(*it);
         _client->updateFolderCountStatus(&folder);
 
         if (!QMailStore::instance()->updateFolder(&folder)) {
-            qWarning() << "Unable to update folder for account:" << _client->_config.id();
+            qWarning() << "Unable to update folder " << *it << " for account:" << _client->_config.id();
         }
     }
 
@@ -2658,7 +2659,7 @@
 {
     if (!_readUids.isEmpty()) {
         QStringList msgUidl = _readUids.mid(0, batchSize);
-        QString msg = QObject::tr("Marking message %1 read").arg(msgUidl.first());
+        QString msg = QObject::tr("Marking message as read");
         foreach(QString uid, msgUidl) {
             _readUids.removeAll(uid);
             _storedReadUids.append(uid);
@@ -2677,7 +2678,7 @@
 {
     if (!_unreadUids.isEmpty()) {
         QStringList msgUidl = _unreadUids.mid(0, batchSize);
-        QString msg = QObject::tr("Marking message %1 unread").arg(msgUidl.first());
+        QString msg = QObject::tr("Marking message as unread");
         foreach(QString uid, msgUidl) {
             _unreadUids.removeAll(uid);
             _storedUnreadUids.append(uid);
@@ -2696,7 +2697,7 @@
 {
     if (!_importantUids.isEmpty()) {
         QStringList msgUidl = _importantUids.mid(0, batchSize);
-        QString msg = QObject::tr("Marking message %1 important").arg(msgUidl.first());
+        QString msg = QObject::tr("Marking message as important");
         foreach(QString uid, msgUidl) {
             _importantUids.removeAll(uid);
             _storedImportantUids.append(uid);
@@ -2715,7 +2716,7 @@
 {
     if (!_unimportantUids.isEmpty()) {
         QStringList msgUidl = _unimportantUids.mid(0, batchSize);
-        QString msg = QObject::tr("Marking message %1 unimportant").arg(msgUidl.first());
+        QString msg = QObject::tr("Marking message as unimportant");
         foreach(QString uid, msgUidl) {
             _unimportantUids.removeAll(uid);
             _storedUnimportantUids.append(uid);
@@ -2736,7 +2737,7 @@
     if (imapCfg.canDeleteMail()) {
         if (!_removedUids.isEmpty()) {
             QStringList msgUidl = _removedUids.mid(0, batchSize);
-            QString msg = QObject::tr("Deleting message %1").arg(msgUidl.first());
+            QString msg = QObject::tr("Deleting message");
             foreach(QString uid, msgUidl) {
                 _removedUids.removeAll(uid);
                 _storedRemovedUids.append(uid);
@@ -3249,7 +3250,7 @@
     foreach(QString uid, region.toStringList()) {
         uidList.append(QString::number(folderId.toULongLong()) + UID_SEPARATOR + uid);
     }
-    QMailMessageKey uidKey(QMailMessageKey::serverUid(uidList));
+    QMailMessageKey uidKey(QMailMessageKey::serverUid(uidList) & QMailMessageKey::status(flag, set ? QMailDataComparator::Excludes : QMailDataComparator::Includes));
     if (!QMailStore::instance()->updateMessagesMetaData(uidKey, flag, set)) {
         qWarning() << "Unable to update message metadata for folder:" << folderId << "flag" << flag << "set" << set;
         *error = true;
--- src/plugins/messageservices/smtp/smtpclient.cpp
+++ src/plugins/messageservices/smtp/smtpclient.cpp
@@ -98,6 +98,7 @@
 
 SmtpClient::SmtpClient(QObject* parent)
     : QObject(parent)
+    , messageLength(0)
     , sending(false)
     , transport(0)
     , temporaryFile(0)
@@ -111,8 +112,7 @@
 SmtpClient::~SmtpClient()
 {
     delete transport;
-    if (temporaryFile)
-        delete temporaryFile;
+    delete temporaryFile;
 }
 
 QMailMessage::MessageType SmtpClient::messageType() const
@@ -446,7 +446,9 @@
 
                 QMailAccount account(config.id());
                 if (((account.status() & QMailAccount::CanTransmitViaReference) && !supportsReferences) ||
-                    (!(account.status() & QMailAccount::CanTransmitViaReference) && supportsReferences)) {
+                    (!(account.status() & QMailAccount::CanTransmitViaReference) && supportsReferences) ||
+                    (account.customField("qmf-smtp-capabilities-listed") != "true")) {
+                    account.setCustomField("qmf-smtp-capabilities-listed", "true");
                     account.setStatus(QMailAccount::CanTransmitViaReference, supportsReferences);
                     if (!QMailStore::instance()->updateAccount(&account)) {
                         qWarning() << "Unable to update account" << account.id() << "to set CanTransmitViaReference";
@@ -662,6 +664,12 @@
     case Body:  
     {
         if (responseCode == 354) {
+
+            if (temporaryFile) {
+                operationFailed(QMailServiceAction::Status::ErrInvalidData, tr("Received response 354 while sending."));
+                break;
+            }
+
             linestart = true;
             sendingId = mailItr->mail.id();
             sentLength = 0;
@@ -669,8 +677,6 @@
             // Set the message's message ID
             mailItr->mail.setHeaderField("Message-ID", messageId(domainName, addressComponent));
 
-            Q_ASSERT(temporaryFile == 0);
-
             // Buffer the message to a temporary file.
             QString tempPath = QMail::tempPath();
             QDir dir;
@@ -831,6 +837,7 @@
 void SmtpClient::operationFailed(int code, const QString &text)
 {
     if (sending) {
+        stopTransferring();
         transport->close();
         qMailLog(SMTP) << "Closed connection:" << text << flush;
         
@@ -846,6 +853,7 @@
 void SmtpClient::operationFailed(QMailServiceAction::Status::ErrorCode code, const QString &text)
 {
     if (sending) {
+        stopTransferring();
         transport->close();
         qMailLog(SMTP) << "Closed connection:" << text << flush;
         
@@ -892,15 +900,9 @@
 
     // No more data to send
     if (temporaryFile->atEnd()) {
-        if (transport->isEncrypted())
-            disconnect(&(transport->socket()), SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(sendMoreData(qint64)));
-        else
-            disconnect(transport, SIGNAL(bytesWritten(qint64)), this, SLOT(sendMoreData(qint64)));
-        delete temporaryFile;
-        temporaryFile = 0;
-        transport->stream().writeRawData("\r\n.\r\n", 5);
+        stopTransferring();
         qMailLog(SMTP) << "Body: sent:" << messageLength << "bytes";
-        status = Sent;
+        transport->stream().writeRawData("\r\n.\r\n", 5);
         return;
     }
 
@@ -909,7 +911,7 @@
     qint64 bytes = temporaryFile->read(buffer, SENDING_BUFFER_SIZE);
     
     QByteArray dotstuffed;
-    dotstuffed.reserve(SENDING_BUFFER_SIZE + 10); // more than 10 stuffs and array will be autoresized
+    dotstuffed.reserve(SENDING_BUFFER_SIZE + 10); // more than 10 stuffs and array may be autoresized
     for (int i = 0; i < bytes; ++i) {
         if (linestart && (buffer[i] == '.')) {
             dotstuffed.append("..");
@@ -928,6 +930,20 @@
     //qMailLog(SMTP) << "Body: sent a" << bytes << "byte block";
 }
 
+void SmtpClient::stopTransferring()
+{
+    if (temporaryFile)
+    {
+        if (transport->isEncrypted())
+            disconnect(&(transport->socket()), SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(sendMoreData(qint64)));
+        else
+            disconnect(transport, SIGNAL(bytesWritten(qint64)), this, SLOT(sendMoreData(qint64)));
+        delete temporaryFile;
+        temporaryFile = 0;
+        status = Sent;
+    }
+}
+
 void SmtpClient::ssoResponse(const SignOn::SessionData &sessionData)
 {
     qMailLog(SMTP)  << "Got SSO response";
--- src/plugins/messageservices/smtp/smtpclient.h
+++ src/plugins/messageservices/smtp/smtpclient.h
@@ -115,6 +115,7 @@
 
     void operationFailed(int code, const QString &text);
     void operationFailed(QMailServiceAction::Status::ErrorCode code, const QString &text);
+    void stopTransferring();
 
 private:
     enum TransferStatus
--- src/plugins/messageservices/smtp/smtpservice.cpp
+++ src/plugins/messageservices/smtp/smtpservice.cpp
@@ -88,13 +88,15 @@
             }
         }
     }
-    
+
     if (failedMessages.count()) {
         emit messagesFailedTransmission(failedMessages, QMailServiceAction::Status::ErrInvalidAddress);
     }
 
-    if (messageQueued) {
+    QMailAccount account(_service->accountId());
+    if (messageQueued || (account.customField("qmf-smtp-capabilities-listed") != "true")) {
         // At least one message could be queued for sending
+        // or the smtp server capabilities (e.g. forward without download capable) are not known
         _service->_client.newConnection();
     } else {
         // No messages to send, so sending completed successfully
--- src/plugins/messageservices/smtp/smtpsettings.cpp
+++ src/plugins/messageservices/smtp/smtpsettings.cpp
@@ -273,7 +273,7 @@
         int index(authentication->currentIndex());
         Q_ASSERT(index >= 0);
         SmtpConfiguration::AuthType type = authenticationType[index];
-        const bool enableCredentials(type == SmtpConfiguration::Auth_LOGIN || type == SmtpConfiguration::Auth_PLAIN);
+        const bool enableCredentials(type == SmtpConfiguration::Auth_LOGIN || type == SmtpConfiguration::Auth_PLAIN || type == SmtpConfiguration::Auth_CRAMMD5);
         smtpUsernameInput->setEnabled(enableCredentials);
         lblSmtpUsername->setEnabled(enableCredentials);
         smtpPasswordInput->setEnabled(enableCredentials);
--- src/tools/messageserver/messageserver.cpp
+++ src/tools/messageserver/messageserver.cpp
@@ -209,8 +209,6 @@
                 handler, SLOT(protocolRequest(quint64, QMailAccountId, QString, QVariant)));
         connect(client, SIGNAL(searchMessages(quint64, QMailMessageKey, QString, QMailSearchAction::SearchSpecification, QMailMessageSortKey)),
                 handler, SLOT(searchMessages(quint64, QMailMessageKey, QString, QMailSearchAction::SearchSpecification, QMailMessageSortKey)));
-        connect(client, SIGNAL(cancelSearch(quint64)),
-                handler, SLOT(cancelSearch(quint64)));
         connect(client, SIGNAL(shutdown()),
                 handler, SLOT(shutdown()));
         connect(client, SIGNAL(listActions()),
--- src/tools/messageserver/messageserver.sh
+++ src/tools/messageserver/messageserver.sh
@@ -4,11 +4,5 @@
 # if the process was not running, 0 otherwise.
 pidof messageserver
 if [ $? -eq 1 ]; then
-    if [ $(id -u) -eq 0 ]; then
-        # running as root, set the user env, as it's needed by messageserver
-        su - user -c "/usr/bin/messageserver&"
-    else
-        # running as a user
-        /usr/bin/messageserver&
-    fi
+    aegis-exec -l -s -u user "/usr/bin/messageserver&"
 fi
--- src/tools/messageserver/servicehandler.cpp
+++ src/tools/messageserver/servicehandler.cpp
@@ -173,6 +173,8 @@
                                                                                                 QMailStore::ReturnAll)) {
             if (metaData.id().isValid() && metaData.parentAccountId().isValid())
                 map[metaData.parentAccountId()].append(metaData.id());
+            if (metaData.id().isValid() && metaData.parentAccountId().isValid()) //xxx
+                qWarning() << "XXX accountMessages account" << metaData.parentAccountId() << "id" << metaData.id();
         }
 
 
@@ -292,7 +294,7 @@
 
             if (key.combiner() == QMailKey::None) {
                 Q_ASSERT(key.subKeys().size() == 0);
-                Q_ASSERT(key.arguments().size() == 1);
+                Q_ASSERT(key.arguments().size() <= 1);
             } else if (key.combiner() == QMailKey::Or) {
                 foreach (QMailMessageKey const& k, key.subKeys()) {
                     IncludedExcludedPair v(extractAccounts(k));
@@ -514,7 +516,7 @@
                 if (master.id().isValid()) {
                     masterAccount.insert(id, master.id());
                 } else {
-                    qMailLog(Messaging) << "Unable to locate master account:" << masterId << "for account:" << id;
+                    qWarning() << "Unable to locate master account:" << masterId << "for account:" << id;
                 }
             } else {
                 foreach (const QString& service, config.services()) {
@@ -589,22 +591,22 @@
     }
 }
 
-void ServiceHandler::reregisterAccountServices(const QMailAccountIdList &ids, QMailServiceAction::Status::ErrorCode code, const QString &text)
+void ServiceHandler::reregisterAccountServices(QMailAccountIdList ids, QMailServiceAction::Status::ErrorCode code, const QString &text)
 {
     // Remove and re-create these accounts' services
-    QMailAccountIdList reregisterIds;
+
     QMap<QPair<QMailAccountId, QString>,  QPointer<QMailMessageService> >::iterator it = serviceMap.begin();
     while (it != serviceMap.end()) {
         if (ids.contains(it.key().first)) {
            QMailMessageService *service = it.value();
-           if (service && service->requiresReregistration()) {
-               reregisterIds.append(it.key().first);
+           if (service && !service->requiresReregistration()) {
+               ids.removeAll(it.key().first);
            }
         }
         ++it;
     }
-    deregisterAccountServices(reregisterIds, code, text);
-    registerAccountServices(reregisterIds);
+    deregisterAccountServices(ids, code, text);
+    registerAccountServices(ids);
 }
 
 void ServiceHandler::accountsAdded(const QMailAccountIdList &ids)
@@ -647,7 +649,18 @@
     sourceMap.insert(accountId, source);
     sourceService.insert(source, service);
 
+    connect(source, SIGNAL(newMessagesAvailable(quint64)), this, SIGNAL(newMessagesAvailable())); // TODO: <- I don't this this makes much sense..
     connect(source, SIGNAL(newMessagesAvailable()), this, SIGNAL(newMessagesAvailable()));
+
+    // if (service->usesConcurrentActions()) {  // This can be uncommented to be stricter.
+    connect(source, SIGNAL(messagesDeleted(QMailMessageIdList,quint64)), this, SLOT(messagesDeleted(QMailMessageIdList,quint64)));
+    connect(source, SIGNAL(messagesCopied(QMailMessageIdList, quint64)), this, SLOT(messagesCopied(QMailMessageIdList, quint64)));
+    connect(source, SIGNAL(messagesMoved(QMailMessageIdList, quint64)), this, SLOT(messagesMoved(QMailMessageIdList, quint64)));
+    connect(source, SIGNAL(messagesFlagged(QMailMessageIdList, quint64)), this, SLOT(messagesFlagged(QMailMessageIdList, quint64)));
+    connect(source, SIGNAL(messagesPrepared(QMailMessageIdList, quint64)), this, SLOT(messagesPrepared(QMailMessageIdList, quint64)));
+    connect(source, SIGNAL(matchingMessageIds(QMailMessageIdList, quint64)), this, SLOT(matchingMessageIds(QMailMessageIdList, quint64)));
+    connect(source, SIGNAL(protocolResponse(QString, QVariant, quint64)), this, SLOT(protocolResponse(QString, QVariant, quint64)));
+    // } else {
     connect(source, SIGNAL(messagesDeleted(QMailMessageIdList)), this, SLOT(messagesDeleted(QMailMessageIdList)));
     connect(source, SIGNAL(messagesCopied(QMailMessageIdList)), this, SLOT(messagesCopied(QMailMessageIdList)));
     connect(source, SIGNAL(messagesMoved(QMailMessageIdList)), this, SLOT(messagesMoved(QMailMessageIdList)));
@@ -655,6 +668,7 @@
     connect(source, SIGNAL(messagesPrepared(QMailMessageIdList)), this, SLOT(messagesPrepared(QMailMessageIdList)));
     connect(source, SIGNAL(matchingMessageIds(QMailMessageIdList)), this, SLOT(matchingMessageIds(QMailMessageIdList)));
     connect(source, SIGNAL(protocolResponse(QString, QVariant)), this, SLOT(protocolResponse(QString, QVariant)));
+    // }
 }
 
 QMailMessageSource *ServiceHandler::accountSource(const QMailAccountId &accountId) const
@@ -671,9 +685,16 @@
     sinkMap.insert(accountId, sink);
     sinkService.insert(sink, service);
 
+    // if (service->usesConcurrentActions()) { // this can be uncommented to be stricter
+    connect(sink, SIGNAL(messagesTransmitted(QMailMessageIdList, quint64)), this, SLOT(messagesTransmitted(QMailMessageIdList, quint64)));
+    connect(sink, SIGNAL(messagesFailedTransmission(QMailMessageIdList, QMailServiceAction::Status::ErrorCode, quint64)),
+            this, SLOT(messagesFailedTransmission(QMailMessageIdList, QMailServiceAction::Status::ErrorCode, quint64)));
+
+    // } else {
     connect(sink, SIGNAL(messagesTransmitted(QMailMessageIdList)), this, SLOT(messagesTransmitted(QMailMessageIdList)));
     connect(sink, SIGNAL(messagesFailedTransmission(QMailMessageIdList, QMailServiceAction::Status::ErrorCode)), 
             this, SLOT(messagesFailedTransmission(QMailMessageIdList, QMailServiceAction::Status::ErrorCode)));
+    // }
 }
 
 QMailMessageSink *ServiceHandler::accountSink(const QMailAccountId &accountId) const
@@ -688,14 +709,23 @@
 QMailMessageService *ServiceHandler::createService(const QString &name, const QMailAccountId &accountId)
 {
     QMailMessageService *service = QMailMessageServiceFactory::createService(name, accountId);
+    connect(service, SIGNAL(connectivityChanged(QMailServiceAction::Connectivity)), this, SLOT(connectivityChanged(QMailServiceAction::Connectivity)));
+    connect(service, SIGNAL(availabilityChanged(bool)), this, SLOT(availabilityChanged(bool)));
+
+
 
     if (service) {
-        connect(service, SIGNAL(availabilityChanged(bool)), this, SLOT(availabilityChanged(bool)));
-        connect(service, SIGNAL(connectivityChanged(QMailServiceAction::Connectivity)), this, SLOT(connectivityChanged(QMailServiceAction::Connectivity)));
+        // if (service->usesConcurrentActions()) { // this can be uncommented to be stricter
+        connect(service, SIGNAL(activityChanged(QMailServiceAction::Activity, quint64)), this, SLOT(activityChanged(QMailServiceAction::Activity, quint64)));
+        connect(service, SIGNAL(statusChanged(const QMailServiceAction::Status, quint64)), this, SLOT(statusChanged(const QMailServiceAction::Status, quint64)));
+        connect(service, SIGNAL(progressChanged(uint, uint, quint64)), this, SLOT(progressChanged(uint, uint, quint64)));
+        connect(service, SIGNAL(actionCompleted(bool, quint64)), this, SLOT(actionCompleted(bool, quint64)));
+        // } else {
         connect(service, SIGNAL(activityChanged(QMailServiceAction::Activity)), this, SLOT(activityChanged(QMailServiceAction::Activity)));
         connect(service, SIGNAL(statusChanged(const QMailServiceAction::Status)), this, SLOT(statusChanged(const QMailServiceAction::Status)));
         connect(service, SIGNAL(progressChanged(uint, uint)), this, SLOT(progressChanged(uint, uint)));
         connect(service, SIGNAL(actionCompleted(bool)), this, SLOT(actionCompleted(bool)));
+        // }
     }
 
     return service;
@@ -719,7 +749,7 @@
             if (!service->available())
                 mUnavailableServices.insert(service);
         } else {
-            qMailLog(Messaging) << "Unable to instantiate service:" << svcCfg.service();
+            qWarning() << "Unable to instantiate service:" << svcCfg.service();
         }
     }
 }
@@ -735,7 +765,7 @@
 
 bool ServiceHandler::serviceAvailable(QPointer<QMailMessageService> service) const
 {
-    if (mServiceAction.contains(service) || mUnavailableServices.contains(service))
+    if ((!service->usesConcurrentActions() && mServiceAction.contains(service)) || mUnavailableServices.contains(service))
         return false;
 
     return true;
@@ -749,7 +779,7 @@
     if (QMailMessageSource *source = accountSource(id)) {
         services.insert(sourceService.value(source));
     } else {
-        qMailLog(Messaging) << "Unable to find message source for account:" << id;
+        qWarning() << "Unable to find message source for account:" << id;
     }
 
     return services;
@@ -764,7 +794,7 @@
         if (QMailMessageSource *source = accountSource(id)) {
             services.insert(sourceService.value(source));
         } else {
-            qMailLog(Messaging) << "Unable to find message source for account:" << id;
+            qWarning() << "Unable to find message source for account:" << id;
             return QSet<QMailMessageService*>();
         }
     }
@@ -779,7 +809,7 @@
     if (QMailMessageSink *sink = accountSink(id)) {
         services.insert(sinkService[sink]);
     } else {
-        qMailLog(Messaging) << "Unable to find message sink for account:" << id;
+        qWarning() << "Unable to find message sink for account:" << id;
     }
 
     return services;
@@ -793,7 +823,7 @@
         if (QMailMessageSink *sink = accountSink(id)) {
             services.insert(sinkService[sink]);
         } else {
-            qMailLog(Messaging) << "Unable to find message sink for account:" << id;
+            qWarning() << "Unable to find message sink for account:" << id;
             return QSet<QMailMessageService*>();
         }
     }
@@ -897,7 +927,7 @@
         } else {
             mActiveActions.remove(request->action);
 
-            qMailLog(Messaging) << "Unable to dispatch request:" << request->action << "to services:" << request->services;
+            qWarning() << "Unable to dispatch request:" << request->action << "to services:" << request->services;
             emit activityChanged(request->action, QMailServiceAction::Failed);
 
             foreach (QMailMessageService *service, request->services)
@@ -934,7 +964,7 @@
 
             // Is the oldest action expired?
             if (data.unixTimeExpiry <= now) {
-                qMailLog(Messaging) << "Expired request:" << action;
+                qWarning() << "Expired request:" << action;
                 reportFailure(action, QMailServiceAction::Status::ErrTimeout, tr("Request is not progressing"));
                 emit activityChanged(action, QMailServiceAction::Failed);
 
@@ -1009,6 +1039,7 @@
 // Cancelled by user
 void ServiceHandler::cancelTransfer(quint64 action)
 {
+    cancelLocalSearch(action);
     QMap<quint64, ActionData>::iterator it = mActiveActions.find(action);
     if (it != mActiveActions.end()) {
         bool retrievalSetModified(false);
@@ -1016,11 +1047,15 @@
 
         const ActionData &data(it.value());
         foreach (QMailMessageService *service, data.services) {
-            if (service)
-                service->cancelOperation(QMailServiceAction::Status::ErrCancel, tr("Cancelled by user"));
+            if (service) {
+                if (service->usesConcurrentActions())
+                    service->cancelOperation(QMailServiceAction::Status::ErrCancel, tr("Cancelled by user"), it.key());
+                else
+                    service->cancelOperation(QMailServiceAction::Status::ErrCancel, tr("Cancelled by user"));
+            }
             mServiceAction.remove(service);
             if (!service) {
-                qMailLog(Messaging) << "Unable to cancel null service for action:" << action;
+                qWarning() << "Unable to cancel null service for action:" << action;
                 continue;
             }
 
@@ -1112,7 +1147,7 @@
     for ( ; it != end; ++it) {
         if (QMailMessageSource *source = accountSource(it.key())) {
             if (!source->prepareMessages(it.value())) {
-                qMailLog(Messaging) << "Unable to service request to prepare messages for account:" << it.key();
+                qWarning() << "Unable to service request to prepare messages for account:" << it.key();
                 return false;
             } else {
                 // This account is now transmitting
@@ -1138,12 +1173,18 @@
         QMailMessageKey accountKey(QMailMessageKey::parentAccountId(accountId));
         QMailMessageKey outboxKey(QMailMessageKey::status(QMailMessage::Outbox) & ~QMailMessageKey::status(QMailMessage::Trash));
 
-        if (!sink->transmitMessages(QMailStore::instance()->queryMessages(accountKey & outboxKey))) {
-            qMailLog(Messaging) << "Unable to service request to add messages to sink for account:" << accountId;
-            return false;
-        } else {
+        QMailMessageIdList toTransmit(QMailStore::instance()->queryMessages(accountKey & outboxKey));
+
+        bool success(sinkService.value(sink)->usesConcurrentActions()
+                     ? sink->transmitMessages(toTransmit, action)
+                     : sink->transmitMessages(toTransmit));
+
+        if (success) {
             // This account is now transmitting
             setTransmissionInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to add messages to sink for account:" << accountId;
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate sink for account"), accountId);
@@ -1172,12 +1213,16 @@
     deserialize(data, accountId, folderId, descending);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->retrieveFolderList(accountId, folderId, descending)) {
-            qMailLog(Messaging) << "Unable to service request to retrieve folder list for account:" << accountId;
-            return false;
-        } else {
+        bool success(sourceService.value(source)->usesConcurrentActions()
+                            ? source->retrieveFolderList(accountId, folderId, descending, action)
+                            : source->retrieveFolderList(accountId, folderId, descending));
+
+        if (success) {
             // This account is now retrieving (arguably...)
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to retrieve folder list for account:" << accountId;
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1207,12 +1252,15 @@
     deserialize(data, accountId, folderId, minimum, sort);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->retrieveMessageList(accountId, folderId, minimum, sort)) {
-            qMailLog(Messaging) << "Unable to service request to retrieve message list for folder:" << folderId;
-            return false;
-        } else {
+        bool success(sourceService.value(source)->usesConcurrentActions()
+                            ? source->retrieveMessageList(accountId, folderId, minimum, sort, action)
+                            : source->retrieveMessageList(accountId, folderId, minimum, sort));
+        if (success) {
             // This account is now retrieving
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to retrieve message list for folder:" << folderId;
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1244,14 +1292,18 @@
     QMap<QMailAccountId, QMailMessageIdList>::const_iterator it = messageLists.begin(), end = messageLists.end();
     for ( ; it != end; ++it) {
         if (QMailMessageSource *source = accountSource(it.key())) {
-            if (!source->retrieveMessages(it.value(), spec)) {
-                qMailLog(Messaging) << "Unable to service request to retrieve messages for account:" << it.key();
-                return false;
-            } else if (spec != QMailRetrievalAction::Flags) {
+            bool success(sourceService.value(source)->usesConcurrentActions()
+                                ? source->retrieveMessages(it.value(), spec, action)
+                                : source->retrieveMessages(it.value(), spec));
+
+            if (success) {
                 // This account is now retrieving
                 if (!_retrievalAccountIds.contains(it.key())) {
                     _retrievalAccountIds.insert(it.key());
                 }
+            } else {
+                qWarning() << "Unable to service request to retrieve messages for account:" << it.key() << "with spec" << spec;
+                return false;
             }
         } else {
             reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), it.key());
@@ -1282,12 +1334,16 @@
     deserialize(data, accountId, partLocation);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->retrieveMessagePart(partLocation)) {
-            qMailLog(Messaging) << "Unable to service request to retrieve part for message:" << partLocation.containingMessageId();
-            return false;
-        } else {
-            // This account is now retrieving
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->retrieveMessagePart(partLocation, action)
+            : source->retrieveMessagePart(partLocation));
+
+        if (success) {
+           // This account is now retrieving
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to retrieve part for message:" << partLocation.containingMessageId();
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1317,12 +1373,16 @@
     deserialize(data, accountId, messageId, minimum);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->retrieveMessageRange(messageId, minimum)) {
-            qMailLog(Messaging) << "Unable to service request to retrieve range:" << minimum << "for message:" << messageId;
-            return false;
-        } else {
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->retrieveMessageRange(messageId, minimum, action)
+            : source->retrieveMessageRange(messageId, minimum));
+
+        if (success) {
             // This account is now retrieving
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to retrieve range:" << minimum << "for message:" << messageId;
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1352,12 +1412,17 @@
     deserialize(data, accountId, partLocation, minimum);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->retrieveMessagePartRange(partLocation, minimum)) {
-            qMailLog(Messaging) << "Unable to service request to retrieve range:" << minimum << "for part in message:" << partLocation.containingMessageId();
-            return false;
-        } else {
+
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->retrieveMessagePartRange(partLocation, minimum, action)
+            : source->retrieveMessagePartRange(partLocation, minimum));
+
+        if (!success) {
             // This account is now retrieving
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to retrieve range:" << minimum << "for part in message:" << partLocation.containingMessageId();
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1383,13 +1448,17 @@
 
     deserialize(data, accountId);
 
-    if (QMailMessageSource *source = accountSource(accountId)){
-        if (!source->retrieveAll(accountId)) {
-            qMailLog(Messaging) << "Unable to service request to retrieve all messages for account:" << accountId;
-            return false;
-        } else {
+    if (QMailMessageSource *source = accountSource(accountId)) {
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->retrieveAll(accountId, action)
+            : source->retrieveAll(accountId));
+
+        if (success) {
             // This account is now retrieving
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to retrieve all messages for account:" << accountId;
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1416,8 +1485,12 @@
     deserialize(data, accountId);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->exportUpdates(accountId)) {
-            qMailLog(Messaging) << "Unable to service request to export updates for account:" << accountId;
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->exportUpdates(accountId, action)
+            : source->exportUpdates(accountId));
+
+        if (!success) {
+            qWarning() << "Unable to service request to export updates for account:" << accountId;
             return false;
         }
     } else {
@@ -1445,12 +1518,17 @@
     deserialize(data, accountId);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->synchronize(accountId)) {
-            qMailLog(Messaging) << "Unable to service request to synchronize account:" << accountId;
-            return false;
-        } else {
+
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->exportUpdates(accountId, action)
+            : source->exportUpdates(accountId));
+
+        if (success) {
             // This account is now retrieving
             setRetrievalInProgress(accountId, true);
+        } else {
+            qWarning() << "Unable to service request to synchronize account:" << accountId;
+            return false;
         }
     } else {
         reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1494,7 +1572,7 @@
 
     // Just delete all these messages
     if (!QMailStore::instance()->removeMessages(QMailMessageKey::id(messageIds), QMailStore::NoRemovalRecord)) {
-        qMailLog(Messaging) << "Unable to service request to discard messages";
+        qWarning() << "Unable to service request to discard messages";
 
         reportFailure(action, QMailServiceAction::Status::ErrEnqueueFailed, tr("Unable to discard messages"));
         return false;
@@ -1514,8 +1592,12 @@
     QMap<QMailAccountId, QMailMessageIdList>::const_iterator it = messageLists.begin(), end = messageLists.end();
     for ( ; it != end; ++it) {
         if (QMailMessageSource *source = accountSource(it.key())) {
-            if (!source->deleteMessages(it.value())) {
-                qMailLog(Messaging) << "Unable to service request to delete messages for account:" << it.key();
+            bool success(sourceService.value(source)->usesConcurrentActions()
+                ? source->deleteMessages(it.value(), action)
+                : source->deleteMessages(it.value()));
+
+            if (!success) {
+                qWarning() << "Unable to service request to delete messages for account:" << it.key();
                 return false;
             }
         } else {
@@ -1564,8 +1646,13 @@
     } else {
         QMailAccountId accountId(*accountIds.begin());
         if (QMailMessageSource *source = accountSource(accountId)) {
-            if (!source->copyMessages(messageIds, destination)) {
-                qMailLog(Messaging) << "Unable to service request to copy messages to folder:" << destination << "for account:" << accountId;
+
+            bool success(sourceService.value(source)->usesConcurrentActions()
+                ? source->copyMessages(messageIds, destination, action)
+                : source->copyMessages(messageIds, destination));
+
+            if (!success) {
+                qWarning() << "Unable to service request to copy messages to folder:" << destination << "for account:" << accountId;
                 return false;
             }
         } else {
@@ -1600,7 +1687,7 @@
         message.setParentFolderId(destination);
 
         if (!QMailStore::instance()->addMessage(&message)) {
-            qMailLog(Messaging) << "Unable to service request to copy messages to folder:" << destination << "for account:" << message.parentAccountId();
+            qWarning() << "Unable to service request to copy messages to folder:" << destination << "for account:" << message.parentAccountId();
 
             reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to copy messages for account"), message.parentAccountId());
             return false;
@@ -1634,10 +1721,15 @@
     deserialize(data, messageLists, destination);
 
     QMap<QMailAccountId, QMailMessageIdList>::const_iterator it = messageLists.begin(), end = messageLists.end();
-    for ( ; it != end; ++it) {
+    for ( ; it != end; ++it) {       
         if (QMailMessageSource *source = accountSource(it.key())) {
-            if (!source->moveMessages(it.value(), destination)) {
-                qMailLog(Messaging) << "Unable to service request to move messages to folder:" << destination << "for account:" << it.key();
+
+            bool success(sourceService.value(source)->usesConcurrentActions()
+                ? source->moveMessages(it.value(), destination, action)
+                : source->moveMessages(it.value(), destination));
+
+            if (!success) {
+                qWarning() << "Unable to service request to move messages to folder:" << destination << "for account:" << it.key();
                 return false;
             }
         } else {
@@ -1673,8 +1765,12 @@
     QMap<QMailAccountId, QMailMessageIdList>::const_iterator it = messageLists.begin(), end = messageLists.end();
     for ( ; it != end; ++it) {
         if (QMailMessageSource *source = accountSource(it.key())) {
-            if (!source->flagMessages(it.value(), setMask, unsetMask)) {
-                qMailLog(Messaging) << "Unable to service request to flag messages for account:" << it.key();
+            bool success(sourceService.value(source)->usesConcurrentActions()
+                ? source->flagMessages(it.value(), setMask, unsetMask, action)
+                : source->flagMessages(it.value(), setMask, unsetMask));
+
+            if (!success) {
+                qWarning() << "Unable to service request to flag messages for account:" << it.key();
                 return false;
             }
         } else {
@@ -1707,10 +1803,13 @@
     deserialize(data, name, accountId, parentId);
 
     if(QMailMessageSource *source = accountSource(accountId)) {
-        if(source->createFolder(name, accountId, parentId)) {
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->createFolder(name, accountId, parentId, action)
+            : source->createFolder(name, accountId, parentId));
+        if (success) {
             return true;
         } else {
-            qMailLog(Messaging) << "Unable to service request to create folder for account:" << accountId;
+            qWarning() << "Unable to service request to create folder for account:" << accountId;
             return false;
         }
 
@@ -1740,10 +1839,13 @@
     deserialize(data, folderId, newFolderName);
 
     if(QMailMessageSource *source = accountSource(QMailFolder(folderId).parentAccountId())) {
-        if(source->renameFolder(folderId, newFolderName)) {
+        bool success(sourceService.value(source)->usesConcurrentActions()
+            ? source->renameFolder(folderId, newFolderName, action)
+            : source->renameFolder(folderId, newFolderName));
+        if (success) {
             return true;
         } else {
-            qMailLog(Messaging) << "Unable to service request to rename folder id:" << folderId;
+            qWarning() << "Unable to service request to rename folder id:" << folderId;
             return false;
         }
 
@@ -1775,7 +1877,7 @@
         if(source->deleteFolder(folderId)) {
             return true;
         } else {
-            qMailLog(Messaging) << "Unable to service request to delete folder id:" << folderId;
+            qWarning() << "Unable to service request to delete folder id:" << folderId;
             return false;
         }
     } else {
@@ -1798,7 +1900,7 @@
         }
     } else {
         // Find the messages that match the filter criteria
-        QMailMessageIdList searchIds = QMailStore::instance()->queryMessages(filter, sort);
+        QMailMessageIdList searchIds(QMailStore::instance()->queryMessages(filter, sort));
 
         // Schedule this search
         mSearches.append(MessageSearch(action, searchIds, bodyText));
@@ -1819,12 +1921,15 @@
 
     foreach (const QMailAccountId &accountId, accountIds) {
         if (QMailMessageSource *source = accountSource(accountId)) {
+            bool success(sourceService.value(source)->usesConcurrentActions()
+                ? source->searchMessages(filter, bodyText, sort, action)
+                : source->searchMessages(filter, bodyText, sort));
             //only dispatch to appropriate account
-            if (source->searchMessages(filter, bodyText, sort)) {
+            if (success) {
                 sentSearch = true; //we've at least sent one
             } else {
                 //do it locally instead
-                qMailLog(Messaging) << "Unable to do remote search, doing it locally instead";
+                qWarning() << "Unable to do remote search, doing it locally instead";
                 mSearches.append(MessageSearch(action, QMailStore::instance()->queryMessages(filter, sort), bodyText));
                 QTimer::singleShot(0, this, SLOT(continueSearch()));
             }
@@ -1836,54 +1941,23 @@
     return sentSearch;
 }
 
-void ServiceHandler::cancelSearch(quint64 action)
-{
-    QSet<QMailAccountId> accounts(sourceMap.keys().toSet());
-
-    QSet<QMailMessageService*> sources(sourceServiceSet(accounts));
-    if (!sources.isEmpty()) {
-        enqueueRequest(action, serialize(accounts), sources, &ServiceHandler::dispatchCancelSearch, &ServiceHandler::searchCompleted, CancelSearchRequestType);
-    }
 
+void ServiceHandler::cancelLocalSearch(quint64 action) // cancel local search
+{
     QList<MessageSearch>::iterator it = mSearches.begin(), end = mSearches.end();
     for ( ; it != end; ++it) {
         if ((*it).action() == action) {
-            bool currentSearch(it == mSearches.begin());
-
-            if (currentSearch && !mMatchingIds.isEmpty())
+            if (!mMatchingIds.isEmpty())
                 emit matchingMessageIds(action, mMatchingIds);
 
             emit searchCompleted(action);
 
             mSearches.erase(it);
-
-            if (currentSearch) {
-                // Tell the sources to stop searching also
-                cancelTransfer(action);
-            }
             return;
         }
     }
 }
 
-bool ServiceHandler::dispatchCancelSearch(quint64 action, const QByteArray &data)
-{
-    QSet<QMailAccountId> accounts;
-
-    deserialize(data, accounts);
-
-    foreach (const QMailAccountId &accountId, accounts) {
-        if (QMailMessageSource *source = accountSource(accountId)) {
-            source->cancelSearch();
-        } else {
-            reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
-            return false;
-        }
-    }
-
-    return true;
-}
-
 void ServiceHandler::shutdown()
 {
     QTimer::singleShot(0,QCoreApplication::instance(),SLOT(quit()));
@@ -1902,6 +1976,174 @@
     emit actionsListed(list);
 }
 
+// concurrent actions
+void ServiceHandler::statusChanged(const QMailServiceAction::Status s, quint64 a)
+{
+    emit statusChanged(a, s);
+}
+
+void ServiceHandler::availabilityChanged(bool b, quint64 a)
+{
+    emit availabilityChanged(a, b);
+}
+
+void ServiceHandler::connectivityChanged(QMailServiceAction::Connectivity c, quint64 a)
+{
+    emit connectivityChanged(a, c);
+}
+
+void ServiceHandler::activityChanged(QMailServiceAction::Activity act, quint64 a)
+{
+    emit activityChanged(a, act);
+}
+
+void ServiceHandler::progressChanged(uint p, uint t, quint64 a)
+{
+    emit progressChanged(a, p, t);
+}
+
+void ServiceHandler::actionCompleted(bool success, quint64 action)
+{
+   QMailMessageService *service = qobject_cast<QMailMessageService*>(sender());
+   Q_ASSERT(service);
+
+   actionCompleted(success, service, action);
+}
+
+void ServiceHandler::actionCompleted(bool success, QMailMessageService *service, quint64 action)
+{
+    QMap<quint64, ActionData>::iterator it = mActiveActions.find(action);
+    if (it != mActiveActions.end()) {
+        ActionData &data(it.value());
+
+        if (!mSentIds.isEmpty() && (data.completion == &ServiceHandler::transmissionCompleted)) {
+            if (accountSource(service->accountId())) {
+                // Mark these message as Sent
+                quint64 setMask(QMailMessage::Sent);
+                quint64 unsetMask(QMailMessage::Outbox | QMailMessage::Draft | QMailMessage::LocalOnly);
+
+                QMailMessageKey idsKey(QMailMessageKey::id(mSentIds));
+
+                bool failed = QMailStore::instance()->updateMessagesMetaData(idsKey, setMask, true);
+                failed = QMailStore::instance()->updateMessagesMetaData(idsKey, unsetMask, false) || failed;
+
+                if (failed) {
+                    qWarning() << "Unable to flag messages:" << mSentIds;
+                }
+
+                enqueueRequest(newLocalActionId(),
+                    serialize(accountMessages(mSentIds), setMask, unsetMask),
+                    sourceServiceSet(service->accountId()),
+                    &ServiceHandler::dispatchFlagMessages,
+                    &ServiceHandler::storageActionCompleted,
+                    FlagMessagesRequestType);
+
+            }
+
+            mSentIds.clear();
+        }
+
+        QSet<QPointer<QMailMessageService> >::iterator sit = data.services.find(service);
+        if (sit != data.services.end()) {
+            // Remove this service from the set for the action
+            data.services.erase(sit);
+
+            // This account is no longer retrieving/transmitting
+            QMailAccountId accountId(service->accountId());
+            if (accountId.isValid()) {
+                if (data.completion == &ServiceHandler::retrievalCompleted) {
+                    setRetrievalInProgress(accountId, false);
+                } else if (data.completion == &ServiceHandler::transmissionCompleted) {
+                    setTransmissionInProgress(accountId, false);
+                }
+            }
+
+            if (success) {
+                if (data.services.isEmpty() && data.completion && (data.reported == false)) {
+                    // Report success
+                    emit (this->*data.completion)(action);
+                    data.reported = true;
+                }
+            } else {
+                // This action has failed - mark it so that it can't be reported as successful
+                data.reported = true;
+            }
+        }
+
+        if (data.services.isEmpty()) {
+            // This action is finished
+            mActiveActions.erase(it);
+            emit activityChanged(action, success ? QMailServiceAction::Successful : QMailServiceAction::Failed);
+        }
+    }
+
+    if (_outstandingRequests.contains(action)) {
+        _outstandingRequests.remove(action);
+
+        // Ensure this request is no longer in the file
+        _requestsFile.resize(0);
+        foreach (quint64 req, _outstandingRequests) {
+            QByteArray requestNumber(QByteArray::number(req));
+            _requestsFile.write(requestNumber.append('\n'));
+        }
+        _requestsFile.flush();
+    }
+
+    mServiceAction.remove(service);
+
+
+    // See if there are pending requests
+    QTimer::singleShot(0, this, SLOT(dispatchRequest()));
+}
+
+void ServiceHandler::messagesTransmitted(const QMailMessageIdList& ml, quint64 a)
+{
+    emit messagesTransmitted(a, ml);
+}
+
+void ServiceHandler::messagesFailedTransmission(const QMailMessageIdList& ml, QMailServiceAction::Status::ErrorCode err, quint64 a)
+{
+    emit messagesFailedTransmission(a, ml, err);
+}
+
+void ServiceHandler::messagesDeleted(const QMailMessageIdList& ml, quint64 a)
+{
+    emit messagesDeleted(a, ml);
+}
+
+void ServiceHandler::messagesCopied(const QMailMessageIdList& ml, quint64 a)
+{
+    emit messagesCopied(a, ml);
+}
+
+void ServiceHandler::messagesMoved(const QMailMessageIdList& ml, quint64 a)
+{
+    emit messagesMoved(a, ml);
+}
+
+void ServiceHandler::messagesFlagged(const QMailMessageIdList& ml, quint64 a)
+{
+    emit messagesFlagged(a, ml);
+}
+
+void ServiceHandler::messagesPrepared(const QMailMessageIdList& ml, quint64 a)
+{
+    Q_UNUSED(ml);
+    Q_UNUSED(a);
+}
+
+void ServiceHandler::matchingMessageIds(const QMailMessageIdList& ml, quint64 a)
+{
+    emit matchingMessageIds(a, ml);
+}
+
+void ServiceHandler::protocolResponse(const QString &response, const QVariant &data, quint64 a)
+{
+    emit protocolResponse(a, response, data);
+}
+
+// end concurrent actions
+
 void ServiceHandler::protocolRequest(quint64 action, const QMailAccountId &accountId, const QString &request, const QVariant &data)
 {
     QSet<QMailMessageService*> sources(sourceServiceSet(accountId));
@@ -1921,8 +2163,11 @@
     deserialize(data, accountId, request, requestData);
 
     if (QMailMessageSource *source = accountSource(accountId)) {
-        if (!source->protocolRequest(accountId, request, requestData)) {
-            qMailLog(Messaging) << "Unable to service request to forward protocol-specific request to account:" << accountId;
+        bool success(sourceService.value(source)->usesConcurrentActions()
+                     ? source->protocolRequest(accountId, request, requestData, action)
+                     : source->protocolRequest(accountId, request, requestData));
+        if (!success) {
+            qWarning() << "Unable to service request to forward protocol-specific request to account:" << accountId;
             return false;
         }
     } else {
@@ -2048,86 +2293,12 @@
 {
     if (QMailMessageService *service = qobject_cast<QMailMessageService*>(sender())) {
         if (quint64 action = serviceAction(service)) {
-            QMap<quint64, ActionData>::iterator it = mActiveActions.find(action);
-            if (it != mActiveActions.end()) {
-                ActionData &data(it.value());
-
-                if (!mSentIds.isEmpty() && (data.completion == &ServiceHandler::transmissionCompleted)) {
-                    if (accountSource(service->accountId())) {
-                        // Mark these message as Sent
-                        quint64 setMask(QMailMessage::Sent);
-                        quint64 unsetMask((QMailMessage::Outbox | QMailMessage::Draft | QMailMessage::LocalOnly));
-
-                        QMailMessageKey idsKey(QMailMessageKey::id(mSentIds));
-
-                        if (!QMailStore::instance()->updateMessagesMetaData(idsKey, setMask, true) ||
-                            !QMailStore::instance()->updateMessagesMetaData(idsKey, unsetMask, false))
-                        {
-                            qMailLog(Messaging) << "Unable to flag messages:" << mSentIds;
-                        }
-
-                        enqueueRequest(newLocalActionId(),
-                                       serialize(accountMessages(mSentIds), setMask, unsetMask),
-                                        sourceServiceSet(service->accountId()),
-                                        &ServiceHandler::dispatchFlagMessages,
-                                        &ServiceHandler::storageActionCompleted,
-                                        FlagMessagesRequestType);
-
-                    }
-
-                    mSentIds.clear();
-                }
-
-                QSet<QPointer<QMailMessageService> >::iterator sit = data.services.find(service);
-                if (sit != data.services.end()) {
-                    // Remove this service from the set for the action
-                    data.services.erase(sit);
-
-                    // This account is no longer retrieving/transmitting
-                    QMailAccountId accountId(service->accountId());
-                    if (accountId.isValid()) {
-                        if (data.completion == &ServiceHandler::retrievalCompleted) {
-                            setRetrievalInProgress(accountId, false);
-                        } else if (data.completion == &ServiceHandler::transmissionCompleted) {
-                            setTransmissionInProgress(accountId, false);
-                        } 
-                    }
-
-                    if (success) {
-                        if (data.services.isEmpty() && data.completion && (data.reported == false)) {
-                            // Report success
-                            emit (this->*data.completion)(action);
-                            data.reported = true;
-                        }
-                    } else {
-                        // This action has failed - mark it so that it can't be reported as successful
-                        data.reported = true;
-                    }
-                }
-
-                if (data.services.isEmpty()) {
-                    // This action is finished
-                    mActiveActions.erase(it);
-                    emit activityChanged(action, success ? QMailServiceAction::Successful : QMailServiceAction::Failed);
-                }
-            }
-
-            if (_outstandingRequests.contains(action)) {
-                _outstandingRequests.remove(action);
-
-                // Ensure this request is no longer in the file
-                _requestsFile.resize(0);
-                foreach (quint64 req, _outstandingRequests) {
-                    QByteArray requestNumber(QByteArray::number(req));
-                    _requestsFile.write(requestNumber.append('\n'));
-                }
-                _requestsFile.flush();
-            }
-
-            mServiceAction.remove(service);
+            actionCompleted(success, service, action);
+            return;
         }
     }
 
+    qWarning() << "Would not determine server/action completing";
     // See if there are pending requests
     QTimer::singleShot(0, this, SLOT(dispatchRequest()));
 }
@@ -2190,27 +2361,6 @@
         }
     }
 }
-
-void ServiceHandler::finaliseSearch(quint64 action)
-{
-    if (mSearches.isEmpty()) {
-        qWarning() << "Remote search complete but none pending!" << action;
-    } else {
-        MessageSearch &currentSearch(mSearches.first());
-
-        if (currentSearch.action() != action) {
-            qWarning() << "Remote search complete but not current!" << action;
-        } else {
-            if (currentSearch.isEmpty()) {
-                // This search is now finished
-                emit searchCompleted(currentSearch.action());
-                mSearches.removeFirst();
-                if (!mSearches.isEmpty())
-                    QTimer::singleShot(0, this, SLOT(continueSearch()));
-            }
-        }
-    }
-}
 
 void ServiceHandler::reportFailures()
 {
--- src/tools/messageserver/servicehandler.h
+++ src/tools/messageserver/servicehandler.h
@@ -85,7 +85,7 @@
     void deleteFolder(quint64 action, const QMailFolderId &folderId);
     void cancelTransfer(quint64 action);
     void searchMessages(quint64 action, const QMailMessageKey &filter, const QString &bodyText, QMailSearchAction::SearchSpecification spec, const QMailMessageSortKey &sort);
-    void cancelSearch(quint64 action);
+    void cancelLocalSearch(quint64 action);
     void shutdown();
     void listActions();
     void protocolRequest(quint64 action, const QMailAccountId &accountId, const QString &request, const QVariant &data);
@@ -129,30 +129,45 @@
 
 private slots:
     void statusChanged(const QMailServiceAction::Status);
+    void statusChanged(const QMailServiceAction::Status, quint64);
     void availabilityChanged(bool);
+    void availabilityChanged(bool, quint64);
     void connectivityChanged(QMailServiceAction::Connectivity);
+    void connectivityChanged(QMailServiceAction::Connectivity, quint64);
     void activityChanged(QMailServiceAction::Activity);
+    void activityChanged(QMailServiceAction::Activity, quint64);
     void progressChanged(uint, uint );
+    void progressChanged(uint, uint, quint64);
     void actionCompleted(bool);
+    void actionCompleted(bool, quint64);
+    void actionCompleted(bool, QMailMessageService *, quint64);
 
     void messagesTransmitted(const QMailMessageIdList&);
+    void messagesTransmitted(const QMailMessageIdList&, quint64);
     void messagesFailedTransmission(const QMailMessageIdList&, QMailServiceAction::Status::ErrorCode);
+    void messagesFailedTransmission(const QMailMessageIdList&, QMailServiceAction::Status::ErrorCode, quint64);
 
     void messagesDeleted(const QMailMessageIdList&);
+    void messagesDeleted(const QMailMessageIdList& , quint64);
     void messagesCopied(const QMailMessageIdList&);
+    void messagesCopied(const QMailMessageIdList&, quint64);
     void messagesMoved(const QMailMessageIdList&);
+    void messagesMoved(const QMailMessageIdList&, quint64);
     void messagesFlagged(const QMailMessageIdList&);
+    void messagesFlagged(const QMailMessageIdList&, quint64);
     void messagesPrepared(const QMailMessageIdList&);
+    void messagesPrepared(const QMailMessageIdList&, quint64);
     void matchingMessageIds(const QMailMessageIdList&);
+    void matchingMessageIds(const QMailMessageIdList&, quint64);
 
     void protocolResponse(const QString &response, const QVariant &data);
+    void protocolResponse(const QString &response, const QVariant &data, quint64);
 
     void accountsAdded(const QMailAccountIdList &);
     void accountsUpdated(const QMailAccountIdList &);
     void accountsRemoved(const QMailAccountIdList &);
 
     void continueSearch();
-    void finaliseSearch(quint64 action);
 
     void dispatchRequest();
 
@@ -167,7 +182,7 @@
     void deregisterAccountServices(const QMailAccountIdList &ids, QMailServiceAction::Status::ErrorCode code, const QString &text);
     void removeServiceFromActions(QMailMessageService *removeService);
 
-    void reregisterAccountServices(const QMailAccountIdList &ids, QMailServiceAction::Status::ErrorCode code, const QString &text);
+    void reregisterAccountServices(QMailAccountIdList ids, QMailServiceAction::Status::ErrorCode code, const QString &text);
 
     void registerAccountSource(const QMailAccountId &accountId, QMailMessageSource *source, QMailMessageService *service);
     QMailMessageSource *accountSource(const QMailAccountId &accountId) const;
@@ -220,7 +235,6 @@
     bool dispatchDeleteFolder(quint64 action, const QByteArray &data);
     bool dispatchRenameFolder(quint64 action, const QByteArray &data);
     bool dispatchSearchMessages(quint64 action, const QByteArray &data);
-    bool dispatchCancelSearch(quint64 action, const QByteArray &data);
     bool dispatchProtocolRequest(quint64 action, const QByteArray &data);
 
     void reportFailure(quint64, QMailServiceAction::Status::ErrorCode, const QString& = QString(), const QMailAccountId& = QMailAccountId(), const QMailFolderId& = QMailFolderId(), const QMailMessageId& = QMailMessageId());

++++++ qmf.yaml
--- qmf.yaml
+++ qmf.yaml
@@ -1,14 +1,12 @@
 Name: qmf
 Summary: Qt Messaging Framework (QMF)
-Version: 1.0.7~2010w43
+Version: 1.0.7~2010w46
 Release: 1
 Group: System/Libraries
 License: LGPLv2.1 with exception or GPLv3
 URL: http://meego.gitorious.org/meego-middleware/messagingframework
 Sources:
     - "%{name}-%{version}.tar.gz"
-    - "%{name}.sh"
-    - messageserver.desktop
 Patches:
     - fix_docs_installation.patch
     - fix_plugins_installation.patch
@@ -29,6 +27,10 @@
 Builder: qmake
 QMakeOptions:
     - "QMF_INSTALL_ROOT=%{_prefix}"
+    - CONFIG+=syslog
+ExtraSources:
+    - qmf.sh;%{_sysconfdir}/profile.d
+    - messageserver.desktop;%{_sysconfdir}/xdg/autostart
 NoFiles: yes
 RunFdupes: "%{_includedir}"
 SubPackages:




More information about the MeeGo-commits mailing list