Revision: 201037 default PDK_4.0.a
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 04 Oct 2010 01:37:06 +0300
changeset 5 603d3f8b6302
parent 3 e4ebb16b39ea
Revision: 201037 Kit: 201039
.hg_archival.txt
.hgtags
VERSION.SHA1
common.pri
config.pri
config.tests/messaging_qthighway/main.cpp
config.tests/messaging_qthighway/messaging_qthighway.pro
data/qtmobility.pkg
data/qtmobility_stub.pkg
data/qtmobility_stub.sis
data/qtmobilityexampleapps.pkg
examples/audiorecorder/audiorecorder.cpp
examples/audiorecorder/audiorecorder.pro
examples/audiorecorder/audiorecorder_small.ui
examples/bearermonitor/bearermonitor.cpp
examples/bearermonitor/sessionwidget.cpp
examples/examples.pro
examples/keepintouch/addressfinder.cpp
examples/player/mediakeysobserver.cpp
examples/player/mediakeysobserver.h
examples/querymessages/main.cpp
examples/sensors/arrowkeys/main.cpp
examples/sensors/orientation/orientation.pro
examples/sensors/panoramaWithSense/accelerometercontroller.cpp
examples/sensors/panoramaWithSense/accelerometercontroller.h
examples/sensors/panoramaWithSense/compasscontroller.cpp
examples/sensors/panoramaWithSense/compasscontroller.h
examples/sensors/panoramaWithSense/images/foreshore_final.jpg
examples/sensors/panoramaWithSense/images/koskipuisto_pieni.jpg
examples/sensors/panoramaWithSense/inputcontroller.cpp
examples/sensors/panoramaWithSense/inputcontroller.h
examples/sensors/panoramaWithSense/keycontroller.cpp
examples/sensors/panoramaWithSense/keycontroller.h
examples/sensors/panoramaWithSense/magnetometercontroller.cpp
examples/sensors/panoramaWithSense/magnetometercontroller.h
examples/sensors/panoramaWithSense/main.cpp
examples/sensors/panoramaWithSense/orientationcontroller.cpp
examples/sensors/panoramaWithSense/orientationcontroller.h
examples/sensors/panoramaWithSense/panoramaWithSense.pro
examples/sensors/panoramaWithSense/panoramaWithSense.pro.bck
examples/sensors/panoramaWithSense/panoramaWithSense.qrc
examples/sensors/panoramaWithSense/rotationcontroller.cpp
examples/sensors/panoramaWithSense/rotationcontroller.h
examples/sensors/panoramaWithSense/rotationsensorcontroller.h
examples/sensors/panoramaWithSense/tapcontroller.cpp
examples/sensors/panoramaWithSense/tapcontroller.h
examples/sensors/panoramaWithSense/timedcontroller.cpp
examples/sensors/panoramaWithSense/timedcontroller.h
examples/sensors/panoramaWithSense/view.cpp
examples/sensors/panoramaWithSense/view.h
examples/sensors/sensors.pro
examples/sensors/test_manual/test_manual.pro
features/mobilityconfig.prf
features/qtservice.mk
plugins/contacts/contacts.pro
plugins/contacts/maemo5/qcontactabook.cpp
plugins/contacts/maemo5/qcontactabook_p.h
plugins/contacts/maemo5/qcontactmaemo5backend.cpp
plugins/contacts/symbian/contactsmodel/bwins/cntmodlv2_sqliteu.def
plugins/contacts/symbian/contactsmodel/bwins/cntplsqlu.def
plugins/contacts/symbian/contactsmodel/cntmodel/src/ccontactdatabase.cpp
plugins/contacts/symbian/contactsmodel/cntmodel/src/rcntmodel.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/inc/c12keykeymap.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/clplcontactproperties.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/cntsqlsearch.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/cpcskeymap.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/cqwertykeymap.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/cqwertypredictivesearchtable.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/pltables.h
plugins/contacts/symbian/contactsmodel/cntplsql/inc/pplcontactitemmanager.h
plugins/contacts/symbian/contactsmodel/cntplsql/src/c12keykeymap.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/clplcontactproperties.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cntpredictivesearch.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cntsqlsearch.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cpcskeymap.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cpplcontacttable.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cqwertykeymap.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/cqwertypredictivesearchtable.cpp
plugins/contacts/symbian/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp
plugins/contacts/symbian/contactsmodel/cntsrv/inc/ccntfilemanagermsghandler.h
plugins/contacts/symbian/contactsmodel/cntsrv/inc/persistencelayer.h
plugins/contacts/symbian/contactsmodel/cntsrv/src/ccntfilemanagermsghandler.cpp
plugins/contacts/symbian/contactsmodel/contactsmodel.pro
plugins/contacts/symbian/contactsmodel/eabi/cntmodlv2_sqliteu.def
plugins/contacts/symbian/contactsmodel/eabi/cntplsqlu.def
plugins/contacts/symbian/contactsmodel/group/1020384e.txt
plugins/contacts/symbian/contactsmodel/group/common.inf
plugins/contacts/symbian/contactsmodel/groupsql/cntmodel.iby
plugins/contacts/symbian/contactsmodel/groupsql/cntplsql.mmp
plugins/contacts/symbian/contactsmodel/inc/cntdb.h
plugins/contacts/symbian/contactsmodel/inc/cntpredictivesearch.h
plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_cprogressnotification.mmp
plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_dbtransactiontest.mmp
plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_states.mmp
plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_templatecache.mmp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/contacts_just_12key_tables.db
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/contacts_language_45.db
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/contacts_without_pred_search_tables.db
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/readme.txt
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.cpp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.cpp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.cpp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.cpp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.h
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/main.cpp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/runtest.cmd
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.cpp
plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.h
plugins/contacts/symbian/contactsmodel/tsrc/cntviewstore/10003a73.txt
plugins/contacts/symbian/contactsmodel/tsrc/integration/tcntpolice/group/te_cntsrv_api_policing.mmp
plugins/contacts/symbian/contactsmodel/tsrc/integration/tcntpolice/template/te_cntsrv_api_policing.mmp
plugins/contacts/symbian/contactsmodel/tsrc/t_apac_initial_contacts.txt
plugins/contacts/symbian/contactsmodel/tsrc/t_mults.mmp
plugins/contacts/symbian/contactsmodel/tsrc/t_view2_initial_contacts.txt
plugins/contacts/symbian/contactsmodel/tsrc/t_view2_initial_contacts_small.txt
plugins/contacts/symbian/contactsmodel/tsrc/t_view2_more_contacts_1.txt
plugins/contacts/symbian/contactsmodel/tsrc/t_view2_more_contacts_2.txt
plugins/contacts/symbian/contactsmodel/tsrc/testsyncplugin/1020384e.txt
plugins/contacts/symbian/plugin/inc/cntabstractrelationship.h
plugins/contacts/symbian/plugin/inc/cntdisplaylabel.h
plugins/contacts/symbian/plugin/inc/cntrelationship.h
plugins/contacts/symbian/plugin/inc/cntrelationshipgroup.h
plugins/contacts/symbian/plugin/inc/contactbackendsdefs.h
plugins/contacts/symbian/plugin/inc/filtering/cntsqlsearch.h
plugins/contacts/symbian/plugin/inc/filtering/cntsymbiansrvconnection.h
plugins/contacts/symbian/plugin/plugin.pro
plugins/contacts/symbian/plugin/src/cntdisplaylabel.cpp
plugins/contacts/symbian/plugin/src/cntrelationship.cpp
plugins/contacts/symbian/plugin/src/cntrelationshipgroup.cpp
plugins/contacts/symbian/plugin/src/cntsymbianengine.cpp
plugins/contacts/symbian/plugin/src/filtering/cntdbinfo.cpp
plugins/contacts/symbian/plugin/src/filtering/cntfilterdetail.cpp
plugins/contacts/symbian/plugin/src/filtering/cntsqlsearch.cpp
plugins/contacts/symbian/plugin/src/filtering/cntsymbiansrvconnection.cpp
plugins/contacts/symbian/plugin/symbian_defines.pri
plugins/contacts/symbian/plugin/tsrc/tsrc.pri
plugins/contacts/symbian/plugin/tsrc/tst_qcontactmanagersymbian/tst_qcontactmanagersymbian.pro
plugins/contacts/symbian/plugin/tsrc/ut_symbian/main.cpp
plugins/contacts/symbian/plugin/tsrc/ut_symbian/test_data.txt
plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntfiltering.cpp
plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsqlsearch.cpp
plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsqlsearch.h
plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsymbianengine.cpp
plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_symbian.pro
plugins/contacts/symbian/symbian.pro
plugins/contacts/symbiansim/inc/cntsimstoreeventlistener.h
plugins/contacts/symbiansim/inc/cntsimstoreprivate.h
plugins/contacts/symbiansim/inc/cntsymbiansimengine.h
plugins/contacts/symbiansim/src/cntsimstoreeventlistener.cpp
plugins/contacts/symbiansim/src/cntsimstoreprivate.cpp
plugins/contacts/symbiansim/src/cntsymbiansimengine.cpp
plugins/declarative/contacts/contacts.pro
plugins/declarative/multimedia/multimedia.pro
plugins/declarative/publishsubscribe/publishsubscribe.pro
plugins/declarative/sensors/sensors.pro
plugins/declarative/serviceframework/qdeclarativeservice.h
plugins/declarative/serviceframework/serviceframework.pro
plugins/multimedia/gstreamer/mediacapture/qgstreamerrecordercontrol.h
plugins/multimedia/gstreamer/qx11videosurface.cpp
plugins/multimedia/qt7/mediaplayer/mediaplayer.pri
plugins/multimedia/qt7/mediaplayer/qt7playercontrol.h
plugins/multimedia/qt7/mediaplayer/qt7playercontrol.mm
plugins/multimedia/qt7/mediaplayer/qt7playermetadata.h
plugins/multimedia/qt7/mediaplayer/qt7playermetadata.mm
plugins/multimedia/qt7/mediaplayer/qt7playerservice.h
plugins/multimedia/qt7/mediaplayer/qt7playerservice.mm
plugins/multimedia/qt7/mediaplayer/qt7playersession.h
plugins/multimedia/qt7/mediaplayer/qt7playersession.mm
plugins/multimedia/qt7/qt7.pro
plugins/multimedia/qt7/qt7playercontrol.h
plugins/multimedia/qt7/qt7playercontrol.mm
plugins/multimedia/qt7/qt7playermetadata.h
plugins/multimedia/qt7/qt7playermetadata.mm
plugins/multimedia/qt7/qt7playerservice.h
plugins/multimedia/qt7/qt7playerservice.mm
plugins/multimedia/qt7/qt7playersession.h
plugins/multimedia/qt7/qt7playersession.mm
plugins/multimedia/qt7/qt7serviceplugin.mm
plugins/multimedia/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h
plugins/plugins.pro
plugins/sensors/maemo6/Sensors.conf
plugins/sensors/maemo6/maemo6.pro
plugins/sensors/maemo6/maemo6accelerometer.cpp
plugins/sensors/maemo6/maemo6als.cpp
plugins/sensors/maemo6/maemo6magnetometer.cpp
plugins/sensors/maemo6/maemo6magnetometer.h
plugins/sensors/maemo6/maemo6sensorbase.cpp
plugins/sensors/maemo6/maemo6sensorbase.h
plugins/sensors/s60_sensor_api/s60_sensor_api.pro
plugins/versit/backuphandler/backuphandler.pro
plugins/versit/backuphandler/backupvcardhandler.cpp
plugins/versit/backuphandler/backupvcardhandler.h
plugins/versit/versit.pro
qtmobility.pro
src/bearer/qnetworkmanagerservice_p.cpp
src/contacts/qcontact.cpp
src/contacts/qcontactabstractrequest.cpp
src/global/qmobilityglobal.h
src/global/qmobilitypluginsearch.h
src/location/location.pro
src/messaging/messaging.pro
src/messaging/qfsengine_symbian.cpp
src/messaging/qmessage.cpp
src/messaging/qmessageaccount_symbian.cpp
src/messaging/qmessageid_maemo.cpp
src/messaging/qmtmengine_symbian.cpp
src/messaging/qmtmengine_symbian_p.h
src/multimedia/qgraphicsvideoitem_maemo5.cpp
src/multimedia/qmediaplaylistnavigator.h
src/multimedia/qmediapluginloader.cpp
src/multimedia/qmediapluginloader_p.h
src/multimedia/qvideowidget.h
src/multimedia/qxvideosurface_maemo5.cpp
src/publishsubscribe/psmapperserver_symbian/pathmapper_symbian.cpp
src/s60installs/backup_registration.xml
src/s60installs/bwins/QtVersitu.def
src/s60installs/eabi/QtVersitu.def
src/s60installs/qtmobility.iby
src/s60installs/s60installs.pro
src/sensors/qsensor.cpp
src/sensors/qsensormanager.cpp
src/sensors/qsensorpluginloader.cpp
src/systeminfo/qsysteminfo.cpp
src/systeminfo/qsysteminfo_linux.cpp
src/systeminfo/qsysteminfo_linux_common.cpp
src/systeminfo/qsysteminfo_linux_common_p.h
src/systeminfo/qsysteminfo_linux_p.h
src/systeminfo/qsysteminfo_maemo.cpp
src/systeminfo/qsysteminfo_maemo_p.h
src/systeminfo/qsysteminfo_s60.cpp
src/versit/README
src/versit/qvcard21writer.cpp
src/versit/qvcard30writer.cpp
src/versit/qvcardbackuphandlers_p.cpp
src/versit/qvcardbackuphandlers_p.h
src/versit/qversitcontactexporter.cpp
src/versit/qversitcontactexporter.h
src/versit/qversitcontactexporter_p.cpp
src/versit/qversitcontactexporter_p.h
src/versit/qversitcontacthandler.cpp
src/versit/qversitcontacthandler.h
src/versit/qversitcontactimporter.cpp
src/versit/qversitcontactimporter.h
src/versit/qversitcontactimporter_p.cpp
src/versit/qversitcontactimporter_p.h
src/versit/qversitcontactpluginloader_p.cpp
src/versit/qversitcontactpluginloader_p.h
src/versit/qversitcontactsdefs_p.h
src/versit/qversitdefs_p.h
src/versit/qversitdocument.cpp
src/versit/qversitdocument.h
src/versit/qversitdocument_p.cpp
src/versit/qversitdocument_p.h
src/versit/qversitdocumentwriter_p.cpp
src/versit/qversitdocumentwriter_p.h
src/versit/qversitproperty.cpp
src/versit/qversitreader.cpp
src/versit/qversitreader_p.cpp
src/versit/qversitreader_p.h
src/versit/qversitresourcehandler.cpp
src/versit/qversitwriter.cpp
src/versit/qversitwriter_p.cpp
src/versit/versit.pro
src/versit/versitutils.cpp
src/versit/versitutils_p.h
tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp
tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp
tests/auto/qmessageservice/tst_qmessageservice.cpp
tests/auto/qsensor/qsensor.pro
tests/auto/qsensor/tst_qsensor.cpp
tests/auto/qsystemdisplayinfo/tst_qsystemdisplayinfo.cpp
tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp
tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.h
tests/messagingex/messagingex.pro
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hg_archival.txt	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,2 @@
+repo: 86532d94ffa4a0438f3191e1f0d564468e044f90
+node: 3bce1935d8c7147e816592000dc5b548367e3f67
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgtags	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,14 @@
+86532d94ffa4a0438f3191e1f0d564468e044f90 prep-1026
+19ba1b1d0aee192a0b387cfbab063e2e1a87d4f7 prep-1028
+64cbd909fa702805678fae116d9d142e728a3fbb prep-1028-1
+335027457e3d6b799bc5c253fb8fcf4644633f8a prep-1030
+d858c670b77efde4f2da2575ea2aa952b46a391c prep-1030-1
+71acf64e6adeedb2b81b08bd8b365ff22a380fce prep-1034
+709deae561a2135e87fcde79ca02f4f7c22242dc prep-1036
+211cc600326be359cae28dd2e1e595497c83f870 prep-1036-1
+ace972504fa67823c9f6115f225a6a7ec7b832b6 prep-1036-2
+f340a31d7168a12cc7d041f56ec03f4969887df6 prep-1036-3
+5fd27732f3ba08755dc257d9c8e9f2a2ffcf1047 prep-1036-4
+85564da9a68dd0610f6323ba92954818bfcc3bac prep-1036-5
+d1907885355b34512b2c44a4499b30c56f800c62 prep-1036-6
+c65e4bb07fc0b6d9b50c2ba49103f7027cf8c85f prep-1036-7
--- a/VERSION.SHA1	Fri Sep 17 08:34:34 2010 +0300
+++ b/VERSION.SHA1	Mon Oct 04 01:37:06 2010 +0300
@@ -1,1 +1,1 @@
-c45b842b839c9b1a592f63ac7668f75b79119522
+e01e17904fcd1e08c561aab827993f928f9e8941
--- a/common.pri	Fri Sep 17 08:34:34 2010 +0300
+++ b/common.pri	Mon Oct 04 01:37:06 2010 +0300
@@ -36,7 +36,7 @@
 #didn't select a version - if Qt is build in debug_and_release
 #this avoids problems for third party as qmake build debug by default
 #If mobility selected debug_and_release but Qt only supports
-#one version but not the other we slently disable the impossible combination
+#one version but not the other we silently disable the impossible combination
 win32:contains(CONFIG_WIN32,build_all) {
     contains(QT_CONFIG,debug):contains(QT_CONFIG,release) {
         contains(TEMPLATE,.*lib):!plugin {
@@ -88,7 +88,7 @@
         contains(TEMPLATE,.*lib) {
             DESTDIR = $$OUTPUT_DIR/lib
             symbian:defFilePath=../s60installs
-#            VERSION = 1.0.2
+            VERSION = 1.0.3
         } else {
             DESTDIR = $$OUTPUT_DIR/bin
         }
--- a/config.pri	Fri Sep 17 08:34:34 2010 +0300
+++ b/config.pri	Mon Oct 04 01:37:06 2010 +0300
@@ -23,3 +23,4 @@
 openmaxal_symbian_enabled = yes
 surfaces_s60_enabled = yes
 messaging_freestyle_enabled = yes
+messaging_qthighway_enabled = yes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.tests/messaging_qthighway/main.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <xqaiwdecl.h>
+#include <xqaiwdeclplat.h>
+#include <xqaiwrequest.h>
+#include <xqservicerequest.h>
+#include <email_services_api.h>
+
+int main(int, char**)
+{
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.tests/messaging_qthighway/messaging_qthighway.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,10 @@
+#CONFIG -= qt
+TEMPLATE = app
+
+# Input
+SOURCES += main.cpp
+
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+
+LIBS += -lxqservice \
+        -lxqserviceutil
--- a/data/qtmobility.pkg	Fri Sep 17 08:34:34 2010 +0300
+++ b/data/qtmobility.pkg	Mon Oct 04 01:37:06 2010 +0300
@@ -3,7 +3,7 @@
 &EN
 
 ; SIS header: name, uid, version
-#{"QtMobility"},(0x2002AC89),1,0,2,TYPE=SA,RU
+#{"QtMobility"},(0x2002AC89),1,0,3,TYPE=SA,RU
 
 ; Localised Vendor name
 %{"Nokia"}
@@ -55,4 +55,6 @@
 "/epoc32/release/armv5/urel/cntphone.dll"                  - "!:\sys\bin\cntphone.dll"
 "/epoc32/data/z/resource/plugins/cntvcard.rsc"             - "!:\resource\plugins\cntvcard.rsc"
 "/epoc32/data/z/resource/plugins/cntphone.rsc"             - "!:\resource\plugins\cntphone.rsc"
-"/epoc32/data/z/resource/cntmodel/cntmodel.rsc"            - "!:\resource\cntmodel\cntmodel.rsc"
\ No newline at end of file
+"/epoc32/data/z/resource/cntmodel/cntmodel.rsc"            - "!:\resource\cntmodel\cntmodel.rsc"
+
+"/epoc32/data/z/private/10202D56/import/packages/2002AC89/backup_registration.xml"   - "!:\private\10202D56\import\packages\2002AC89\backup_registration.xml"
--- a/data/qtmobility_stub.pkg	Fri Sep 17 08:34:34 2010 +0300
+++ b/data/qtmobility_stub.pkg	Mon Oct 04 01:37:06 2010 +0300
@@ -3,7 +3,7 @@
 &EN
 
 ; SIS header: name, uid, version
-#{"QtMobility"},(0x2002AC89),1,0,2,TYPE=SA
+#{"QtMobility"},(0x2002AC89),1,0,3,TYPE=SA
 
 ; Localised Vendor name
 %{"Nokia"}
Binary file data/qtmobility_stub.sis has changed
--- a/data/qtmobilityexampleapps.pkg	Fri Sep 17 08:34:34 2010 +0300
+++ b/data/qtmobilityexampleapps.pkg	Mon Oct 04 01:37:06 2010 +0300
@@ -2,7 +2,7 @@
 &EN
 
 ; SIS header: name, uid, version
-#{"QtMobilityExamples"},(0xE001E61D),1,0,2,TYPE=SA
+#{"QtMobilityExamples"},(0xE001E61D),1,0,3,TYPE=SA
  
 ; Localised Vendor name
 %{"Nokia, Qt"}
@@ -10,6 +10,14 @@
 ; Unique Vendor name
 :"Nokia, Qt"
 
+; Default HW/platform dependencies
+[0x101F7961],0,0,0,{"S60ProductID"}
+[0x102032BE],0,0,0,{"S60ProductID"}
+[0x102752AE],0,0,0,{"S60ProductID"}
+[0x1028315F],0,0,0,{"S60ProductID"}
+[0x20022e6d],0,0,0,{"S60ProductID"}
+
+;Bearer
 "/epoc32/release/armv5/urel/bearercloud.exe"                        - "!:\sys\bin\bearercloud.exe"
 "/epoc32/data/z/resource/apps/bearercloud.rsc"                      - "!:\resource\apps\bearercloud.rsc"
 "/epoc32/data/z/private/10003a3f/import/apps/bearercloud_reg.rsc"   - "!:\private\10003a3f\import\apps\bearercloud_reg.rsc"
@@ -18,6 +26,54 @@
 "/epoc32/data/z/resource/apps/bearermonitor.rsc"                    - "!:\resource\apps\bearermonitor.rsc"
 "/epoc32/data/z/private/10003a3f/import/apps/bearermonitor_reg.rsc" - "!:\private\10003a3f\import\apps\bearermonitor_reg.rsc"
 
-"/epoc32/release/armv5/urel/BearerEx.exe"                           - "!:\sys\bin\BearerEx.exe"
-"/epoc32/data/z/resource/apps/BearerEx.rsc"                         - "!:\resource\apps\BearerEx.rsc"
-"/epoc32/data/z/private/10003a3f/import/apps/BearerEx_reg.rsc"      - "!:\private\10003a3f\import\apps\BearerEx_reg.rsc"
+;Contacts
+"/epoc32/release/armv5/urel/samplephonebook.exe"                      - "!:\sys\bin\samplephonebook.exe"
+"/epoc32/data/z/resource/apps/samplephonebook.rsc"                    - "!:\resource\apps\samplephonebook.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/samplephonebook_reg.rsc" - "!:\private\10003a3f\import\apps\samplephonebook_reg.rsc"
+
+;Location
+"/epoc32/release/armv5/urel/satellitedialog.exe"                      - "!:\sys\bin\satellitedialog.exe"
+"/epoc32/data/z/resource/apps/satellitedialog.rsc"                    - "!:\resource\apps\satellitedialog.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/satellitedialog_reg.rsc" - "!:\private\10003a3f\import\apps\satellitedialog_reg.rsc"
+
+;Messaging
+"/epoc32/release/armv5/urel/querymessages.exe"                      - "!:\sys\bin\querymessages.exe"
+"/epoc32/data/z/resource/apps/querymessages.rsc"                    - "!:\resource\apps\querymessages.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/querymessages_reg.rsc" - "!:\private\10003a3f\import\apps\querymessages_reg.rsc"
+
+"/epoc32/release/armv5/urel/writemessage.exe"                      - "!:\sys\bin\writemessage.exe"
+"/epoc32/data/z/resource/apps/writemessage.rsc"                    - "!:\resource\apps\writemessage.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/writemessage_reg.rsc" - "!:\private\10003a3f\import\apps\writemessage_reg.rsc"
+
+;Multimedia
+"/epoc32/release/armv5/urel/player.exe"                      - "!:\sys\bin\player.exe"
+"/epoc32/data/z/resource/apps/player.rsc"                    - "!:\resource\apps\player.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/player_reg.rsc" - "!:\private\10003a3f\import\apps\player_reg.rsc"
+
+"/epoc32/release/armv5/urel/audiorecorder.exe"                      - "!:\sys\bin\audiorecorder.exe"
+"/epoc32/data/z/resource/apps/audiorecorder.rsc"                    - "!:\resource\apps\audiorecorder.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/audiorecorder_reg.rsc" - "!:\private\10003a3f\import\apps\audiorecorder_reg.rsc"
+
+"/epoc32/release/armv5/urel/slideshow.exe"                      - "!:\sys\bin\slideshow.exe"
+"/epoc32/data/z/resource/apps/slideshow.rsc"                    - "!:\resource\apps\slideshow.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/slideshow_reg.rsc" - "!:\private\10003a3f\import\apps\slideshow_reg.rsc"
+
+;Publish and Subscribe
+"/epoc32/release/armv5/urel/publish_subscribe.exe"                      - "!:\sys\bin\publish_subscribe.exe"
+"/epoc32/data/z/resource/apps/publish_subscribe.rsc"                    - "!:\resource\apps\publish_subscribe.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/publish_subscribe_reg.rsc" - "!:\private\10003a3f\import\apps\publish_subscribe_reg.rsc"
+
+;Sensors
+"/epoc32/release/armv5/urel/smallsensors.exe"                      - "!:\sys\bin\smallsensors.exe"
+"/epoc32/data/z/resource/apps/smallsensors.rsc"                    - "!:\resource\apps\smallsensors.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/smallsensors_reg.rsc" - "!:\private\10003a3f\import\apps\smallsensors_reg.rsc"
+
+;ServiceFramework
+"/epoc32/release/armv5/urel/servicebrowser.exe"                      - "!:\sys\bin\servicebrowser.exe"
+"/epoc32/data/z/resource/apps/servicebrowser.rsc"                    - "!:\resource\apps\servicebrowser.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/servicebrowser_reg.rsc" - "!:\private\10003a3f\import\apps\servicebrowser_reg.rsc"
+
+;SystemInfo
+"/epoc32/release/armv5/urel/qsysinfo.exe"                      - "!:\sys\bin\qsysinfo.exe"
+"/epoc32/data/z/resource/apps/qsysinfo.rsc"                    - "!:\resource\apps\qsysinfo.rsc"
+"/epoc32/data/z/private/10003a3f/import/apps/qsysinfo_reg.rsc" - "!:\private\10003a3f\import\apps\qsysinfo_reg.rsc"
--- a/examples/audiorecorder/audiorecorder.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/audiorecorder/audiorecorder.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -46,7 +46,7 @@
 
 #include "audiorecorder.h"
 
-#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
+#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) || defined(SYMBIAN_S60_32)
 #include "ui_audiorecorder_small.h"
 #else
 #include "ui_audiorecorder.h"
--- a/examples/audiorecorder/audiorecorder.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/audiorecorder/audiorecorder.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -18,10 +18,12 @@
 
 maemo*: {
     FORMS += audiorecorder_small.ui
-} else {
+}else:symbian:contains(S60_VERSION, 3.2) {
+    DEFINES += SYMBIAN_S60_32
+    FORMS += audiorecorder_small.ui
+}else {
     FORMS += audiorecorder.ui
 }
-
 symbian: {
     TARGET.CAPABILITY = UserEnvironment ReadDeviceData WriteDeviceData 
 }
--- a/examples/audiorecorder/audiorecorder_small.ui	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/audiorecorder/audiorecorder_small.ui	Mon Oct 04 01:37:06 2010 +0300
@@ -17,6 +17,9 @@
    <layout class="QGridLayout" name="gridLayout_5">
     <item row="0" column="0" colspan="3">
      <widget class="QScrollArea" name="scrollArea">
+      <property name="focusPolicy">
+       <enum>Qt::ClickFocus</enum>
+      </property>
       <property name="widgetResizable">
        <bool>true</bool>
       </property>
@@ -26,7 +29,7 @@
          <x>0</x>
          <y>0</y>
          <width>398</width>
-         <height>262</height>
+         <height>275</height>
         </rect>
        </property>
        <layout class="QGridLayout" name="gridLayout_4">
--- a/examples/bearermonitor/bearermonitor.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/bearermonitor/bearermonitor.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -239,6 +239,15 @@
         }
     }
 
+    QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
+    if (defaultConfiguration.type() == QNetworkConfiguration::UserChoice) {
+        QTreeWidgetItem *item = itemMap.take(defaultConfiguration.identifier());
+        if (item)
+            updateItem(item, defaultConfiguration);
+        else
+            configurationAdded(defaultConfiguration);
+    }
+
     foreach (const QString &id, itemMap.keys())
         delete itemMap.value(id);
 }
--- a/examples/bearermonitor/sessionwidget.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/bearermonitor/sessionwidget.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -89,14 +89,27 @@
 {
     updateSessionState(session->state());
 
-    if (session->configuration().type() == QNetworkConfiguration::InternetAccessPoint)
-        bearer->setText(session->configuration().bearerName());
-    else {
-        QNetworkConfigurationManager mgr;
-        QNetworkConfiguration c = mgr.configurationFromIdentifier(session->sessionProperty("ActiveConfiguration").toString());
-        bearer->setText(c.bearerName());
+    QNetworkConfigurationManager manager;
+    QNetworkConfiguration config;
+    switch (session->configuration().type()) {
+    case QNetworkConfiguration::InternetAccessPoint:
+        config = session->configuration();
+        break;
+    case QNetworkConfiguration::ServiceNetwork:
+        config = manager.configurationFromIdentifier(
+                    session->sessionProperty("ActiveConfiguration").toString());
+        break;
+    case QNetworkConfiguration::UserChoice:
+        config = manager.configurationFromIdentifier(
+                    session->sessionProperty("UserChoiceConfiguration").toString());
+        break;
+    default:
+        ;
     }
 
+    bearer->setText(config.bearerName());
+    configuration->setText(config.name());
+
     interfaceName->setText(session->interface().humanReadableName());
     interfaceGuid->setText(session->interface().name());
 }
--- a/examples/examples.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/examples.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -9,9 +9,10 @@
                notesmanagerplugin \
                servicebrowser
 
+    #These examples do not work on Symbian yet
     !symbian:SUBDIRS+= sfw-notes
     
-    contains(QT_CONFIG, declarative) {
+    !symbian:contains(QT_CONFIG, declarative) {
         SUBDIRS += declarative-sfw-dialer
 
         sources.files += declarative-sfw-notes \
--- a/examples/keepintouch/addressfinder.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/keepintouch/addressfinder.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -276,10 +276,7 @@
 //! [handle-search-result]
                 } else {
                     QMessageBox::information(0, tr("Empty"), tr("No messages found"));
-                    searchAction->setEnabled(true);
-#ifdef USE_SEARCH_BUTTON
-                    searchButton->setEnabled(true);
-#endif
+                    setSearchActionEnabled(true);
                 }
             }
         } else {
@@ -546,6 +543,10 @@
 {
     searchAction->setEnabled(val);
 #ifdef USE_SEARCH_BUTTON
+    if (val)
+        searchButton->setText(tr("Search"));
+    else
+        searchButton->setText(tr("Searching.."));
     searchButton->setEnabled(val);
 #endif
 }
--- a/examples/player/mediakeysobserver.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**   * Redistributions of source code must retain the above copyright
-**     notice, this list of conditions and the following disclaimer.
-**   * Redistributions in binary form must reproduce the above copyright
-**     notice, this list of conditions and the following disclaimer in
-**     the documentation and/or other materials provided with the
-**     distribution.
-**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-**     the names of its contributors may be used to endorse or promote
-**     products derived from this software without specific prior written
-**     permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "mediakeysobserver.h"
-
-MediaKeysObserver::MediaKeysObserver(QObject *parent) : QObject(parent)
-{
-    iInterfaceSelector = CRemConInterfaceSelector::NewL();
-    iCoreTarget = CRemConCoreApiTarget::NewL(*iInterfaceSelector, *this);
-    iInterfaceSelector->OpenTargetL();
-}
-
-MediaKeysObserver::~MediaKeysObserver()
-{
-    delete iInterfaceSelector;
-}
-
-void MediaKeysObserver::MrccatoCommand(TRemConCoreApiOperationId aOperationId,
-									TRemConCoreApiButtonAction aButtonAct)
-{
-    TRequestStatus status;
-	switch(aOperationId)
-	{
-	case ERemConCoreApiPausePlayFunction:
-		{
-		if (aButtonAct == ERemConCoreApiButtonClick) 
-		    emit mediaKeyPressed(MediaKeysObserver::EPlayPauseKey);
-
-		//Send the response back to Remcon server       
-		iCoreTarget->PausePlayFunctionResponse(status, KErrNone);
-		User::WaitForRequest(status);
-		break;
-		}   
-
-	case ERemConCoreApiStop:
-		{
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EStopKey);
-		iCoreTarget->StopResponse(status, KErrNone);
-		User::WaitForRequest(status);
-		break;
-		}
-	case ERemConCoreApiRewind:
-		{
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EFastRewindKey);
-		iCoreTarget->RewindResponse(status, KErrNone);
-		User::WaitForRequest(status);   
-		break;
-		}       
-	case ERemConCoreApiForward:
-		{
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EForwardKey);
-		iCoreTarget->ForwardResponse(status, KErrNone);
-		User::WaitForRequest(status);
-		break;
-		}
-	case ERemConCoreApiVolumeUp:
-		{   
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EVolIncKey);
-		iCoreTarget->VolumeUpResponse(status, KErrNone);
-		User::WaitForRequest(status);   
-
-		break;
-		}       
-	case ERemConCoreApiVolumeDown:
-		{
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EVolDecKey);
-		iCoreTarget->VolumeDownResponse(status, KErrNone);
-		User::WaitForRequest(status);   
-		break;
-		}
-	case ERemConCoreApiFastForward:
-		{
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EFastForwardKey);
-		iCoreTarget->FastForwardResponse(status, KErrNone);
-		User::WaitForRequest(status);
-		break;
-		}              
-	case ERemConCoreApiBackward:
-		{
-        if (aButtonAct == ERemConCoreApiButtonClick) 
-            emit mediaKeyPressed(MediaKeysObserver::EBackwardKey);
-		iCoreTarget->BackwardResponse(status, KErrNone);
-		User::WaitForRequest(status);
-		break;
-		}                   
-	default:
-		break;
-	}
-}
--- a/examples/player/mediakeysobserver.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**   * Redistributions of source code must retain the above copyright
-**     notice, this list of conditions and the following disclaimer.
-**   * Redistributions in binary form must reproduce the above copyright
-**     notice, this list of conditions and the following disclaimer in
-**     the documentation and/or other materials provided with the
-**     distribution.
-**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-**     the names of its contributors may be used to endorse or promote
-**     products derived from this software without specific prior written
-**     permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MEDIAKEYSOBSERVER_H_
-#define MEDIAKEYSOBSERVER_H_
-
-#include <remconcoreapitargetobserver.h>    
-#include <remconcoreapitarget.h>
-#include <remconinterfaceselector.h>     
-#include <aknappui.h>   
-#include <QObject>
-
-class MediaKeysObserver : public QObject, public MRemConCoreApiTargetObserver
-{
-    Q_OBJECT
-    
-public:
-    enum MediaKeys {
-        EVolIncKey,
-        EVolDecKey,
-        EPlayPauseKey,
-        EStopKey,
-        EBackwardKey,
-        EForwardKey,
-        EFastForwardKey,
-        EFastRewindKey
-    };
-
-    MediaKeysObserver(QObject *parent = 0); 
-    virtual ~MediaKeysObserver();
-
-protected: // From public MRemConCoreApiTargetObserver
-    void MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct);
-    void MrccatoPlay(TRemConCoreApiPlaybackSpeed /*aSpeed*/, TRemConCoreApiButtonAction /*aButtonAct*/) {};         
-    void MrccatoTuneFunction(TBool /*aTwoPart*/, TUint /*aMajorChannel*/, TUint /*aMinorChannel*/, TRemConCoreApiButtonAction /*aButtonAct*/) {};        
-    void MrccatoSelectDiskFunction(TUint /*aDisk*/, TRemConCoreApiButtonAction /*aButtonAct*/) {};
-    void MrccatoSelectAvInputFunction(TUint8 /*aAvInputSignalNumber*/, TRemConCoreApiButtonAction /*aButtonAct*/) {};
-    void MrccatoSelectAudioInputFunction(TUint8 /*aAudioInputSignalNumber*/, TRemConCoreApiButtonAction /*aButtonAct*/) {};   
-    
-Q_SIGNALS:
-    void mediaKeyPressed(MediaKeysObserver::MediaKeys key);
-    
-private:
-    CRemConInterfaceSelector* iInterfaceSelector;
-    CRemConCoreApiTarget*     iCoreTarget;
-};
-#endif
-
--- a/examples/querymessages/main.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/querymessages/main.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -41,6 +41,7 @@
 #include <QCoreApplication>
 #include <qmessagemanager.h>
 #include <qdebug.h>
+#include <QMap>
 #ifdef Q_OS_SYMBIAN
 #include <iostream>
 #endif
@@ -56,15 +57,83 @@
 #endif
 }
 
+void usage()
+{
+    QString msg("Usage: [<options>] [<datafields>]\n"
+                  " Where <options> limit the types of messages shown, valid choices: -all, -sms, -mms, -email, -instantmessage, -incoming, -read, -inboxfolder, -draftsfolder, -outboxfolder, -sentfolder, -trashfolder\n"
+                  "         To join options by logical OR use +, for option, eg \"+sms +mms\" will return sms OR mms messages\n"
+                  " Where <datafields> specify what fields to print from matched messages, valid choices are: subject, date, receivedDate, status, size, priority, to, cc, bcc, from, type, body, attachments");
+    printMessage(msg);
+}
+
+// create message filter as requested by command line options
+QMessageFilter createFilter(QStringList args)
+{
+    QMessageFilter filter(QMessageFilter::byStatus(QMessage::Incoming));
+    QMessageFilter customfilter;
+    bool setCustomFilter = false;
+    QMap<QString, QMessageFilter> filterMap;
+    filterMap.insert(QLatin1String("all"), QMessageFilter());
+    filterMap.insert(QLatin1String("sms"), QMessageFilter::byType(QMessage::Sms));
+    filterMap.insert(QLatin1String("mms"), QMessageFilter::byType(QMessage::Mms));
+    filterMap.insert(QLatin1String("email"), QMessageFilter::byType(QMessage::Email));
+    filterMap.insert(QLatin1String("instantmessage"), QMessageFilter::byType(QMessage::InstantMessage));
+    filterMap.insert(QLatin1String("incoming"), QMessageFilter::byStatus(QMessage::Incoming));
+    filterMap.insert(QLatin1String("read"), QMessageFilter::byStatus(QMessage::Read));
+    filterMap.insert(QLatin1String("inboxfolder"), QMessageFilter::byStandardFolder(QMessage::InboxFolder));
+    filterMap.insert(QLatin1String("draftsfolder"), QMessageFilter::byStandardFolder(QMessage::DraftsFolder));
+    filterMap.insert(QLatin1String("outboxfolder"), QMessageFilter::byStandardFolder(QMessage::OutboxFolder));
+    filterMap.insert(QLatin1String("sentfolder"), QMessageFilter::byStandardFolder(QMessage::SentFolder));
+    filterMap.insert(QLatin1String("trashfolder"), QMessageFilter::byStandardFolder(QMessage::TrashFolder));
+
+    // process command line options after the application name
+    foreach (const QString &arg, args.mid(1)){
+        QMap<QString, QMessageFilter>::const_iterator iterator = filterMap.find(arg.toLower().mid(1));
+        if (iterator != filterMap.end()){
+            setCustomFilter = true;
+            // use AND logic when compounding filter?
+            if (arg[0] == '-' )
+                customfilter = customfilter & iterator.value();
+            else
+                customfilter = customfilter | iterator.value();
+        }
+    }
+
+    if (setCustomFilter)
+        filter = customfilter;
+
+    return filter;
+}
+
+
 int main(int argc, char *argv[])
 {
     QCoreApplication app(argc, argv);
 
     printMessage("Querying messages...");
 
+    // determine what data options were requested and if help was requested
+    // if no data options were provided default to "subject"
+    QStringList dataOptions;
+    QStringList validDataOptions = QStringList() << "subject" << "date" << "receivedDate" << "status"
+                    << "size" << "priority" << "to" << "cc" << "bcc" << "from"
+                    << "type" << "body" << "attachments";
+    foreach (const QString &arg, app.arguments()){
+        if (arg == "-help"){
+            usage();
+            exit(1);
+        }
+        if (validDataOptions.contains(arg))
+            dataOptions.append(arg);
+    }
+    if (dataOptions.isEmpty())
+        dataOptions.append("subject");
+
 //! [setup-query]
-    // Match all messages whose status field includes the Incoming flag
-    QMessageFilter filter(QMessageFilter::byStatus(QMessage::Incoming));
+    // Create filter to match required messages
+    QMessageFilter filter = createFilter(app.arguments());
+    // instead of the above use the following for a simple filter of all messages whose status field have the Incoming flag to be set, eg incoming emails
+    //QMessageFilter filter(QMessageFilter::byStatus(QMessage::Incoming));
 
     // Order the matching results by their reception timestamp, in descending order
     QMessageSortOrder sortOrder(QMessageSortOrder::byReceptionTimeStamp(Qt::DescendingOrder));
@@ -90,43 +159,40 @@
         if (manager.error() == QMessageManager::NoError) {
             QStringList result;
 
-            if (app.arguments().count() < 2) {
-                // Default to printing only the subject
-                result.append(message.subject());
-            } else {
 //! [generate-output]
-                // Extract the requested data items from this message
-                foreach (const QString &arg, app.arguments().mid(1)) {
-                    if (arg == "subject") {
-                        result.append(message.subject());
-                    } else if (arg == "date") {
-                        result.append(message.date().toLocalTime().toString());
+            // Extract the requested data items from this message
+            foreach (const QString &arg, dataOptions) {
+                if (arg == "subject") {
+                    result.append(message.subject());
+                } else if (arg == "date") {
+                    result.append(message.date().toLocalTime().toString());
 //! [generate-output]
-                    } else if (arg == "receivedDate") {
-                        result.append(message.receivedDate().toLocalTime().toString());
-                    } else if (arg == "size") {
-                        result.append(QString::number(message.size()));
-                    } else if (arg == "priority") {
+                } else if (arg == "receivedDate") {
+                    result.append(message.receivedDate().toLocalTime().toString());
+                } else if (arg == "size") {
+                    result.append(QString::number(message.size()));
+                } else if (arg == "priority") {
                         result.append(message.priority() == QMessage::HighPriority ? "High" : (message.priority() == QMessage::LowPriority ? "Low" : "Normal"));
-                    } else if ((arg == "to") || (arg == "cc") || (arg == "bcc")) {
-                        QStringList addresses;
-                        foreach (const QMessageAddress &addr, (arg == "to" ? message.to() : (arg == "cc" ? message.cc() : message.bcc()))) {
-                            addresses.append(addr.addressee());
-                        }
-                        result.append(addresses.join(","));
-                    } else if (arg == "from") {
-                        result.append(message.from().addressee());
-                    } else if (arg == "type") {
-                        result.append(message.contentType() + '/' + message.contentSubType());
-                    } else if (arg == "body") {
-                        result.append(message.find(message.bodyId()).textContent());
-                    } else if (arg == "attachments") {
-                        QStringList fileNames;
-                        foreach (const QMessageContentContainerId &id, message.attachmentIds()) {
-                            fileNames.append(message.find(id).suggestedFileName());
-                        }
-                        result.append(fileNames.join(","));
+                } else if ((arg == "to") || (arg == "cc") || (arg == "bcc")) {
+                    QStringList addresses;
+                    foreach (const QMessageAddress &addr, (arg == "to" ? message.to() : (arg == "cc" ? message.cc() : message.bcc()))) {
+                        addresses.append(addr.addressee());
                     }
+                    result.append(addresses.join(","));
+                } else if (arg == "from") {
+                    result.append(message.from().addressee());
+                } else if (arg == "type") {
+                    result.append(message.contentType() + '/' + message.contentSubType());
+                } else if (arg == "body") {
+                    result.append(message.find(message.bodyId()).textContent());
+                } else if (arg == "status") {
+                    result.append(QString("0x%1").arg(QString::number(message.status())));
+                } else if (arg == "attachments") {
+                    QStringList fileNames;
+                    foreach (const QMessageContentContainerId &id, message.attachmentIds()) {
+                        fileNames.append(message.find(id).suggestedFileName());
+                    }
+                    result.append(fileNames.join(","));
                 }
             }
 
--- a/examples/sensors/arrowkeys/main.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/sensors/arrowkeys/main.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -1,59 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**   * Redistributions of source code must retain the above copyright
-**     notice, this list of conditions and the following disclaimer.
-**   * Redistributions in binary form must reproduce the above copyright
-**     notice, this list of conditions and the following disclaimer in
-**     the documentation and/or other materials provided with the
-**     distribution.
-**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-**     the names of its contributors may be used to endorse or promote
-**     products derived from this software without specific prior written
-**     permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
 #include <QtCore>
 #include <qaccelerometer.h>
 
 QTM_USE_NAMESPACE
 
 namespace arrows{
-    static const QString ARROW_UP="^", ARROW_DOWN="v", ARROW_LEFT="<",ARROW_RIGHT=">", ARROW_TO=".", ARROW_FROM="x";
+    static const QString ARROW_UP="^", ARROW_DOWN="v", ARROW_LEFT="<",ARROW_RIGHT=">";
 }
 
 class AccelerometerFilter : public QAccelerometerFilter
 {
 public:
-
     bool filter(QAccelerometerReading *reading)
     {
-        QString arrow = getArrowKey(reading->x(), reading->y(), reading->z());
+        QString arrow = getArrowKey(reading->x(), reading->y());
         if (arrow!=exArrow){
             qDebug() << "direction:" << arrow;
             exArrow = arrow;
@@ -63,35 +22,29 @@
 
 private:
     QString exArrow;
-    static const qreal THRESHOLD;
-
-    QString getArrowKey(qreal x, qreal y, qreal z){
-
-        // axis_z: TO or FROM
-        if (abs(y)<THRESHOLD && abs(x)<THRESHOLD) return z>0?(arrows::ARROW_FROM):(arrows::ARROW_TO);
-
+    QString getArrowKey(qreal x, qreal y){
         // axis_x: LEFT or RIGHT
         if (abs(x)>abs(y)) return x>0?(arrows::ARROW_LEFT):(arrows::ARROW_RIGHT);
-
         // axis_y: UP or DOWN
         return y>0?(arrows::ARROW_DOWN):(arrows::ARROW_UP);
     }
-
     static qreal abs(qreal value) {return value<0?-value:value;}
 };
 
-const qreal AccelerometerFilter::THRESHOLD = 0.3;
-
 int main(int argc, char **argv)
 {
     QCoreApplication app(argc, argv);
     QAccelerometer sensor;
     if (!sensor.connectToBackend()) {
         qWarning("No Accelerometer available!");
-        return 1;
+        return EXIT_FAILURE;
     }
     AccelerometerFilter filter;
     sensor.addFilter(&filter);
+
+    qrangelist datarates = sensor.availableDataRates();
+    int i = datarates.size();
+    sensor.setDataRate(datarates.at(i-1).second);
     sensor.start();
 
     return app.exec();
--- a/examples/sensors/orientation/orientation.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/sensors/orientation/orientation.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -1,7 +1,7 @@
 TEMPLATE=app
 TARGET=orientation
 include(../../examples.pri)
-QT+=declarative
+QT+=declarative script network
 CONFIG+=mobility
 MOBILITY+=sensors
 INCLUDEPATH += ../../../src/sensors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/accelerometercontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,47 @@
+
+
+#include "accelerometercontroller.h"
+
+QAccelerometer AccelerometerController::m_accelerometer;
+
+AccelerometerController::AccelerometerController(): InputController(){
+    setDataRate(&m_accelerometer);
+    doConnect();
+}
+
+
+AccelerometerController::~AccelerometerController(){
+    doDisconnect();
+}
+
+
+void AccelerometerController::update()
+{
+    qreal accX = m_accelerometer.reading()->x();
+    qreal accY= m_accelerometer.reading()->y();
+    m_dx = accX*3;
+    m_dy= -accY*3;
+
+    updateCoordinates();
+
+}
+
+
+void AccelerometerController::updateCoordinates(){
+    m_x +=m_dx;
+    m_y +=m_dy;
+
+}
+
+
+
+void AccelerometerController::doConnect(){
+    m_accelerometer.start();
+    connect(&m_accelerometer, SIGNAL(readingChanged()), this, SLOT(update()));
+}
+
+
+void AccelerometerController::doDisconnect(){
+    m_accelerometer.disconnect();
+    m_accelerometer.stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/accelerometercontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,33 @@
+#ifndef ACCELEROMETERCONTROLLER_H
+#define ACCELEROMETERCONTROLLER_H
+
+#include "inputcontroller.h"
+#include <qaccelerometer.h>
+
+
+QTM_USE_NAMESPACE
+
+class AccelerometerController : public InputController
+{
+    Q_OBJECT
+
+public:
+    AccelerometerController();
+    virtual ~AccelerometerController();
+    virtual void updateCoordinates();
+
+
+public slots:
+    virtual void doConnect();
+    virtual void doDisconnect();
+
+private slots:
+    void update();
+
+private:
+    static QAccelerometer m_accelerometer;
+    int m_dx, m_dy;
+
+};
+
+#endif // ACCELEROMETERCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/compasscontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,34 @@
+
+
+#include "compasscontroller.h"
+#include "view.h"
+
+CompassController::CompassController(): m_width(View::m_imageWidth){
+    setDataRate(&m_compass);
+    doConnect();
+}
+
+CompassController::~CompassController(){
+    doDisconnect();
+}
+
+
+void CompassController::update()
+{
+    qreal azimuth = m_compass.reading()->azimuth();
+    m_x = (int)(azimuth * m_width/360);
+}
+
+
+
+void CompassController::doConnect(){
+    m_compass.start();
+    connect(&m_compass, SIGNAL(readingChanged()), this, SLOT(update()));
+
+}
+
+
+void CompassController::doDisconnect(){
+    m_compass.disconnect();
+    m_compass.stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/compasscontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,32 @@
+#ifndef COMPASSCONTROLLER_H
+#define COMPASSCONTROLLER_H
+
+#include "inputcontroller.h"
+#include <qcompass.h>
+
+QTM_USE_NAMESPACE
+
+class CompassController : public InputController
+{
+    Q_OBJECT
+
+public:
+    CompassController();
+    virtual ~CompassController();
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+private slots:
+    void update();
+
+private:
+    QCompass m_compass;
+    int m_width;
+
+};
+
+
+
+#endif // COMPASSCONTROLLER_H
Binary file examples/sensors/panoramaWithSense/images/foreshore_final.jpg has changed
Binary file examples/sensors/panoramaWithSense/images/koskipuisto_pieni.jpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/inputcontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,49 @@
+
+#include "inputcontroller.h"
+
+const QString InputController::QACCELEROMETER="QAccelerometer";
+const QString InputController::QORIENTATIONSENSOR = "QOrientationSensor";
+const QString InputController::QMAGNETOMETER = "QMagnetometer";
+const QString InputController::QROTATIONSENSOR = "QRotationSensor";
+const QString InputController::QTAPSENSOR = "QTapSensor";
+const QString InputController::QCOMPASS = "QCompass";
+const QString InputController::QKEYS = "Keys";
+
+int InputController::m_x =0;
+int InputController::m_y =0;
+
+InputController::InputController() {}
+
+void InputController::keyPressEvent(QKeyEvent*){}
+
+int InputController::getX(){return m_x;}
+
+int InputController::getY() {return m_y;}
+
+void InputController::setX(int x){m_x = x;}
+
+void InputController::setY(int y){m_y = y;}
+
+void InputController::updateCoordinates(){}
+
+
+
+void InputController::setDataRate(QSensor* sensor)
+{
+    qrangelist datarates = sensor->availableDataRates();
+    int i = datarates.size();
+    if (i==0) return;
+    int minRate = datarates.at(i-1).first;
+    int maxRate = datarates.at(i-1).second;
+    if (minRate==maxRate) sensor->setDataRate(minRate);
+    else sensor->setDataRate((int)((maxRate+minRate)/2));
+};
+
+
+void InputController::doConnect(){
+}
+
+
+void InputController::doDisconnect(){
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/inputcontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,42 @@
+#ifndef INPUTCONTROLLER_H
+#define INPUTCONTROLLER_H
+
+#include <QKeyEvent>
+#include <qsensor.h>
+
+QTM_USE_NAMESPACE
+
+class InputController : public QObject
+{
+
+public:
+
+    InputController();
+    virtual ~InputController(){};
+    virtual void updateCoordinates();
+    virtual void keyPressEvent(QKeyEvent *e);
+
+    static int getX(), getY();
+    static void setX(int x), setY(int y);
+
+
+    static const QString QACCELEROMETER,
+    QORIENTATIONSENSOR, QROTATIONSENSOR,
+    QMAGNETOMETER, QTAPSENSOR, QCOMPASS, QKEYS;
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+protected:
+    //current coordinates
+    static int m_x,m_y;
+    void setDataRate(QSensor* sensor);
+
+
+
+
+};
+
+
+#endif // INPUTCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/keycontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,41 @@
+
+#include "keycontroller.h"
+
+KeyController::KeyController(): TimedController(), m_step(5){}
+
+KeyController::~KeyController(){}
+
+
+void KeyController::keyPressEvent(QKeyEvent *e)
+{
+    int code = e->key();
+    handleKeyPress(code);
+    m_step = m_exCode==code && m_exCode > 0? m_step+2 : 5;
+}
+
+
+void KeyController::updateCoordinates() { handleKeyPress(m_exCode);}
+
+
+void KeyController::handleKeyPress(int code){
+    switch (code){
+    case Qt::Key_Right:
+        m_x+=m_step;
+        break;
+    case Qt::Key_Left:
+        m_x-=m_step;
+        break;
+    case Qt::Key_Up:
+        m_y-=m_step;
+        break;
+    case Qt::Key_Down:
+        m_y+=m_step;
+        break;
+    default:
+        m_exCode = 0;
+        return;
+    }
+    m_exCode = code;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/keycontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,25 @@
+#ifndef KEYCONTROLLER_H
+#define KEYCONTROLLER_H
+
+#include "timedcontroller.h"
+#include <QKeyEvent>
+
+class KeyController : public TimedController
+{
+    Q_OBJECT
+
+public:
+    KeyController();
+    virtual ~KeyController();
+    virtual void updateCoordinates();
+
+protected:
+    virtual void keyPressEvent(QKeyEvent *e);
+    void handleKeyPress(int code);
+    int m_exCode;
+    int m_step;
+
+};
+
+
+#endif // KEYCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/magnetometercontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,40 @@
+
+
+#include "magnetometercontroller.h"
+#include "view.h"
+
+MagnetometerController::MagnetometerController(): m_width(View::m_imageWidth){
+    setDataRate(&m_magnetometer);
+    m_magnetometer.setProperty("returnGeoValues", true);
+    doStart();
+}
+
+
+MagnetometerController::~MagnetometerController(){
+    disconnect(&m_magnetometer);
+}
+
+
+void MagnetometerController::update()
+{
+    qreal azimuth = -m_magnetometer.reading()->z();
+    azimuth = azimuth<0?360+azimuth:azimuth;
+    m_x = (int)(-azimuth * m_width/360);
+
+
+    //TODO: consider provide y values based on x and y
+}
+
+
+
+
+void MagnetometerController::doStart(){
+    m_magnetometer.start();
+    connect(&m_magnetometer, SIGNAL(readingChanged()), this, SLOT(update()));
+}
+
+
+void MagnetometerController::doStop(){
+    m_magnetometer.disconnect();
+    m_magnetometer.stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/magnetometercontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,33 @@
+#ifndef MAGNETOMETERCONTROLLER_H
+#define MAGNETOMETERCONTROLLER_H
+
+#include "inputcontroller.h"
+#include <qmagnetometer.h>
+
+
+
+class MagnetometerController : public InputController
+{
+    Q_OBJECT
+
+public:
+    MagnetometerController();
+    virtual ~MagnetometerController();
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+private slots:
+    void update();
+
+private:
+    QTM_NAMESPACE::QMagnetometer  m_magnetometer;
+    int m_width;
+    int m_height;
+
+};
+
+
+
+#endif // MAGNETOMETERCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/main.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "view.h"
+#include <QtGui>
+#include <QtCore/qstate.h>
+
+class Pixmap : public QObject, public QGraphicsPixmapItem
+{
+    Q_OBJECT
+    Q_PROPERTY(QPointF pos READ pos WRITE setPos)
+public:
+            Pixmap(const QPixmap &pix)
+                : QObject(), QGraphicsPixmapItem(pix)
+    {
+        setCacheMode(DeviceCoordinateCache);
+    }
+};
+
+
+int main(int argc, char **argv)
+{
+
+    QApplication app(argc, argv);
+
+
+    Q_INIT_RESOURCE(panoramaWithSense);
+    QGraphicsScene scene(0, 0, 700, 700);
+    View *view = new View(&scene);
+    view->show();
+
+
+#ifdef QT_KEYPAD_NAVIGATION
+    QApplication::setNavigationMode(Qt::NavigationModeCursorAuto);
+#endif
+
+    return app.exec();
+}
+
+
+
+
+#include "main.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/orientationcontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,58 @@
+
+
+#include "orientationcontroller.h"
+
+
+OrientationController::OrientationController(): KeyController(){
+    m_delay=10;
+    m_step=10;
+    doStart();
+
+}
+
+OrientationController::~OrientationController(){
+     doStop();
+}
+
+void OrientationController::updateCoordinates(){
+    handleKeyPress(m_exCode);
+    m_step = m_exCode!=0 ? m_step+5 : 10;
+}
+
+
+void OrientationController::update()
+{
+    switch (m_orientationSensor.reading()->orientation()){
+    case QTM_NAMESPACE::QOrientationReading::TopUp:
+        m_exCode = Qt::Key_Up;
+        break;
+    case QTM_NAMESPACE::QOrientationReading::TopDown:
+        m_exCode = Qt::Key_Down;
+        break;
+    case QTM_NAMESPACE::QOrientationReading::LeftUp:
+        m_exCode = Qt::Key_Left;
+        break;
+    case QTM_NAMESPACE::QOrientationReading::RightUp:
+        m_exCode = Qt::Key_Right;
+        break;
+    default:
+        m_exCode = 0;
+        return;
+    }
+    handleKeyPress(m_exCode);
+}
+
+
+
+
+void OrientationController::doStart(){
+    m_orientationSensor.start();
+    connect(&m_orientationSensor, SIGNAL(readingChanged()), this, SLOT(update()));
+}
+
+
+void OrientationController::doStop(){
+    m_orientationSensor.disconnect();
+    m_orientationSensor.stop();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/orientationcontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,34 @@
+#ifndef ORIENTATIONCONTROLLER_H
+#define ORIENTATIONCONTROLLER_H
+
+
+#include "keycontroller.h"
+#include <qorientationsensor.h>
+
+
+//QTM_USE_NAMESPACE
+
+class OrientationController : public KeyController
+{
+    Q_OBJECT
+
+public:
+    OrientationController();
+    virtual ~OrientationController();
+    virtual void updateCoordinates();
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+private slots:
+    void update();
+
+private:
+    QTM_NAMESPACE::QOrientationSensor m_orientationSensor;
+
+};
+
+
+
+#endif // ORIENTATIONCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/panoramaWithSense.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,26 @@
+include(../sensors.pri)
+QT += gui \
+    core
+HEADERS += inputcontroller.h \
+    keycontroller.h \
+    timedcontroller.h \
+    view.h \
+    accelerometercontroller.h \
+    compasscontroller.h \
+    magnetometercontroller.h \
+    orientationcontroller.h \
+    rotationcontroller.h \
+    tapcontroller.h
+SOURCES += main.cpp \
+    inputcontroller.cpp \
+    keycontroller.cpp \
+    timedcontroller.cpp \
+    view.cpp \
+    accelerometercontroller.cpp \
+    compasscontroller.cpp \
+    magnetometercontroller.cpp \
+    orientationcontroller.cpp \
+    rotationcontroller.cpp \
+    tapcontroller.cpp
+RESOURCES += panoramaWithSense.qrc
+TARGET = panoramaWithSense
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/panoramaWithSense.pro.bck	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,30 @@
+include(../sensors.pri)
+QT += gui \
+    core
+CONFIG += mobility
+CONFIG += debug
+DEFINES+=ENABLE_RUNTIME_SENSORLOG
+MOBILITY += sensors
+HEADERS += inputcontroller.h \
+    keycontroller.h \
+    timedcontroller.h \
+    view.h \
+    accelerometercontroller.h \
+    compasscontroller.h \
+    magnetometercontroller.h \
+    orientationcontroller.h \
+    rotationcontroller.h \
+    tapcontroller.h
+SOURCES += main.cpp \
+    inputcontroller.cpp \
+    keycontroller.cpp \
+    timedcontroller.cpp \
+    view.cpp \
+    accelerometercontroller.cpp \
+    compasscontroller.cpp \
+    magnetometercontroller.cpp \
+    orientationcontroller.cpp \
+    rotationcontroller.cpp \
+    tapcontroller.cpp
+RESOURCES += panoramaWithSense.qrc
+TARGET = panoramaWithSense
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/panoramaWithSense.qrc	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/">
+        <file>images/foreshore_final.jpg</file>
+        <file>images/koskipuisto_pieni.jpg</file>
+    </qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/rotationcontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,45 @@
+#include "rotationcontroller.h"
+
+
+RotationController::RotationController(): InputController(), m_factor(0.5){
+    setDataRate(&m_rotationSensor);
+    doStart();
+}
+
+RotationController::~RotationController(){
+    doStop();
+}
+
+
+void RotationController::update()
+{
+    qreal pitch = m_rotationSensor.reading()->x();
+    qreal roll= m_rotationSensor.reading()->y();
+
+    m_dx = - m_factor* roll;
+    m_dy =  - m_factor * pitch;
+
+    updateCoordinates();
+}
+
+
+void RotationController::updateCoordinates(){
+    m_x +=m_dx;
+    m_y +=m_dy;
+}
+
+
+
+
+void RotationController::doStart(){
+    m_rotationSensor.start();
+    connect(&m_rotationSensor, SIGNAL(readingChanged()), this, SLOT(update()));
+
+}
+
+
+void RotationController::doStop(){
+    m_rotationSensor.disconnect();
+    m_rotationSensor.stop();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/rotationcontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,35 @@
+#ifndef ROTATIONCONTROLLER_H
+#define ROTATIONCONTROLLER_H
+
+
+#include "inputcontroller.h"
+#include <qrotationsensor.h>
+
+QTM_USE_NAMESPACE
+
+class RotationController : public InputController
+{
+    Q_OBJECT
+
+public:
+    RotationController();
+    virtual ~RotationController();
+    virtual void updateCoordinates();
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+private slots:
+    void update();
+
+private:
+    QTM_NAMESPACE::QRotationSensor m_rotationSensor;
+    int m_dx, m_dy;
+    qtimestamp m_exTimestamp;
+    qreal m_factor;
+
+};
+
+
+#endif // ROTATIONCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/rotationsensorcontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,4 @@
+#ifndef ROTATIONSENSORCONTROLLER_H
+#define ROTATIONSENSORCONTROLLER_H
+
+#endif // ROTATIONSENSORCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/tapcontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,138 @@
+
+
+#include "tapcontroller.h"
+
+
+const qreal TapController::m_timewindow=1000;
+
+
+TapController::TapController(): TimedController(), m_step(20){
+    doStart();
+}
+
+TapController::~TapController(){
+    doStop();
+}
+
+
+
+void TapController::update()
+{
+    int direction = m_tap.reading()->tapDirection();
+    switch(direction){
+    case QTapReading::X:
+    case QTapReading::X_Pos:
+    case QTapReading::X_Neg:
+        m_dy=0;
+        setDx(direction);
+        break;
+    case QTapReading::Y:
+    case QTapReading::Y_Pos:
+    case QTapReading::Y_Neg:
+        m_dx = 0;
+        setDy(direction);
+        break;
+    case QTapReading::Undefined:
+    case QTapReading::Z:
+    case QTapReading::Z_Pos:
+    case QTapReading::Z_Neg:
+    default:
+        m_dx = 0; m_dy = 0;
+        return;
+    }    
+
+}
+
+
+void TapController::updateAcce()
+{
+    qreal accX = m_accelerometer.reading()->x();
+    qreal accY= m_accelerometer.reading()->y();
+    m_now = m_accelerometer.reading()->timestamp();
+
+    checkX(accX);
+    checkY(accY);
+}
+
+
+void TapController::updateCoordinates(){
+
+    if (m_now - m_timestampX > m_timewindow){
+        m_absMaxX = 0;
+        m_timestampX = m_now;
+    }
+
+    if (m_now - m_timestampY > m_timewindow){
+        m_absMaxY = 0;
+        m_timestampY = m_now;
+    }
+
+    if (m_dx!=0) m_dx = m_dx>0? m_dx-1: m_dx+1;
+    if (m_dy!=0) m_dy = m_dy>0? m_dy-1: m_dy+1;
+
+    m_x +=m_dx;
+    m_y +=m_dy;
+}
+
+
+void TapController::checkX(qreal accX){
+    if (qAbs(accX)>qAbs(m_absMaxX)){
+        m_absMaxX = accX;
+        m_timestampX = m_now;
+    }
+}
+
+
+void TapController::checkY(qreal accY){
+    if (qAbs(accY)>qAbs(m_absMaxY)){
+        m_absMaxY = accY;
+        m_timestampY = m_now;
+    }
+}
+
+
+void TapController::setDx(int direction){
+    switch(direction){
+    case QTapReading::X:
+        m_dx = m_absMaxX>0?m_step : -m_step;
+        break;
+    case QTapReading::X_Pos:
+        m_dx = m_step;
+        break;
+    case QTapReading::X_Neg:
+        m_dx = -m_step;
+        break;
+    }
+}
+
+void TapController::setDy(int direction){
+    switch(direction){
+    case QTapReading::Y:
+        m_dy = m_absMaxY>0?m_step : - m_step;
+        break;
+    case QTapReading::Y_Pos:
+        m_dy = m_step;
+        break;
+    case QTapReading::Y_Neg:
+        m_dy = -m_step;
+        break;
+    }
+}
+
+
+
+void TapController::doStart(){
+    m_accelerometer.start();
+    connect(&m_accelerometer, SIGNAL(readingChanged()), this, SLOT(updateAcce()));
+
+    m_tap.start();
+    connect(&m_tap, SIGNAL(readingChanged()), this, SLOT(update()));
+}
+
+
+void TapController::doStop(){
+    m_tap.stop();
+    disconnect(&m_tap);
+    m_accelerometer.stop();
+    disconnect(&m_accelerometer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/tapcontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,42 @@
+#ifndef TAPCONTROLLER_H
+#define TAPCONTROLLER_H
+
+#include "timedcontroller.h"
+#include <qtapsensor.h>
+#include <qaccelerometer.h>
+
+QTM_USE_NAMESPACE
+
+class TapController : public TimedController
+{
+    Q_OBJECT
+
+public:
+    TapController();
+    virtual ~TapController();
+    virtual void updateCoordinates();
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+private slots:
+    void update();
+    void updateAcce();
+
+private:
+    void checkX(qreal);
+    void checkY(qreal);
+    void setDx(int);
+    void setDy(int);
+    QTapSensor m_tap;
+    QAccelerometer m_accelerometer;
+    qreal m_absMaxX, m_absMaxY;
+    qtimestamp m_timestampX, m_timestampY, m_now;
+    static const qreal m_timewindow;
+    int m_dx,m_dy;
+    int m_step;
+
+};
+
+#endif // TAPCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/timedcontroller.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,36 @@
+
+
+#include "timedcontroller.h"
+
+TimedController::TimedController(): m_delay(10), m_interval(0){
+    m_exTime = QTime::currentTime();
+    m_exTimestamp =QTime::currentTime();
+    m_timer.setSingleShot(false);
+    doStart();
+}
+
+TimedController::~TimedController(){
+    doStop();
+}
+
+
+void TimedController::handleTimedUpdate()
+{
+    int timeDiff = m_exTime.msecsTo(QTime::currentTime());
+    if (timeDiff<  m_delay) return;
+    updateCoordinates();
+    m_exTime = QTime::currentTime();
+}
+
+
+
+void TimedController::doStart(){
+    m_timer.start(m_delay);
+    connect(&m_timer, SIGNAL(timeout()), this, SLOT(handleTimedUpdate()));
+}
+
+
+void TimedController::doStop(){
+    disconnect(&m_timer);
+    m_timer.stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/timedcontroller.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,35 @@
+#ifndef TIMEDCONTROLLER_H
+#define TIMEDCONTROLLER_H
+
+
+#include <QTime>
+#include <QTimer>
+#include "inputcontroller.h"
+
+class TimedController : public InputController
+{
+    Q_OBJECT
+
+public:
+    TimedController();
+    virtual ~TimedController();
+
+
+public slots:
+    virtual void doStart();
+    virtual void doStop();
+
+private slots:
+    void handleTimedUpdate();
+
+protected:
+    QTimer m_timer;
+    QTime m_exTime;
+    QTime m_exTimestamp;
+    int m_delay;
+    int m_interval;
+
+};
+
+
+#endif // TIMEDCONTROLLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/view.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,362 @@
+#include "view.h"
+#include "accelerometercontroller.h"
+#include "magnetometercontroller.h"
+#include "rotationcontroller.h"
+#include "orientationcontroller.h"
+#include "compasscontroller.h"
+#include "tapcontroller.h"
+#include <QDebug>
+#include <iostream>
+
+
+
+int View::m_imageWidth;
+int View::m_imageHeight;
+QString View::m_currentSensor;
+bool View::m_isStarted = true;
+
+
+
+View::View(QGraphicsScene *scene) :
+        QGraphicsView(scene), m_timer(this) ,m_delay(30){
+
+    qDebug()<<"in View now";
+
+    QPixmap bgPix(":/images/koskipuisto_pieni.jpg");
+    m_pix = bgPix;
+
+    setupWindow();
+
+    int h = height();
+    int y = qAbs(m_imageHeight-h)/2;
+    setSceneRect(0, y, width(), h);
+
+
+    m_sensors.append(InputController::QACCELEROMETER);
+    m_sensors.append(InputController::QORIENTATIONSENSOR);
+    m_sensors.append(InputController::QMAGNETOMETER);
+    m_sensors.append(InputController::QROTATIONSENSOR);
+    m_sensors.append(InputController::QTAPSENSOR);
+    m_sensors.append(InputController::QCOMPASS);
+    m_sensors.append(InputController::QKEYS);
+
+
+    m_menu = new QMenu(this);
+    createActions();
+    handleAction(NULL,InputController::QACCELEROMETER);
+
+    m_timer.setSingleShot(false);
+    m_timer.start(m_delay);
+
+    connect(&m_timer, SIGNAL(timeout()), this, SLOT(update()));
+    connect(this,SIGNAL(sceneRectChanged(QRectF)), this, SLOT(checkSensors(QRectF)));
+
+}
+
+
+View::~View(){
+    m_timer.stop();
+    if (m_controller) delete m_controller;
+    if (m_exController) delete m_exController;
+}
+
+
+void View::resizeEvent(QResizeEvent *event)
+{
+    QGraphicsView::resizeEvent(event);
+    fitInView(sceneRect(), Qt::KeepAspectRatio);
+}
+
+
+
+void View::handleAction(QString oldSensor, QString newSensor){
+
+    m_menu->setVisible(false);
+
+    if (oldSensor==newSensor) return;
+
+
+    QList<QAction*> tmpActions = m_menu->actions();
+    for (int i=0; i<tmpActions.length(); i++){
+        if (tmpActions.at(i)->text() ==  oldSensor){
+            tmpActions.at(i)->setEnabled(true);
+            continue;
+        }
+        if (tmpActions.at(i)->text() == newSensor){
+            tmpActions.at(i)->setEnabled(false);
+        }
+    }
+    m_currentSensor = newSensor;
+    switchController(m_currentSensor);
+
+}
+
+
+
+void View::createActions()
+{
+
+    for (int i=0; i<m_sensors.length();i++){
+        QAction* tmp = new QAction(m_sensors.at(i), this);
+
+        const QString sensor = m_sensors.at(i);
+        do{
+            if (sensor==InputController::QACCELEROMETER){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startAccelerometer()));
+                break;
+            }
+            if (sensor==InputController::QORIENTATIONSENSOR){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startOrientationSensor()));
+                break;
+            }
+            if (sensor==InputController::QROTATIONSENSOR){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startRotationSensor()));
+                break;
+            }
+            if (sensor==InputController::QMAGNETOMETER){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startMagnetometer()));
+                break;
+            }
+            if (sensor==InputController::QTAPSENSOR){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startTapSensor()));
+                break;
+            }
+            if (sensor==InputController::QCOMPASS){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startCompass()));
+                break;
+            }
+            if (sensor==InputController::QKEYS){
+                connect(tmp, SIGNAL(triggered()), this, SLOT(startKeys()));
+                break;
+            }
+        }while (true);
+        m_menu->addAction(tmp);
+    }
+
+}
+
+void View::startAccelerometer(){
+    handleAction(m_currentSensor, InputController::QACCELEROMETER);
+}
+
+void View::startOrientationSensor(){
+    handleAction(m_currentSensor, InputController::QORIENTATIONSENSOR);
+}
+
+void View::startTapSensor(){
+    handleAction(m_currentSensor, InputController::QTAPSENSOR);
+}
+
+void View::startMagnetometer(){
+    handleAction(m_currentSensor, InputController::QMAGNETOMETER);
+}
+
+void View::startRotationSensor(){
+    handleAction(m_currentSensor, InputController::QROTATIONSENSOR);
+}
+
+void View::startKeys(){
+    handleAction(m_currentSensor, InputController::QKEYS);
+}
+
+void View::startCompass(){
+    handleAction(m_currentSensor, InputController::QCOMPASS);
+}
+
+
+
+
+void View::keyPressEvent(QKeyEvent *e)
+{
+    if (m_currentSensor!=InputController::QKEYS) return;
+
+    if (m_controller) m_controller->keyPressEvent(e);
+}
+
+
+void View::switchController(QString sensor){
+
+    if (m_controller){
+        delete m_controller;
+        m_controller =0;
+    }
+
+    if (sensor==InputController::QACCELEROMETER){
+        m_controller = new AccelerometerController();
+        return;
+    }
+    if (sensor==InputController::QROTATIONSENSOR){
+        m_controller = new RotationController();
+        return;
+    }
+    if (sensor==InputController::QMAGNETOMETER){
+        m_controller = new MagnetometerController();
+        return;
+    }
+    if (sensor==InputController::QORIENTATIONSENSOR){
+        m_controller = new OrientationController();
+        return;
+    }
+    if (sensor==InputController::QTAPSENSOR){
+        m_controller = new TapController();
+        return;
+    }
+    if (sensor==InputController::QCOMPASS){
+        m_controller = new CompassController();
+        return;
+    }
+    if (sensor==InputController::QKEYS){
+        m_controller = new KeyController();
+        return;
+    }
+
+
+
+}
+
+
+int View::checkX(int x){
+    int tmpX = qAbs(x) < m_imageWidth ? x : x % m_imageWidth;
+    m_mouseMode?m_exController->setX(tmpX):m_controller->setX(tmpX);
+    return tmpX;
+
+}
+
+int View::checkY(int y){
+    int limit = m_imageHeight-height();
+    if (y<0){
+        y = limit<0?-limit/2:0;
+    }
+    else if (limit<0){
+        y=-limit/2;
+    }
+    else if (y > limit){y=limit;}
+
+    m_mouseMode?m_exController->setY(y):m_controller->setY(y);
+    return y;
+}
+
+
+
+void View::mousePressEvent ( QMouseEvent* ){
+    m_mousePressTime = QTime::currentTime();
+    m_exController = m_controller;
+    m_mouseMode = false;
+}
+
+
+void View::mouseMoveEvent(QMouseEvent* event){
+
+    // first time
+    if (!m_mouseMode){
+        m_mouseMode = true;
+        m_eventX = event->x();
+        m_eventY = event->y();
+        return;
+    }
+
+    if (m_menu->isVisible()){
+        if (m_mousePressTime.msecsTo(QTime::currentTime())>300)
+            m_menu->setVisible(false);
+    }
+
+    int cur_x = event->x();
+    int cur_y = event->y();
+
+    m_dx = m_eventX - cur_x;
+    m_dy = m_eventY - cur_y;
+
+    m_eventX = cur_x;
+    m_eventY = cur_y;
+
+    update();
+
+}
+
+
+
+void View::mouseReleaseEvent(QMouseEvent* event){
+    m_controller = m_exController;
+    m_exController = 0;
+    m_mouseMode = false;
+
+
+    if (m_menu->isVisible()){
+        m_menu->setVisible(false);
+        return;
+    }
+
+    // slow press -> move
+    if (m_mousePressTime.msecsTo(QTime::currentTime())>300) return;
+
+    // quick press -> show menu
+    int x = event->x();
+    int y = event->y();
+    m_menu->move(x, y);
+    m_menu->setVisible(true);
+
+}
+
+
+void View::update(){
+
+    if (!m_isStarted) return;
+
+    if (!m_mouseMode && m_controller)
+        m_controller->updateCoordinates();
+
+    if (m_menu->isVisible()){
+        if (m_mousePressTime.msecsTo(QTime::currentTime())>5000)
+            m_menu->setVisible(false);
+    }
+
+
+    int x = m_mouseMode?m_exController->getX():m_controller->getX();
+    int y = m_mouseMode?m_exController->getY():m_controller->getY();
+
+    x = checkX(m_mouseMode?x+m_dx:x);
+    y = checkY(m_mouseMode?y+m_dy:y);
+
+    setSceneRect(x, y, width(), height());
+}
+
+
+
+
+void View::setupWindow(){
+    int w = m_pix.width();
+    int h = m_pix.height();
+
+    if (m_imageWidth>0 && m_imageHeight > 0){
+        int x = m_controller? m_controller->getX(): (m_exController?m_exController->getX():0);
+        int y = m_controller? m_controller->getY(): (m_exController?m_exController->getY():0);
+
+        checkX(x*w/m_imageWidth);
+        checkY(y*h/m_imageHeight);
+    }
+
+
+    m_imageWidth = w;
+    m_imageHeight = h;
+
+
+    setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+    setBackgroundBrush(m_pix);
+    setCacheMode(QGraphicsView::CacheBackground);
+    setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
+    setWindowTitle("PanoramaWithSense");
+
+}
+
+
+ void View::focusInEvent(QFocusEvent*) {
+    if (m_controller) m_controller->doStart();
+    m_isStarted = true;
+}
+
+ void View::focusOutEvent(QFocusEvent*) {
+    if (m_controller) m_controller->doStop();
+    m_isStarted = false;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/sensors/panoramaWithSense/view.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,77 @@
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <QPixmap>
+#include <QGraphicsView>
+#include <QMenu>
+#include <QTimer>
+#include <QTime>
+#include "inputcontroller.h"
+
+
+
+
+class View : public QGraphicsView
+{
+    Q_OBJECT
+
+public:
+    View(QGraphicsScene *scene);
+    virtual ~View();
+    static int m_imageWidth;
+
+
+protected:
+
+    virtual void resizeEvent(QResizeEvent *event);
+    virtual void keyPressEvent(QKeyEvent *e);
+    virtual void mousePressEvent ( QMouseEvent * event );
+    virtual void mouseMoveEvent(QMouseEvent* event);
+    virtual void mouseReleaseEvent(QMouseEvent* event);
+
+    virtual void focusInEvent(QFocusEvent *);
+    virtual void focusOutEvent(QFocusEvent *);
+
+
+
+
+private slots:
+    void startAccelerometer();
+    void startTapSensor();
+    void startMagnetometer();
+    void startRotationSensor();
+    void startOrientationSensor();
+    void startCompass();
+    void startKeys();
+    void update();
+
+private:
+    int checkX(int x);
+    int checkY(int y);
+    void createActions();
+    void handleAction(QString oldSensor, QString newSensor);
+    void setupWindow();
+    void switchController(QString sensor);
+
+    static int m_imageHeight;
+
+    static QString m_currentSensor;
+    QList<QString> m_sensors;
+    QTimer m_timer;
+    InputController *m_controller;
+    InputController *m_exController;
+    int m_delay;
+    QTime m_mousePressTime;
+    QMenu* m_menu;
+    bool m_mouseMode;
+    int m_eventX, m_eventY;
+    int m_dx, m_dy;
+    QTime m_zoomTime;
+    QPixmap m_pix;
+    static bool m_isStarted;
+
+
+};
+
+
+#endif // VIEW_H
--- a/examples/sensors/sensors.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/sensors/sensors.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -1,6 +1,6 @@
 TEMPLATE = subdirs
 
-SUBDIRS += accel arrowkeys metadata
+SUBDIRS += accel arrowkeys metadata metadata2
 
 contains(QT_CONFIG, declarative) {
     SUBDIRS += orientation
--- a/examples/sensors/test_manual/test_manual.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/examples/sensors/test_manual/test_manual.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -1,8 +1,9 @@
-include(../../../common.pri)
-TEMPLATE = app
+INCLUDEPATH += ../../../src/sensors
+QT += core
 QT += testlib
+CONFIG += qt
 CONFIG += testcase
 CONFIG += mobility
-MOBILITY += sensors
 HEADERS += sensorslotclass.h
 SOURCES += test_manual.cpp
+MOBILITY += sensors
--- a/features/mobilityconfig.prf	Fri Sep 17 08:34:34 2010 +0300
+++ b/features/mobilityconfig.prf	Mon Oct 04 01:37:06 2010 +0300
@@ -1,5 +1,5 @@
 MOBILITY_CONFIG=bearer location publishsubscribe messaging multimedia systeminfo serviceframework sensors contacts versit 
-MOBILITY_VERSION = 1.0.2
+MOBILITY_VERSION = 1.0.3
 MOBILITY_MAJOR_VERSION = 1
 MOBILITY_MINOR_VERSION = 0
-MOBILITY_PATCH_VERSION = 2
+MOBILITY_PATCH_VERSION = 3
--- a/features/qtservice.mk	Fri Sep 17 08:34:34 2010 +0300
+++ b/features/qtservice.mk	Mon Oct 04 01:37:06 2010 +0300
@@ -20,10 +20,10 @@
 #we cannot use the path specified in the QTSERVICE_DESCRIPTOR option, so use the default path
 DES_PATH=$(EPOCROOT)epoc32/data/z/private/2002AC7F/des/$(QTSERVICE_DESCRIPTOR)
 
-FINAL: 
+MAKMAKE: 
 	@$(SFWTOOL) $(QTSERVICE_TARGET) $(QTSERVICE_INITIALIZE) add $(DES_PATH)
 
 CLEAN: 
 	@$(SFWTOOL) $(QTSERVICE_TARGET) $(QTSERVICE_INITIALIZE) remove $(DES_PATH)
 
-MAKMAKE BLD SAVESPACE FREEZE LIB CLEANLIB RESOURCE RELEASABLES: do_nothing
+BLD SAVESPACE FREEZE LIB CLEANLIB RESOURCE RELEASABLES FINAL: do_nothing
--- a/plugins/contacts/contacts.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/contacts.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -6,12 +6,17 @@
 
 symbian {
     SUBDIRS += symbian
-    contains(build_unit_tests, yes):SUBDIRS += symbian/tsrc
-    
+
+    ## build symbian-specific unit tests.
+    contains(build_unit_tests, yes):SUBDIRS += symbian/plugin/tsrc
+
     # SIM backend depends on etel MM APIs
     contains(symbiancntsim_enabled, yes) {
         SUBDIRS += symbiansim
+
+        ## build symbiansim-specific unit tests.
         contains(build_unit_tests, yes):SUBDIRS += symbiansim/tsrc
+
         message("Symbian SIM backend enabled")
     } else {
         message("Symbian SIM backend disabled")
--- a/plugins/contacts/maemo5/qcontactabook.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/maemo5/qcontactabook.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -327,6 +327,7 @@
   return rtn;
   */
 }
+#include "qcontactdetail_p.h"
 
 QContact* QContactABook::getQContact(const QContactLocalId& contactId, QContactManager::Error* error) const
 {
@@ -824,18 +825,11 @@
   /* Note */
   detailList << getNoteDetail(eContact);
 
-  /* Online Account & presences*/
-  QList<QContactOnlineAccount*> onlineAccounts;
-  QList<QContactPresence*> presences;
-  getOnlineAccountAndPresenceDetails(eContact, onlineAccounts, presences);
-  
+  /* Online Account */
+  QList<QContactOnlineAccount*> onlineAccountList = getOnlineAccountDetail(eContact);
   QContactOnlineAccount* onlineAccount;
-  foreach(onlineAccount, onlineAccounts)
+  foreach(onlineAccount, onlineAccountList)
     detailList << onlineAccount;
-  
-  QContactPresence* presence;
-  foreach(presence, presences)
-    detailList << presence;
 
   /* Organization */
   detailList << getOrganizationDetail(eContact);
@@ -902,15 +896,29 @@
 
   QCM5_DEBUG << "Getting aContact with id " << m_localIds[contactId] << "local contactId is" << contactId;
 
-  if(QString::fromAscii(m_localIds[contactId]).compare("osso-abook-self") == 0) {
+  if(QString(m_localIds[contactId]).compare("osso-abook-self") == 0) {
     *error = QContactManager::NoError;
     rtn = A_CONTACT(osso_abook_self_contact_get_default());
   } else {
-    GList* c = osso_abook_aggregator_lookup(m_abookAgregator, m_localIds[contactId]);
-    if (c)
-      rtn = A_CONTACT(c->data);
-    *error = rtn ? QContactManager::NoError : QContactManager::DoesNotExistError;
-    return rtn;
+    EBookQuery* query;
+    GList* contacts;
+
+    query = e_book_query_field_test(E_CONTACT_UID, E_BOOK_QUERY_IS, m_localIds[contactId]);
+    contacts = osso_abook_aggregator_find_contacts(m_abookAgregator, query);
+    if (query)
+        e_book_query_unref(query);
+
+    if (g_list_length(contacts) == 1) {
+      *error = QContactManager::NoError;
+      rtn = A_CONTACT(contacts->data);
+    } else if (g_list_length(contacts) == 0) {
+      *error = QContactManager::DoesNotExistError;
+    } else {
+      // Several contacts have the same UID or the contactId belongs to a roster contact.
+      *error = QContactManager::UnspecifiedError;
+    }
+    if (contacts)
+      g_list_free(contacts);
   }
 
   return rtn;
@@ -972,15 +980,14 @@
     // Set Address Values
     GList *v = NULL;
     v =e_vcard_attribute_get_values(attr);
-    if (!v) {
-      // ADR attribute data is corrupted.  Skipping.
-      g_list_free(attrList);
-      return rtnList;
+    if (!v)
+      qFatal("ADR attribute data is corrupted"); 
+    if (g_list_length(v) != 7){
+      g_list_free(v);
+      qCritical() << "ADR attribute data is corrupted"; 
     }
-
     int i = 0;
-    while (v && i < 7) {
-      // we only deal with the first 7 fields: pobox, extension, street, locality, region, postcode, country.
+    while (v){
       map[addressFields[i]] = QString::fromUtf8(CONST_CHAR(v->data));
       i++;
       v = v->next;
@@ -993,6 +1000,7 @@
   }
   
   g_list_free(attrList);
+  
   return rtnList;
 }
 
@@ -1226,52 +1234,28 @@
     return QStringList();
 }
 
-#if 0
-// BUG? This code has been commented out because osso_abook_presence_get_presence_status returns empty strings
-static QContactPresence::PresenceState telepathyStatusToPresenceState(const QString& status){
-  if (status == "offline")
-    return QContactPresence::PresenceOffline;
-  else if (status == "unknown" || status == "error")
-    return QContactPresence::PresenceUnknown;
-  else if (status == "available")
-    return QContactPresence::PresenceAvailable;
-  else if (status == "away" || status == "brb" ) //Be Right Back (a more specific form of Away)
-    return QContactPresence::PresenceAway;
-  else if (status == "busy" || status == "dnd") //Do Not Disturb (a more specific form of Busy)
-    return QContactPresence::PresenceBusy;
-  else if (status == "xa") //Extended Away
-    return QContactPresence::PresenceExtendedAway;
-  else if (status == "hidden") // "Invisible" or "Appear Offline"
-    return QContactPresence::PresenceHidden;
-}
-#endif
-
-void QContactABook::getOnlineAccountAndPresenceDetails(EContact *eContact, 
-                                                      QList<QContactOnlineAccount*>& onlineAccounts,
-                                                      QList<QContactPresence*>& presences) const
+QList<QContactOnlineAccount*> QContactABook::getOnlineAccountDetail(EContact *eContact) const
 {
+  QList<QContactOnlineAccount*> rtnList;
+  
+  // Get VCards that store Online Account Details.
   const QStringList telepathyVCards = vcardsManagedByTelepathy();
   
-  // Parsing Attributes associated to the Telepathy VCards
+  // Parsing Attributes associated to the previous VCards
   GList *attributeList = e_vcard_get_attributes((EVCard*)eContact);
   GList *node;
 
   if (!attributeList)
-    return;
+    return rtnList;
   
   for (node = attributeList; node != NULL; node = g_list_next (node)) {
-    QContactOnlineAccount* onlineAccount = new QContactOnlineAccount;
-    QContactPresence* contactPresence = new QContactPresence;
-    
+    QContactOnlineAccount* rtn = new QContactOnlineAccount;
     const char* accountUri = NULL;
     const char* serviceProvider = NULL;
     const char* accountPath = NULL; // Outgoing account path eg: SERVICE_NAME/PROTOCOL_NAME/USER_NAME
-    EVCardAttribute* attr = NULL;
-    QVariantMap map;
-    QString presenceMsg, presenceIcon, presenceDisplayState, presenceNickname;
+    
     QStringList caps;
-    
-    attr = (EVCardAttribute*)node->data;
+    EVCardAttribute* attr = (EVCardAttribute*)node->data;
     if (!attr)
       continue;
     
@@ -1284,50 +1268,32 @@
     accountUri = e_vcard_attribute_get_value(attr);
 
     // Get AccountPath and service provider for the roster contact associated to the attribute
-    // Note: there should be just one roster contact associated to the attribute
     GList* rContacts = osso_abook_contact_find_roster_contacts_for_attribute(A_CONTACT(eContact), attr);
     for (GList * node = rContacts; node != NULL; node = g_list_next(node)){
       OssoABookContact* c = NULL;
+      McAccount* a = NULL;
       c = A_CONTACT(node->data);
       if (c) {
-       McAccount* a = NULL;
-       OssoABookPresence *p = NULL;
-       
        a = osso_abook_contact_get_account(c);
        if (a){
          accountPath = a->name;
          serviceProvider = mc_account_compat_get_profile(a);
        }
-       
-       p = OSSO_ABOOK_PRESENCE(c);
-       presenceMsg = QString::fromUtf8(osso_abook_presence_get_presence_status_message(p));
-       presenceIcon = QString::fromUtf8(osso_abook_presence_get_icon_name(p));
-       // presenceState = QString::fromUtf8(osso_abook_presence_get_presence_status(p)); //BUG in osso_abook_presence_get_presence_status??
-       presenceDisplayState = QString::fromUtf8(osso_abook_presence_get_display_status(p));
-       presenceNickname = QString::fromUtf8(osso_abook_contact_get_display_name(c));
-       // Set OnlineAccount details
-       map.clear();
-       map[QContactOnlineAccount::FieldAccountUri] = accountUri;
-       map[QContactOnlineAccount::FieldCapabilities] = serviceProviderCapabilities(serviceProvider);
-       map[QContactOnlineAccount::FieldServiceProvider] = serviceProvider; // eg: facebook-chat,
-       map["AccountPath"] = accountPath;
-       setDetailValues(map, onlineAccount);
-       onlineAccounts << onlineAccount;
-    
-       // Set OnlinePresence details
-       map.clear();
-       map[QContactDetail::FieldLinkedDetailUris] = accountUri;
-       map[QContactPresence::FieldCustomMessage] = presenceMsg;
-       map[QContactPresence::FieldPresenceStateImageUrl] = presenceIcon;
-       map[QContactPresence::FieldPresenceStateText] = presenceDisplayState;
-       map[QContactPresence::FieldNickname] = presenceNickname;
-       //map[QContactPresence::FieldPresenceState] = telepathyStatusToPresenceState(presenceState);
-       //map[QContactPresence::FieldTimestamp] = ;
-       setDetailValues(map, contactPresence);
-       presences << contactPresence;
       }
     }
+    
+    // Set details
+    QVariantMap map;
+    map[QContactOnlineAccount::FieldAccountUri] = accountUri;
+    map[QContactOnlineAccount::FieldCapabilities] = serviceProviderCapabilities(serviceProvider);
+    map[QContactOnlineAccount::FieldServiceProvider] = serviceProvider; // eg: facebook-chat,
+    map["AccountPath"] = accountPath;
+    setDetailValues(map, rtn);
+    
+    rtnList << rtn;
   }
+  
+  return rtnList;
 }
 
 QContactOrganization* QContactABook::getOrganizationDetail(EContact *eContact) const
@@ -1388,6 +1354,134 @@
   return rtnList;
 }
 
+
+QList<QContactPresence*> QContactABook::getPresenceDetail(EContact *eContact) const
+{
+  QList<QContactPresence*> rtnList;
+
+  QStringList evcardToSkip = vcardsManagedByTelepathy();
+
+  // Gets info of online accounts from roster contacts associated to the master one
+  if (!osso_abook_contact_is_roster_contact (A_CONTACT(eContact))) {
+    QContactPresence* rtn = new QContactPresence;
+
+    GList *contacts = osso_abook_contact_get_roster_contacts(A_CONTACT(eContact));
+    GList *node;
+    for (node = contacts; node != NULL; node = g_list_next(node)){
+      OssoABookContact *rosterContact = A_CONTACT(node->data);
+
+      McProfile* id = osso_abook_contact_get_profile(rosterContact);
+      McAccount* account = osso_abook_contact_get_account(rosterContact);
+
+      // Avoid to look for Roster contacts into the VCard
+      QString accountVCard = mc_profile_get_vcard_field(id);
+      evcardToSkip.removeOne(accountVCard);
+
+      // Presence
+      OssoABookPresence *presence = OSSO_ABOOK_PRESENCE (rosterContact);
+      TpConnectionPresenceType presenceType = osso_abook_presence_get_presence_type (presence);
+      QString presenceTypeString;
+      QContactPresence::PresenceState presenceTypeEnum;
+      switch (presenceType) {
+        case TP_CONNECTION_PRESENCE_TYPE_UNSET: presenceTypeString = "Unset"; presenceTypeEnum = QContactPresence::PresenceUnknown; break;
+        case TP_CONNECTION_PRESENCE_TYPE_OFFLINE: presenceTypeString = "Offline"; presenceTypeEnum = QContactPresence::PresenceOffline; break;
+        case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE: presenceTypeString = "Available"; presenceTypeEnum = QContactPresence::PresenceAvailable; break;
+        case TP_CONNECTION_PRESENCE_TYPE_AWAY: presenceTypeString = "Away"; presenceTypeEnum = QContactPresence::PresenceAway; break;
+        case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY: presenceTypeString = "Extended Away"; presenceTypeEnum = QContactPresence::PresenceExtendedAway; break;
+        case TP_CONNECTION_PRESENCE_TYPE_HIDDEN: presenceTypeString = "Hidden"; presenceTypeEnum = QContactPresence::PresenceHidden; break;
+        case TP_CONNECTION_PRESENCE_TYPE_BUSY: presenceTypeString = "Busy"; presenceTypeEnum = QContactPresence::PresenceBusy; break;
+        case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN: presenceTypeString = "Unknown"; presenceTypeEnum = QContactPresence::PresenceUnknown; break;
+        case TP_CONNECTION_PRESENCE_TYPE_ERROR: presenceTypeString = "Error"; presenceTypeEnum = QContactPresence::PresenceUnknown; break;
+        default:
+          qCritical() << "Presence type is not valid" << presenceType;
+      }
+
+      QVariantMap map; // XXX FIXME
+      map[QContactPresence::FieldNickname] = osso_abook_contact_get_display_name(rosterContact);
+      map[QContactPresence::FieldPresenceState] = presenceTypeEnum;
+      map[QContactPresence::FieldPresenceStateText] = QString::fromUtf8(osso_abook_presence_get_presence_status_message(presence));
+      map[QContactPresence::FieldLinkedDetailUris] = mc_profile_get_unique_name(id); //use the unique name as a detail uri of the online account.
+      map["AccountPath"] = account->name; //MCAccount name: variable part of the D-Bus object path.
+
+      setDetailValues(map, rtn);
+    }
+    rtnList << rtn;
+    g_list_free (contacts);
+  }
+
+  /* Users can add Online account details manually. Eg: IRC username.
+   * evcardToSkip stringlist contains evCard attributes that have been already processed.
+   */
+  GList *attributeList = e_vcard_get_attributes((EVCard*)eContact);
+  GList *node;
+
+  if (attributeList) {
+    for (node = attributeList; node != NULL; node = g_list_next (node)) {
+      EVCardAttribute* attr = (EVCardAttribute*)node->data;
+      if (!attr)
+        continue;
+      QString attributeName = e_vcard_attribute_get_name(attr);
+
+      // Skip attributes processed scanning roster contacts.
+      if (!evcardToSkip.contains(attributeName))
+        continue;
+
+      GList *params = e_vcard_attribute_get_params(attr);
+      GList *nodeP;
+      QString type;
+      // If the parameter list lenght is 1, X-OSSO-VALID is not specified
+      bool ossoValidIsOk = (g_list_length(params) == 1) ? true : false;
+
+      for (nodeP = params; nodeP != NULL; nodeP = g_list_next (nodeP)) {
+        EVCardAttributeParam* p = (EVCardAttributeParam*) nodeP->data;
+        QString paramName = e_vcard_attribute_param_get_name(p);
+        bool attrIsType = false;
+        bool attrIsOssoValid = false;
+
+        //If type is empty check if the attribute is "TYPE"
+        if (type.isEmpty())
+          attrIsType = paramName.contains(EVC_TYPE);
+
+        if(!ossoValidIsOk)
+          attrIsOssoValid = paramName.contains("X-OSSO-VALID");
+
+        if (!attrIsType && !attrIsOssoValid) {
+          //qWarning () << "Skipping attribute parameter checking for" << paramName;
+          continue;
+        }
+
+        GList *values = e_vcard_attribute_param_get_values(p);
+        GList *node;
+        for (node = values; node != NULL; node = g_list_next (node)) {
+          QString attributeParameterValue = CONST_CHAR(node->data);
+          if (attrIsOssoValid) {
+            ossoValidIsOk = (attributeParameterValue == "yes")? true : false;
+            if (!ossoValidIsOk) {
+              //qWarning() << "X-OSSO-VALID is false.";
+              break;
+            }
+          } else if (type.isEmpty()) {
+            type = attributeParameterValue;
+            if (type.isEmpty())
+              qCritical() << "TYPE is empty";
+          }
+        }
+
+        if (ossoValidIsOk && !type.isEmpty()) {
+          QContactPresence* rtn = new QContactPresence;
+          QVariantMap map;
+          map[QContactPresence::FieldNickname] = QString::fromUtf8(e_vcard_attribute_get_value(attr));
+          map[QContactPresence::FieldLinkedDetailUris] = type; // XXX FIXME
+          setDetailValues(map, rtn);
+          rtnList << rtn;
+        }
+      }
+    }
+  }
+
+  return rtnList;
+}
+
 QContactTimestamp* QContactABook::getTimestampDetail(EContact *eContact) const
 {
    QContactTimestamp* rtn = new QContactTimestamp;
--- a/plugins/contacts/maemo5/qcontactabook_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/maemo5/qcontactabook_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -119,9 +119,7 @@
   QContactGender* getGenderDetail(EContact *eContact) const;
   QContactGuid* getGuidDetail(EContact *eContact) const;
   QContactNote* getNoteDetail(EContact *eContact) const;
-  void getOnlineAccountAndPresenceDetails(EContact *eContact, 
-                                         QList<QContactOnlineAccount*>& onlineAccounts,
-                                         QList<QContactPresence*>& presences) const;
+  QList<QContactOnlineAccount*> getOnlineAccountDetail(EContact *eContact) const;
   QContactOrganization* getOrganizationDetail(EContact *eContact) const;
   QList<QContactPhoneNumber*> getPhoneDetail(EContact *eContact) const;
   QList<QContactPresence*> getPresenceDetail(EContact *eContact) const;
--- a/plugins/contacts/maemo5/qcontactmaemo5backend.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/maemo5/qcontactmaemo5backend.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -295,6 +295,9 @@
     QContactDetailFieldDefinition gsfd; //Generic string field definition
     gsfd.setDataType(QVariant::String);
 
+    // XXX NOTE: only QContactPhoneNumber, QContactOnlineAccount,
+    // QContactEmailAddress and QContactAddress are currently non-unique.
+    
     // QContactAddress
     fields = defns[contactType][QContactAddress::DefinitionName].fields();
     fields.remove(QContactAddress::FieldSubTypes);
@@ -405,13 +408,9 @@
     defns[contactType][QContactPhoneNumber::DefinitionName].setFields(fields);
     defns[contactType][QContactPhoneNumber::DefinitionName].setUnique(false);
 
-    // QContactPresence
-    fields = defns[contactType][QContactPresence::DefinitionName].fields();
-    fields.remove(QContactPresence::FieldTimestamp);
-    fields.remove(QContactPresence::FieldPresenceState);
-    defns[contactType][QContactPresence::DefinitionName].setFields(fields);
-    defns[contactType][QContactPresence::DefinitionName].setUnique(false);
-    
+    // No QContactPresence
+    defns[contactType].remove(QContactPresence::DefinitionName);
+
     // No QContactRingtone
     defns[contactType].remove(QContactRingtone::DefinitionName);
     
@@ -425,7 +424,7 @@
     fields = defns[contactType][QContactTimestamp::DefinitionName].fields();
     fields.remove(QContactDetail::FieldContext);
     defns[contactType][QContactTimestamp::DefinitionName].setFields(fields);
-    
+
     // QContactType
     fields = defns[contactType][QContactType::DefinitionName].fields();
     fields.remove(QContactDetail::FieldContext);
@@ -621,7 +620,7 @@
      } break;
      default:
      {
-       // this engine currently does not support mutable definitions.
+       // symbian engine currently does not support mutable definitions.
      } break;
 
     
--- a/plugins/contacts/symbian/contactsmodel/bwins/cntmodlv2_sqliteu.def	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/bwins/cntmodlv2_sqliteu.def	Mon Oct 04 01:37:06 2010 +0300
@@ -539,4 +539,6 @@
 	?AddObserverV2L@CContactDatabase@@QAEXAAVMContactDbObserverV2@@@Z @ 538 NONAME ; void CContactDatabase::AddObserverV2L(class MContactDbObserverV2 &)
 	?OpenV2L@CContactDatabase@@SAPAV1@W4TThreadAccess@1@@Z @ 539 NONAME ; class CContactDatabase * CContactDatabase::OpenV2L(enum CContactDatabase::TThreadAccess)
 	?CreateV2L@CContactDatabase@@SAPAV1@W4TThreadAccess@1@@Z @ 540 NONAME ; class CContactDatabase * CContactDatabase::CreateV2L(enum CContactDatabase::TThreadAccess)
+	?RemoveContactsFromGroupL@CContactDatabase@@QAEXAAV?$RArray@J@@J@Z @ 541 NONAME ; void CContactDatabase::RemoveContactsFromGroupL(class RArray<long> &, long)
+	?AddContactsToGroupL@CContactDatabase@@QAEXAAV?$RArray@J@@J@Z @ 542 NONAME ; void CContactDatabase::AddContactsToGroupL(class RArray<long> &, long)
 
--- a/plugins/contacts/symbian/contactsmodel/bwins/cntplsqlu.def	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/bwins/cntplsqlu.def	Mon Oct 04 01:37:06 2010 +0300
@@ -11,7 +11,4 @@
 	?RegisterDbObserver@CPersistenceLayer@@QAEXAAVMContactDbObserverV2@@@Z @ 10 NONAME ; void CPersistenceLayer::RegisterDbObserver(class MContactDbObserverV2 &)
 	?TransactionManager@CPersistenceLayer@@QAEAAVMLplTransactionManager@@XZ @ 11 NONAME ; class MLplTransactionManager & CPersistenceLayer::TransactionManager(void)
 	?KContactsModelSqliteDbCacheSize@@3HB @ 12 NONAME ; int const KContactsModelSqliteDbCacheSize
-	??1CntPredictiveSearch@@UAE@XZ @ 13 NONAME ; CntPredictiveSearch::~CntPredictiveSearch(void)
-	?NewL@CntPredictiveSearch@@SAPAV1@XZ @ 14 NONAME ; class CntPredictiveSearch * CntPredictiveSearch::NewL(void)
-	?CreateSQLQueryL@CntPredictiveSearch@@QAEPAVHBufC16@@AAV2@H@Z @ 15 NONAME ; class HBufC16 * CntPredictiveSearch::CreateSQLQueryL(class HBufC16 &, int)
-
+	
--- a/plugins/contacts/symbian/contactsmodel/cntmodel/src/ccontactdatabase.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntmodel/src/ccontactdatabase.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -1057,6 +1057,61 @@
 	return copyArray;
 	}
 
+/** 
+Sets a list of contact items in the database to be members of a contact group.
+
+The items and the group are identified by their IDs. 
+
+@capability WriteUserData
+
+@param aItemIdList The list of IDs of the items to add to the group.
+@param aGroupId  The ID of the group to which the items should be added. 
+
+@leave KErrNotFound Either the group or the item does not exist.
+@leave KErrNotSupported The group is not of type KUidContactGroup. 
+@leave KErrDiskFull The disk does not have enough free space to perform the operation.
+*/
+EXPORT_C void CContactDatabase::AddContactsToGroupL(RArray<TContactItemId>& aItemIdList, TContactItemId aGroupId)
+	{
+	//Remember if the group was already opened, if so open it at the end of the method
+	TBool isAlreadyOpened = iCntSvr->CloseContact(aGroupId);
+	CContactItem* cntGroup = OpenNoMergeLCX(aGroupId); //double push
+
+	if (cntGroup->Type() != KUidContactGroup)
+		User::Leave(KErrNotSupported);
+
+	CContactGroup* group = static_cast<CContactGroup*>(cntGroup);
+
+    TBool isGroupModified = EFalse;
+    TInt itemCount = aItemIdList.Count();
+    for (TInt i = 0; i < itemCount; ++i)
+        {
+    	TContactItemId itemId = aItemIdList[i];
+    	if (!group->ContainsItem(itemId))
+		    {
+		    group->AddContactL(itemId);
+		    isGroupModified = ETrue;
+		    }
+        }
+
+    if (isGroupModified)
+        {
+	    iCntSvr->CommitContactL(*cntGroup);
+		}
+	else
+		{
+		iCntSvr->CloseContact(cntGroup->Id());
+		}
+
+	CleanupStack::PopAndDestroy(cntGroup);	// cntGroup
+	CleanupStack::Pop(); // Pop the lock
+	cntGroup = NULL;
+	if (isAlreadyOpened)
+		{
+		CContactItem* dummy = OpenContactL(aGroupId);
+		delete dummy;				
+		}
+	}
 
 /** 
 Sets a contact item in the database to be a member of a contact group.
@@ -1245,6 +1300,67 @@
 	}
 
 
+/** 
+Removes the association between a list of contact items and a group.
+
+The items and the group are identified by their IDs. 
+
+@capability WriteUserData
+
+@param aItemId The list of IDs of the items to remove.
+@param aGroupId The ID of the group from which the items should be removed. 
+
+@leave KErrDiskFull The disk does not have enough free space to perform the operation.
+*/
+EXPORT_C void CContactDatabase::RemoveContactsFromGroupL(RArray<TContactItemId>& aItemIdList, TContactItemId aGroupId)
+	{
+	//Remember if the group was already opened, if so open it at the end of the method
+	TBool isAlreadyOpened = iCntSvr->CloseContact(aGroupId);
+	CContactItem* cntGroup = OpenNoMergeLCX(aGroupId); //double push
+	
+	if (cntGroup->Type() != KUidContactGroup)
+		{
+		User::Leave(KErrNotSupported);
+		}
+
+	CContactGroup* group = static_cast<CContactGroup*>(cntGroup);
+	
+    TBool isGroupModified = EFalse;
+    TInt itemCount = aItemIdList.Count();
+    for (TInt i = 0; i < itemCount; ++i)
+        {
+    	TContactItemId itemId = aItemIdList[i];
+    	if (group->ContainsItem(itemId))
+		    {
+		    group->RemoveContactL(itemId);
+		    isGroupModified = ETrue;
+		    }
+		else
+		    {
+            User::Leave(KErrNotFound);
+            }
+        }
+
+    if (isGroupModified)
+        {
+	    iCntSvr->CommitContactL(*cntGroup);
+		}
+	else
+		{
+		iCntSvr->CloseContact(cntGroup->Id());
+		}
+    
+	CleanupStack::PopAndDestroy(2); // cntGroup, CntItemClose
+	cntGroup = NULL;
+	
+	if (isAlreadyOpened)
+		{
+		CContactItem* dummy = OpenContactL(aGroupId);
+		delete dummy;				
+		}
+	}
+	
+    
 /**
 Sets a field containing a telephone number as a speed dial field. The field 
 is identified by aFieldIndex within the contact item aItem. It is assigned a 
--- a/plugins/contacts/symbian/contactsmodel/cntmodel/src/rcntmodel.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntmodel/src/rcntmodel.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -2156,7 +2156,7 @@
 	{
 	RBuf8 buf;
 	CleanupClosePushL(buf);
-	buf.Create(256);
+	buf.CreateL(256);
 	TIpcArgs args(&aDbName, &buf);
 
 	TInt newBufSize;
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/c12keykeymap.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/c12keykeymap.h	Mon Oct 04 01:37:06 2010 +0300
@@ -40,19 +40,15 @@
 
 	public: // From CPcsKeyMap
 		virtual const QChar ArrayIndexToMappedChar(TInt aArrayIndex) const;
-#if !defined(USE_ORBIT_KEYMAP)
-		virtual const QChar UseHardcodedKeyMap(const QChar input) const;
-#endif
 
 	private: // From CPcsKeyMap
 		virtual TInt ComputeValue(QString aString,
 								  TBool aUpperLimit,
 								  QString& aValue) const;
-#if defined(USE_ORBIT_KEYMAP)
+
 		virtual QList<HbInputLanguage> SelectLanguages();
 
 		virtual void SetHardcodedCharacters();
-#endif
 
 		/**
          * Returns ETrue if characters that are mapped to * and # keys, should
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/clplcontactproperties.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/clplcontactproperties.h	Mon Oct 04 01:37:06 2010 +0300
@@ -124,6 +124,8 @@
 	CContactIdArray& CardTemplateIdsL();
 	CContactIdArray& GroupIdListL();
     CBufSeg* DetailsListL(const TDesC& aSearchQuery) const;
+    CBufSeg* DetailsListPredictiveL(const TDesC& aSearchPattern) const;
+
 	TInt64 MachineIdL() const;
 	void SetMachineIdL(TInt64 aMachineId);
 	TPtrC UniqueIdL(); 
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cntsqlsearch.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cntsqlsearch.h	Mon Oct 04 01:37:06 2010 +0300
@@ -1,44 +1,21 @@
 /****************************************************************************
 **
 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-//#ifdef SYMBIAN_BACKEND_USE_SQLITE
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Retrieves the character map for each of the numeric keys.
+*/
 
 #include <QObject>
 #include <QString>
@@ -50,7 +27,8 @@
 // SELECT statement.
 #define USE_DEMORGAN
 
-class CQwertyKeyMap;
+class CPcsKeyMap; 
+class CQwertyKeyMap; 
 class C12keyKeyMap;
 
 class CntSqlSearch// : public QObject
@@ -69,7 +47,8 @@
         };
 
 public:
-    CntSqlSearch();
+    CntSqlSearch( const CPcsKeyMap& twelveKeyKeyMap,
+                  const CPcsKeyMap& qertyKeyMap );
     
     ~CntSqlSearch();
 
@@ -148,8 +127,8 @@
     
 private:
     
-    CQwertyKeyMap* mQertyKeyMap; 
-    C12keyKeyMap* mkeyKeyMap;
+    const C12keyKeyMap* mkeyKeyMap;
+    const CQwertyKeyMap* mQertyKeyMap; 
     
     friend class UT_CntSqlSearch;
 };
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cpcskeymap.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cpcskeymap.h	Mon Oct 04 01:37:06 2010 +0300
@@ -19,29 +19,17 @@
 #ifndef __CPCSKEYMAP_H__
 #define __CPCSKEYMAP_H__
 
-
-// If this macro is defined, Orbit code is used to build the keymap.
-// But this might crash at startup for unknown reason.
-//
-// If macro is not defined, a hardcoded keymap is used. That code does not
-// crash, but it supports just a limited range of characters.
-#define USE_ORBIT_KEYMAP
-
-// If this macro is defined, the hardcoded keymap contains also Thai characters
-#define THAI_KEYMAP
-
 // INCLUDES
 #include <QLocale>
-#if defined(USE_ORBIT_KEYMAP)
 #include <QList>
 #include <hbinputdef.h>	// HbKeyboardType
 #include <hbinputlanguage.h>
-#endif
 #include <e32base.h>
 
 // FORWARD DECLARATIONS
 class QString;
 class QChar;
+class HbKeymap;
 
 
 // CLASS DECLARATION
@@ -84,31 +72,24 @@
 							  QString& aLowerLimit,
 							  QString& aUpperLimit) const;
 
-#if defined(USE_ORBIT_KEYMAP)
 		/*
 		 * Return the separator character.
 		 */
 		QChar Separator() const;
-#endif
 
 	public: // Pure virtual functions
 		virtual const QChar ArrayIndexToMappedChar(TInt aArrayIndex) const = 0;
-#if !defined(USE_ORBIT_KEYMAP)
-		virtual const QChar UseHardcodedKeyMap(const QChar input) const = 0;
-#endif
 
 	private: // Pure virtual functions
 		virtual TInt ComputeValue(QString aString,
 								  TBool aUpperLimit,
 								  QString& aValue) const = 0;
 
-#if defined(USE_ORBIT_KEYMAP)
 	protected: // Virtual functions
 		virtual QList<HbInputLanguage> SelectLanguages();
 
 	private: // Virtual functions
 		virtual void SetHardcodedCharacters();
-#endif
 
 	private: // Virtual functions
 		/**
@@ -128,14 +109,9 @@
 		/**
 		 * Second phase constructor
 		 */
-#if defined(USE_ORBIT_KEYMAP)
 		void ConstructL(HbKeyboardType aKeyboardType);
-#else
-		void ConstructL();
-#endif
 
 	private: // New functions
-#if defined(USE_ORBIT_KEYMAP)
 		void InitKeyMappings();
 
 		/**
@@ -152,9 +128,15 @@
          * Returns the key into which the given character is mapped.
          */
 		const QChar MappedKeyForChar(const QChar aChar) const;
-#endif // #if defined(USE_ORBIT_KEYMAP)
+		
+		/**
+         * Read the keymap's keys and append them to the internal keymap
+         * (iKeyMapping).
+         * Returns they amount of keys appended to the iKeyMapping.
+         */
+		TInt ReadKeymapCharacters(HbKeyboardType aKeyboardType,
+                                  const HbKeymap& aKeymap);
 
-#if defined(USE_ORBIT_KEYMAP)
 	protected:
 		// One QString for each key of the keyboard.
 		// Each contains all the characters that can originate from that key,
@@ -179,7 +161,6 @@
 
 		// Unmapped (unknown) characters are mapped to this
 		const QChar iPadChar;
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
 		// Largest amount of keypresses that can be stored in predictive search
 		// table, using this keyboard.
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cqwertykeymap.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cqwertykeymap.h	Mon Oct 04 01:37:06 2010 +0300
@@ -106,9 +106,6 @@
 
 	public: // From CPcsKeyMap
 		virtual const QChar ArrayIndexToMappedChar(TInt aArrayIndex) const;
-#if !defined(USE_ORBIT_KEYMAP)
-		virtual const QChar UseHardcodedKeyMap(const QChar input) const;
-#endif
 
 	private: // From CPcsKeyMap
 		virtual TInt ComputeValue(QString aString,
@@ -116,9 +113,8 @@
 								  QString& aValue) const;
 
 	public:
-#if defined(USE_ORBIT_KEYMAP)
 		bool IsValidChar(const QChar aChar) const;
-#endif
+
 		TInt MapKeyNameToValue(const QChar aKeyName) const;
 
 	private: // Constructors
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cqwertypredictivesearchtable.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/cqwertypredictivesearchtable.h	Mon Oct 04 01:37:06 2010 +0300
@@ -56,8 +56,7 @@
 
 	void FillKeyboardSpecificFieldsL(RSqlStatement& aSqlStatement,
 									 QStringList aTokens);
-	QStringList GetTableSpecificFields(const CContactItem& aItem,
-									   TBool& aMandatoryFieldsPresent) const;
+	QStringList GetTableSpecificFields(const CContactItem& aItem) const;
 
 private:
 	void ConstructL();
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/pltables.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/pltables.h	Mon Oct 04 01:37:06 2010 +0300
@@ -333,11 +333,11 @@
 											 QStringList aTokens) = 0;
 
 private: // New virtual functions
-	virtual QStringList
-		GetTableSpecificFields(const CContactItem& aItem,
-							   TBool& aMandatoryFieldsPresent) const;
+	virtual QStringList GetTableSpecificFields(const CContactItem& aItem) const;
 
 public:
+	const CPcsKeyMap* KeyMap() const;
+
 	// Return next table's name, ownership is transferred
 	HBufC* GetNextTableNameL(QList<QChar>& aTables) const;
 
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/inc/pplcontactitemmanager.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/inc/pplcontactitemmanager.h	Mon Oct 04 01:37:06 2010 +0300
@@ -40,6 +40,7 @@
 class CQwertyPredictiveSearchTable;
 class CPredictiveSearchSettingsTable;
 class CPredictiveSearchSynchronizer;
+class CPcsKeyMap;
 
 
 /**
@@ -75,6 +76,8 @@
 	CPplPreferencesPersistor& PreferencesPersitor();
 	CContactIdArray* GroupIdListL();	
     CBufSeg* DetailsListL (const TDesC& aSearchQuery) const;
+    CBufSeg* DetailsListPredictiveL(const TDesC& aSearchPattern) const;
+    
     CContactIdArray& CardTemplateIdsL();
     TContactItemId OwnCardIdL();
     void SetOwnCardIdL(TContactItemId aId, TBool aPersist = ETrue);
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/c12keykeymap.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/c12keykeymap.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -51,11 +51,9 @@
 	EKeyHash
     };
 
-#if defined(USE_ORBIT_KEYMAP)
 const QChar KStar = '*';
 const QChar KPlus = '+';
 const QChar KHash = '#';
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
 
 // * key is mapped to this
@@ -122,222 +120,6 @@
         }
     }
 
-#if !defined(USE_ORBIT_KEYMAP)
-// ----------------------------------------------------------------------------
-// C12keyKeyMap::UseHardcodedKeyMap
-// ----------------------------------------------------------------------------
-QChar C12keyKeyMap::UseHardcodedKeyMap(QChar input) const
-    {
-	QChar ret = '0';
-    switch (input.unicode())
-        {
-#if defined(THAI_KEYMAP)
-		case 0x21B2:
-			ret = '0';
-			break;
-
-		case 0x0E01:
-		case 0x0E02:
-		case 0x0E03:
-		case 0x0E04:
-		case 0x0E05:	
-#endif
-		case '-':
-		case '?':
-		    ret = '1';
-		    break;
-
-        case 'a':
-        case 'A':
-        case 'b':
-        case 'B':
-        case 'c':
-        case 'C':
-#if defined(THAI_KEYMAP)
-		case 0x0E06:
-		case 0x0E07:
-		case 0x0E08:
-		case 0x0E09:
-#endif
-            ret = '2';
-            break;
-
-		case 'd':
-        case 'D':
-        case 'e':
-        case 'E':
-        case 'f':
-        case 'F':
-#if defined(THAI_KEYMAP)
-		case 0x0E0A:
-		case 0x0E0B:
-		case 0x0E0C:
-		case 0x0E0D:
-#endif
-            ret = '3';
-            break;
-            
-		case 'g':
-        case 'G':
-        case 'h':
-        case 'H':
-        case 'i':
-        case 'I':
-#if defined(THAI_KEYMAP)
-		case 0x0E0E:
-		case 0x0E0F:
-		case 0x0E10:
-		case 0x0E11:
-		case 0x0E12:
-		case 0x0E13:
-#endif
-            ret = '4';
-            break;
-
-		case 'j':
-        case 'J':
-        case 'k':
-        case 'K':
-        case 'l':
-        case 'L':
-#if defined(THAI_KEYMAP)
-		case 0x0E14:
-		case 0x0E15:
-		case 0x0E16:
-		case 0x0E17:
-		case 0x0E18:
-#endif
-            ret = '5';
-            break;
-
-		case 'm':
-        case 'M':
-        case 'n':
-        case 'N':
-        case 'o':
-        case 'O':
-#if defined(THAI_KEYMAP)
-		case 0x0E19:
-		case 0x0E1A:
-		case 0x0E1B:
-		case 0x0E1C:
-		case 0x0E1D:
-#endif
-            ret = '6';
-            break;
-      
-		case 'p':
-        case 'P':
-        case 'q':
-        case 'Q':
-        case 'r':
-        case 'R':
-        case 's':
-        case 'S':
-#if defined(THAI_KEYMAP)
-		case 0x0E1E:
-		case 0x0E1F:
-		case 0x0E20:
-		case 0x0E21:
-		case 0x0E22:
-#endif
-            ret = '7';
-            break;
-
-		case 't':
-        case 'T':
-        case 'u':
-        case 'U':
-        case 'v':
-        case 'V':
-#if defined(THAI_KEYMAP)
-		case 0x0E23:
-		case 0x0E24:
-		case 0x0E25:
-		case 0x0E26:
-		case 0x0E27:
-		case 0x0E28:
-		case 0x0E29:
-#endif
-            ret = '8';
-            break;
-
-        case 'w':
-        case 'W':
-        case 'X':
-        case 'x':
-        case 'Y':
-        case 'y':
-        case 'z':
-        case 'Z':
-#if defined(THAI_KEYMAP)
-		case 0x0E2A:
-		case 0x0E2B:
-		case 0x0E2C:
-		case 0x0E2D:
-		case 0x0E2E:
-#endif
-            ret = '9';
-            break;
-
-		case '*':
-		case '+':
-#if defined(THAI_KEYMAP)
-		case 0x0E2F:
-		case 0x0E3F:
-		case 0x0E31:
-		case 0x0E34:
-		case 0x0E35:
-		case 0x0E36:
-		case 0x0E37:
-		case 0x0E38:
-		case 0x0E39:
-		case 0x0E46:
-		case 0x0E47:
-		case 0x0E48:
-		case 0x0E49:
-		case 0x0E4A:
-		case 0x0E4B:
-		case 0x0E4C:
-#endif
-		    ret = KMappedCharForStar;
-		    break;
-		    
-		case '#':
-#if defined(THAI_KEYMAP)
-		case 0x0E30:
-		case 0x0E32:
-		case 0x0E33:
-		case 0x0E40:
-		case 0x0E41:
-		case 0x0E42:
-		case 0x0E43:
-		case 0x0E44:
-#endif
-		    ret = KMappedCharForHash;
-		    break;
-
-		case '0':
-		case '1':
-		case '2':
-		case '3':
-		case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-        case ' ':
-            ret = input; // Numbers and space
-            break;
-
-		default: // Other (unknown) chars
-		    ret = KPadChar;
-        }
-    return ret;
-    }
-#endif // #if !defined(USE_ORBIT_KEYMAP)
-
 // ----------------------------------------------------------------------------
 // C12keyKeyMap::ComputeValue
 // ----------------------------------------------------------------------------
@@ -385,8 +167,6 @@
 	return KErrNone;
 	}
 
-#if defined(USE_ORBIT_KEYMAP)
-
 // ----------------------------------------------------------------------------
 // C12keyKeyMap::SetHardcodedCharacters
 // In emulator (except in unit tests), select just the default language, as new
@@ -418,7 +198,6 @@
 	iHardcodedChars.append(KPlus);
 	iHardcodedChars.append(KHash);
 	}
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
 // ----------------------------------------------------------------------------
 // C12keyKeyMap::DetermineSpecialCharBehaviour
@@ -463,11 +242,7 @@
 	{
 	PRINT(_L("Enter C12keyKeyMap::ConstructL"));
 
-#if defined(USE_ORBIT_KEYMAP)
 	CPcsKeyMap::ConstructL(HbKeyboardVirtual12Key);
-#else
-	CPcsKeyMap::ConstructL();
-#endif
 
 	TInt err(KErrNone);
 	QT_TRYCATCH_ERROR(err, GetTextCodecs());
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/clplcontactproperties.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/clplcontactproperties.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -182,14 +182,19 @@
 
 CBufSeg* CLplContactProperties::DetailsListL(const TDesC& aSearchQuery) const 
     {
-	return iContactItemManager->DetailsListL(aSearchQuery);
+    return iContactItemManager->DetailsListL(aSearchQuery);
     }   
 
 
+CBufSeg* CLplContactProperties::DetailsListPredictiveL(const TDesC& aSearchPattern) const
+    {
+    return iContactItemManager->DetailsListPredictiveL(aSearchPattern);
+    }   
+
 TInt64 CLplContactProperties::MachineIdL() const
-	{
-	return iContactItemManager->PreferencesPersitor().MachineIdL();
-	}
+    {
+    return iContactItemManager->PreferencesPersitor().MachineIdL();
+    }
 
 	
 void CLplContactProperties::SetMachineIdL(TInt64 aMachineId)
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cntpredictivesearch.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Retrieves the character map for each of the numeric keys.
-*/
-
-// INCLUDE FILES
-#include "cntpredictivesearch.h"
-#include "cntsqlsearch.h"
-
-#include <QtGlobal>
-#include <QString>
-#include <QChar>
-
-// ============================== MEMBER FUNCTIONS ============================
-
-// ----------------------------------------------------------------------------
-// CntPredictiveSearch::NewL
-// ----------------------------------------------------------------------------
-EXPORT_C CntPredictiveSearch* CntPredictiveSearch::NewL()
-    {
-    CntPredictiveSearch* self = new (ELeave) CntPredictiveSearch();
-    CleanupStack::PushL(self);
-    self->ConstructL();
-    CleanupStack::Pop(self);
-    return self;
-    }
-    
-// ----------------------------------------------------------------------------
-// CntPredictiveSearch::NewL
-// ----------------------------------------------------------------------------
-EXPORT_C CntPredictiveSearch::~CntPredictiveSearch()
-{
-
-}   
- 
-// ----------------------------------------------------------------------------
-// CntPredictiveSearch::CreateSQLQuery
-// Construct SQL query.
-// ----------------------------------------------------------------------------
-EXPORT_C HBufC* CntPredictiveSearch::CreateSQLQueryL(HBufC& searchQuery, int aKeypad)
-{   
-    QString qString;
-    QString queryString;
-    QT_TRYCATCH_LEAVING({
-        qString = QString((QChar*)searchQuery.Des().Ptr(),searchQuery.Length());
-        CntSqlSearch SqlSearch;
-        queryString = SqlSearch.CreatePredictiveSearch(qString);
-        });
-    TPtrC myDescriptor (reinterpret_cast<const TText*>(queryString.constData()),queryString.length());   
-    return myDescriptor.AllocL();
-}
-    
-// ----------------------------------------------------------------------------
-// CntPredictiveSearch::CntPredictiveSearch
-// ----------------------------------------------------------------------------
-CntPredictiveSearch::CntPredictiveSearch()
-{
-}
-      
-// ----------------------------------------------------------------------------
-// CntPredictiveSearch::ConstructL
-// ----------------------------------------------------------------------------
-void CntPredictiveSearch::ConstructL()
-{
-}
-// End of file
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cntsqlsearch.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cntsqlsearch.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -1,43 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Retrieves the character map for each of the numeric keys.
+*/
 #include <QStringList>
 
 #include "cntsqlsearch.h"
@@ -86,23 +61,24 @@
 //Predictive search table
 const QString QwertyTableName = "qm";
 
-CntSqlSearch::CntSqlSearch()
-	{
-    QT_TRAP_THROWING(mQertyKeyMap = CQwertyKeyMap::NewL());
-    QT_TRAP_THROWING(mkeyKeyMap = C12keyKeyMap::NewL());
-	}
+CntSqlSearch::CntSqlSearch( const CPcsKeyMap& twelveKeyKeyMap,
+                            const CPcsKeyMap& qertyKeyMap ) 
+        
+    : mkeyKeyMap( static_cast<const C12keyKeyMap*>(&twelveKeyKeyMap) ),
+      mQertyKeyMap( static_cast<const CQwertyKeyMap*>(&qertyKeyMap) )
+    {
+    }
 
 CntSqlSearch::~CntSqlSearch()
     {
-    delete mQertyKeyMap;
-    delete mkeyKeyMap;
     }
+
 // Basic cases:
 // 1: "0", "5"
 // Just one digit. Select all contact ids from the table. No need to compare
 // values.
 //
-// 2: "123", "01", "10", "010", "00"
+// 2: "123", "01", "10", "00"
 // No zeros which have non-zeros in their both sides
 // One or zero tokens, when pattern is split using '0'.
 //
@@ -117,7 +93,7 @@
 // and those digits are not the same.
 // Two tokens, each with length of 1 and tokens are different.
 //
-// 5: "1023", "0102", "1010", "00100200", "10203", "01020304050"
+// 5: "1023", "1010", "00100200", "10203", "01020304050"
 // Two tokens, at least one of them has length > 1.
 // If tokens are identical, handle as case 3, otherwise handle as case 4.
 // ("10203" -> tokens "1" and "203"
@@ -126,7 +102,11 @@
 // 6: "10", "1000"
 // One token, ends with zero.
 // In this case, query should look-up first toke and number ("10", "1000").
-
+//
+// 7: "0102"
+// Same case 5, but first zero is remover in order to get more matches. 
+// e.g. 0102 is 01 AND 2 or 1 AND 2.
+//
 QString CntSqlSearch::CreatePredictiveSearch(const QString &pattern)
 	{
 	int len = pattern.length();
@@ -310,17 +290,16 @@
 QString CntSqlSearch::CreateQuery(const QString& pattern) const
 	{
 	QStringList tokens = GetTokens(pattern);
-	if (tokens.count() < KTwoTokens)
+	if (TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber))
+        {
+        return CompareTwoColumnsWithModifiedPattern(pattern, tokens);  // Case 7
+        }
+	else if(tokens.count() < KTwoTokens)
         {
 	    if (TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken))
             {
             return TwoDifferentTokensSearch(pattern, tokens);  // Case 6
             }
-	    
-	    if (TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber))
-            {
-            return CompareTwoColumnsWithModifiedPattern(pattern, tokens);  // Case 7
-            }
         else
             {
             return ExactMatchSearch(pattern) + Order(tokens); // Case 2
@@ -334,7 +313,7 @@
             }
         else
             {
-            return IntersectionSearch(pattern, tokens); // Case 4
+            return IntersectionSearch(pattern, tokens); // Case 4 or 5 first token start with multible zeros.
             }
         }
 	}
@@ -502,15 +481,15 @@
 QString CntSqlSearch::TwoDifferentTokensSearch(const QString& pattern, const QStringList& tokens) const
         {
         QString token = tokens.at(0);
-        QString sortPatern = pattern;
-        sortPatern.truncate(pattern.length()-1);
+        /*QString sortPatern = pattern;
+        sortPatern.truncate(pattern.length()-1);*/
 #if defined(USE_DEMORGAN)
         QString query(SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE NOT(NOT" +
-            ExactMatch(sortPatern) +
+            ExactMatch(token) +
         " AND NOT" + ExactMatch(pattern) + ")");
 #else
         QString query(SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE (" +
-            ExactMatch(sortPatern) +  // exact match (e.g. "2")
+            ExactMatch(token) +  // exact match (e.g. "2")
         ") OR " + ExactMatch(pattern)); // exact match (e.g. "20")
 #endif
         query += Order(tokens);
@@ -527,26 +506,116 @@
         WHERE ((NOT(NOT(predictivesearch0.nbr>22517998136852479 AND predictivesearch0.nbr<27021597764222976) AND NOT(predictivesearch0.nbr2>22517998136852479 AND predictivesearch0.nbr2<27021597764222976) AND NOT(predictivesearch0.nbr3>22517998136852479 AND predictivesearch0.nbr3<27021597764222976) AND NOT(predictivesearch0.nbr4>22517998136852479 AND predictivesearch0.nbr4<27021597764222976)))) 
     ) AS PR
     ORDER BY PR.first_name, PR.last_name ASC;
+    
+    - AND case - 
+    SELECT contact_id FROM (
+    SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE NOT(NOT(NOT(NOT(nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr2>382805968326492159 AND nbr2<387309567953862656) AND NOT(nbr3>382805968326492159 AND nbr3<387309567953862656) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>382805968326492159 AND nbr2<387309567953862656) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>382805968326492159 AND nbr2<387309567953862656) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>382805968326492159 AND nbr3<387309567953862656))) AND NOT(NOT(NOT(nbr2>382805968326492159 AND nbr2<387309567953862656 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>382805968326492159 AND nbr3<387309567953862656 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>382805968326492159 AND nbr3<387309567953862656 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) 
+    UNION
+    SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23930870578544639 AND predictivesearch0.nbr<23931970090172416) AND NOT(predictivesearch0.nbr2>23930870578544639 AND predictivesearch0.nbr2<23931970090172416) AND NOT(predictivesearch0.nbr3>23930870578544639 AND predictivesearch0.nbr3<23931970090172416) AND NOT(predictivesearch0.nbr4>23930870578544639 AND predictivesearch0.nbr4<23931970090172416)))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>0387309567953862656382805968326492159 AND nbr<0387309567953862656382805968326492159) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>0387309567953862656382805968326492159 AND nbr<0387309567953862656382805968326492159) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>0387309567953862656382805968326492159 AND nbr2<0387309567953862656382805968326492159) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>0387309567953862656382805968326492159 AND nbr<0387309567953862656382805968326492159) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>0387309567953862656382805968326492159 AND nbr2<0387309567953862656382805968326492159) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>0387309567953862656382805968326492159 AND nbr3<0387309567953862656382805968326492159))) AND NOT(NOT(NOT(nbr2>0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr2<0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr3<0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr3<0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr4<0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr4<0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr4<0387309567953862656382805968326492159387309567953862656382805968326492159 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))
+    )AS PR ORDER BY PR.first_name, PR.last_name ASC;
     */
 
 QString CntSqlSearch::CompareTwoColumnsWithModifiedPattern(const QString& pattern,
                                                                   const QStringList& tokens) const
     {
-    QString patternAfterZero = pattern.right(pattern.count() - 1);
-    // It has been checked earlier that tables are not same
+    QString queryString;
+    QString lower;
+    QString upper;
+    QString lower2;
+    QString upper2;
+    QString lower_without_zero;
+    QString upper_without_zero;
+    QString lower2_without_zero;
+    QString upper2_without_zero;
+    int err;
+    int i(0);
+    
+    QString firstTokenWithoutZeros = tokens.at(0);
+    firstTokenWithoutZeros.remove(QChar('0'), Qt::CaseInsensitive);
+
     QString firstTable = SelectTable(pattern);
-    QString secondTable = SelectTable(patternAfterZero);
-    QString queryString;
-    if (patternAfterZero.count() == 1)
-        { 
+    QString secondTable = SelectTable(firstTokenWithoutZeros);
+    
+    QString secondTokenWithoutZeros;
+    
+    if(tokens.count() > 1)
+        {
+        secondTokenWithoutZeros = tokens.at(1);
+        i = pattern.length()-1;
+        while (pattern[i] == '0') 
+               {
+               --i;
+               }
+        if(pattern.length()-1 != i)
+            {
+            pattern.leftRef(i);
+            }
+        //secondTokenWithoutZeros.remove(QChar('0'), Qt::CaseInsensitive);
+        }
+    
+    // Case like 05
+    if (tokens.at(0).count() == 1 && pattern.length() == 2)
+        {
         queryString = QString("SELECT contact_id FROM (SELECT " + secondTable + ".contact_id, " + secondTable + ".first_name, " + secondTable + ".last_name FROM " + secondTable 
                                 + " UNION SELECT " + firstTable + ".contact_id, " + firstTable + ".first_name, " + firstTable + ".last_name FROM " + firstTable 
                                 + " WHERE " + ModifiedMatchColumns( pattern) + ") AS PR ORDER BY PR.first_name, PR.last_name ASC;");
         }
+    //case like 05055 or 0506 or 00506 
+    else if (tokens.count() > 1)
+        { 
+        err = mkeyKeyMap->GetNumericLimits(tokens.at(0), lower, upper);
+        if(err)
+            {
+            return QString("");
+            }
+        err = mkeyKeyMap->GetNumericLimits(tokens.at(1), lower2, upper2);
+        if(err)
+            {
+            return QString("");
+            }
+        
+        err = mkeyKeyMap->GetNumericLimits(firstTokenWithoutZeros, lower_without_zero, upper_without_zero);
+        if(err)
+            {
+            return QString("");
+            }
+        
+        err = mkeyKeyMap->GetNumericLimits(secondTokenWithoutZeros, lower2_without_zero, upper2_without_zero);
+        if(err)
+           {
+           return QString("");
+           }
+
+        queryString = QString("SELECT contact_id FROM (SELECT " + secondTable + ".contact_id, " + secondTable + ".first_name, " + secondTable + ".last_name FROM " + secondTable + 
+                                   + " WHERE (" + CompareTwoColumns(lower_without_zero, upper_without_zero, lower2_without_zero, upper2_without_zero) + " OR" +
+                                   CompareTwoColumns(lower2_without_zero, upper2_without_zero, lower_without_zero, upper_without_zero) + ")" +
+                              " UNION" +
+                                   " SELECT " + firstTable + ".contact_id, " + firstTable + ".first_name, " + firstTable + ".last_name FROM " + firstTable 
+                                   + " WHERE " + ModifiedMatchColumns( pattern) + " OR"
+                                   + CompareTwoColumns(lower, upper, lower2, upper2) + " OR"
+                                   + CompareTwoColumns(lower2, upper2, lower, upper) +
+                              ") AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+            
+        
+            
+            /* "SELECT contact_id FROM ( SELECT... UNION SELECT ...) AS PR ORDER BY PR.first_name, PR.last_name ASC;*/
+            /* 5 table 
+             queryString = QString("SELECT " + secondTable + ".contact_id, " + secondTable + ".first_name, " + secondTable + ".last_name FROM " + secondTable 
+                                                + " WHERE NOT(NOT" + ExactMatch(tokens.at(0)) + " AND NOT" +
+                                               CompareTwoColumns(lower, upper, lower2, upper2) + " AND NOT" +
+                                               CompareTwoColumns(lower2, upper2, lower, upper) + " );");*/
+        
+            /* table 0 queryString = QString("SELECT " + firstTable + ".contact_id, " + firstTable + ".first_name, " + firstTable + ".last_name FROM " + firstTable 
+                                               + " WHERE " + ModifiedMatchColumns( pattern) + " AND NOT"
+                                               + CompareTwoColumns(zeroPrefix.append(lower), zeroPrefix.append(upper), lower2, upper2) + " AND NOT"
+                                               + CompareTwoColumns(lower2, upper2, zeroPrefix.append(lower), zeroPrefix.append(upper)));*/
+                
+        }
     else
         {
+        //case like 055
         queryString = QString("SELECT contact_id FROM (SELECT " + secondTable + ".contact_id, " + secondTable + ".first_name, " + secondTable + ".last_name FROM " + secondTable 
-                                + " WHERE " + ModifiedMatchColumns( patternAfterZero) + 
+                                + " WHERE " + ModifiedMatchColumns( firstTokenWithoutZeros) + 
                                 + " UNION SELECT " + firstTable + ".contact_id, " + firstTable + ".first_name, " + firstTable + ".last_name FROM " + firstTable 
                                 + " WHERE " + ModifiedMatchColumns( pattern) + ") AS PR ORDER BY PR.first_name, PR.last_name ASC;");
         }
@@ -948,8 +1017,8 @@
         {
         if (CntSqlSearch::ZerosEndOfFirstToken == searchMethod)
             {
-            if( tokens.count() == KOneToken && !tokens.at(0).contains("0")
-                && !pattern.startsWith('0') && pattern.count('0') == 1
+            if( tokens.count() == KOneToken /*&& !tokens.at(0).contains("0")*/
+                && !pattern.startsWith('0') /*&& pattern.count('0') == 1*/
                 && pattern.endsWith('0'))
                 {
                 return true;
@@ -957,8 +1026,11 @@
             }
         if (CntSqlSearch::ZeroIsFirstNumber == searchMethod )
             {
-            if(pattern.startsWith('0') && pattern.count() > 1 
-                && pattern.at(1) != '0')
+            if(pattern.startsWith('0') && pattern.count() > 1 )
+                {
+                return true;
+                }
+            if (pattern.startsWith('0') && tokens.count() >= KTwoTokens )
                 {
                 return true;
                 }
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpcskeymap.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpcskeymap.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -18,11 +18,8 @@
 #include "cpcskeymap.h"
 #include <QChar>
 #include <QString>
-
-#if defined(USE_ORBIT_KEYMAP)
 #include <hbinputkeymap.h>
 #include <hbinputkeymapfactory.h>
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
 // This macro suppresses log writes
 //#define NO_PRED_SEARCH_LOGS
@@ -33,6 +30,10 @@
 // Separator character stored in predictive search table columns
 const QChar KSeparatorChar = ' ';
 
+// Code using the new API (wk32 onwards) is put here. Remove old API code
+// when wk30 is no longer used.
+// #define NEW_KEYMAP_FACTORY_API
+
 
 // ============================== MEMBER FUNCTIONS ============================
 
@@ -89,11 +90,7 @@
         else
 			{
 			QChar ch(0);
-#if defined(USE_ORBIT_KEYMAP)
             ch = MappedKeyForChar(aSource[i]);
-#else
-            ch = UseHardcodedKeyMap(aSource[i]);            
-#endif
 			if (!ShouldSkipChar(ch, skipHashStar))
 				{
 				destination.append(ch);
@@ -134,7 +131,6 @@
 	return err;
 	}
 
-#if defined(USE_ORBIT_KEYMAP)
 // ----------------------------------------------------------------------------
 // CPcsKeyMap::Separator
 // ----------------------------------------------------------------------------
@@ -162,7 +158,6 @@
 void CPcsKeyMap::SetHardcodedCharacters()
 	{
 	}
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
 // ----------------------------------------------------------------------------
 // CPcsKeyMap::DetermineSpecialCharBehaviour
@@ -185,15 +180,10 @@
 // ----------------------------------------------------------------------------
 // CPcsKeyMap::ConstructL
 // ----------------------------------------------------------------------------
-#if defined(USE_ORBIT_KEYMAP)
 void CPcsKeyMap::ConstructL(HbKeyboardType aKeyboardType)
-#else
-void CPcsKeyMap::ConstructL()
-#endif
 	{
 	PRINT(_L("Enter CPcsKeyMap::ConstructL"));
 
-#if defined(USE_ORBIT_KEYMAP)
 	TInt err(KErrNone);
 	QT_TRYCATCH_ERROR(err,
 		{
@@ -206,7 +196,6 @@
         PRINT1(_L("CPcsKeyMap::ConstructL exception, err=%d"), err);
         User::Leave(err);
         }
-#endif
 
 	PRINT(_L("End CPcsKeyMap::ConstructL"));
 	}
@@ -214,7 +203,6 @@
 // ----------------------------------------------------------------------------
 // CPcsKeyMap::CPcsKeyMap
 // ----------------------------------------------------------------------------
-#if defined(USE_ORBIT_KEYMAP)
 CPcsKeyMap::CPcsKeyMap(TInt aAmountOfKeys,
 					   QChar aPadChar,
 					   TInt aMaxKeysStoredInDb) :
@@ -224,16 +212,7 @@
 	iMaxKeysStoredInDb(aMaxKeysStoredInDb)
 	{
 	}
-#else // #if defined(USE_ORBIT_KEYMAP)
-CPcsKeyMap::CPcsKeyMap(TInt /*aAmountOfKeys*/,
-					   QChar /*aPadChar*/,
-					   TInt aMaxKeysStoredInDb) :
-	iMaxKeysStoredInDb(aMaxKeysStoredInDb)
-	{
-	}
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
-#if defined(USE_ORBIT_KEYMAP)
 // ----------------------------------------------------------------------------
 // CPcsKeyMap::InitKeyMappings
 // Put string for each key into iKeyMapping.
@@ -251,8 +230,10 @@
 // ----------------------------------------------------------------------------
 // CPcsKeyMap::ConstructLanguageMappings
 // Fetch keymap for selected languages.
+// Currently QWERTY keymaps do not map digits ('0'..'9') to any key, even with
+// HbModifierChrPressed and HbModifierFnPressed modifiers.
 // ----------------------------------------------------------------------------
-void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType) 
+void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType)
 	{
     PRINT(_L("Enter CPcsKeyMap::ConstructLanguageMappings"));
 
@@ -264,6 +245,16 @@
     PRINT1(_L("build keymap from %d language(s)"), languages.count());
 
 	TInt languageCount = languages.size();
+#if !defined(NEW_KEYMAP_FACTORY_API)
+	// Latest SDKs have so many keymaps contact server runs out of stack.
+	// So limit the amount of keymaps.
+	const TInt KMaxKeymapCount = 10;
+	if (languageCount > KMaxKeymapCount)
+	    {
+        languageCount = KMaxKeymapCount;
+	    }
+#endif
+
 	for (TInt lang = 0; lang < languageCount; ++lang)
 		{
         PRINT2(_L("(%d) handle language %d"), lang, languages[lang].language());
@@ -272,54 +263,27 @@
 			PRINT2(_L("Constructing keymap for lang=%d,var=%d"),
 				   languages[lang].language(),
 				   languages[lang].variant());
+#if defined(NEW_KEYMAP_FACTORY_API)
+			// Gets ownership of keymap
+			const HbKeymap* keymap =
+			    HbKeymapFactory::instance()->keymap(languages[lang],  
+                                                    HbKeymapFactory::NoCaching);
+#else
+			// Does not get ownership of keymap
 			const HbKeymap* keymap =
 				HbKeymapFactory::instance()->keymap(languages[lang].language(),
                                                     languages[lang].variant());
+#endif
 			if (keymap)
 			    {
-				for (TInt key = 0; key < iAmountOfKeys; ++key)
-                    {
-                    PRINT1(_L("handle key(enum value %d)"), key); // test
-                    const HbMappedKey* mappedKey = keymap->keyForIndex(aKeyboardType, key);
-					// 12-key: Most languages don't have mapping for EKeyStar, EKeyHash.
-					// QWERTY: Different languages have different amount of keys,
-					// so mappedKey can be NULL.
-                    if (mappedKey)
-                        {
-						const QString lowerCase = mappedKey->characters(HbModifierNone); // "abc2.."
-						const QString upperCase = mappedKey->characters(HbModifierShiftPressed); // "ABC2.."
-						const QString charsForKey = lowerCase + upperCase; 
-	    
-						// Filter out duplicate characters
-						for (TInt i = charsForKey.length() - 1; i >= 0 ; --i) 
-							{
-							QChar ch = charsForKey[i];
-							if (!iKeyMapping[key].contains(ch) &&
-								!iHardcodedChars.contains(ch))
-								{
 #if defined(WRITE_PRED_SEARCH_LOGS)
-								char ascChar = ch.toAscii();
-								TChar logChar(ArrayIndexToMappedChar(key).unicode());
-	
-								if (ascChar == 0) // ch can't be represented in ASCII
-									{
-									PRINT2(_L("CPcsKeyMap: map key(%c) <-> char=0x%x"),
-									       logChar, ch);
-									}
-								else
-									{
-									PRINT3(_L("CPcsKeyMap: map key(%c) <-> char='%c'(0x%x)"),
-										   logChar,
-										   ascChar,
-										   ascChar);
-									}
-								++count;
-#endif // #if defined(WRITE_PRED_SEARCH_LOGS)
-								iKeyMapping[key] += ch;
-								}
-							}
-						}
-                    }
+                count +=
+#endif
+                ReadKeymapCharacters(aKeyboardType, *keymap);
+				
+#if defined(NEW_KEYMAP_FACTORY_API)
+				delete keymap;
+#endif
 			    }
 			else
                 {
@@ -363,6 +327,63 @@
 #endif
 	return iPadChar;
     }
-#endif // #if defined(USE_ORBIT_KEYMAP)
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::ReadKeymapCharacters
+// ----------------------------------------------------------------------------
+TInt CPcsKeyMap::ReadKeymapCharacters(HbKeyboardType aKeyboardType,
+                                      const HbKeymap& aKeymap)
+    {
+    PRINT(_L("Enter CPcsKeyMap::ReadKeymapCharacters"));
+
+    TInt count(0);
+
+    for (TInt key = 0; key < iAmountOfKeys; ++key)
+        {
+        PRINT1(_L("handle key(enum value %d)"), key); // test
+        const HbMappedKey* mappedKey = aKeymap.keyForIndex(aKeyboardType, key);
+        // 12-key: Most languages don't have mapping for EKeyStar, EKeyHash.
+        // QWERTY: Different languages have different amount of keys,
+        // so mappedKey can be NULL.
+        if (mappedKey)
+            {
+            const QString lowerCase = mappedKey->characters(HbModifierNone); // "abc2.."
+            const QString upperCase = mappedKey->characters(HbModifierShiftPressed); // "ABC2.."                        
+            const QString charsForKey = lowerCase + upperCase; 
+
+            // Filter out duplicate characters
+            for (TInt i = charsForKey.length() - 1; i >= 0 ; --i) 
+                {
+                QChar ch = charsForKey[i];
+                if (!iKeyMapping[key].contains(ch) &&
+                    !iHardcodedChars.contains(ch))
+                    {
+#if defined(WRITE_PRED_SEARCH_LOGS)
+                    char ascChar = ch.toAscii();
+                    TChar logChar(ArrayIndexToMappedChar(key).unicode());
+
+                    if (ascChar == 0) // ch can't be represented in ASCII
+                        {
+                        PRINT2(_L("CPcsKeyMap: map key(%c) <-> char=0x%x"),
+                               logChar, ch);
+                        }
+                    else
+                        {
+                        PRINT3(_L("CPcsKeyMap: map key(%c) <-> char='%c'(0x%x)"),
+                               logChar,
+                               ascChar,
+                               ascChar);
+                        }
+                    ++count;
+#endif // #if defined(WRITE_PRED_SEARCH_LOGS)
+                    iKeyMapping[key] += ch;
+                    }
+                }
+            }
+        }
+    
+    PRINT(_L("End CPcsKeyMap::ReadKeymapCharacters"));
+    return count;
+    }
 
 // End of file
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpplcontacttable.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpplcontacttable.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -1044,7 +1044,6 @@
 	{
 	if (iOwnCardId != 0)
 	    {
-    	RDebug::Print(_L("CPplContactTable::OwnCardIdL() exit %d"), iOwnCardId);
 	    return iOwnCardId;
 	    }
 	    
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -20,6 +20,8 @@
 #include "cpcskeymap.h"
 #include "cntitem.h"
 #include <QStringList>
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
 #include "predictivesearchlog.h"
 
 
@@ -95,15 +97,19 @@
 Default implementation returns empty list.
 */
 QStringList CPplPredictiveSearchTableBase::GetTableSpecificFields(
-	const CContactItem& /*aItem*/,
-	TBool& aMandatoryFieldsPresent) const
+	const CContactItem& /*aItem*/) const
 	{
-	aMandatoryFieldsPresent = ETrue;
 	QStringList emptyList;
 	return emptyList;
 	}
 
 
+const CPcsKeyMap* CPplPredictiveSearchTableBase::KeyMap() const
+	{
+	return iKeyMap;
+	}
+
+
 HBufC* CPplPredictiveSearchTableBase::GetNextTableNameL(QList<QChar>& aTables) const
 	{
 	HBufC* tableName(NULL);
@@ -183,6 +189,9 @@
 // Insert a contact to predictive search tables.
 // Write contact's all tokens to each associate pred.search table.
 // E.g. if FN="11 22" LN="2 333", write "11","22","2" and "333" to tables 1, 2 and 3.
+//
+// Store also contacts that have a mail address beginning by an unknown character
+// as the contact can still be searched by first name or last name.
 void CPplPredictiveSearchTableBase::WriteToDbL(const CContactItem& aItem)
 	{
 	PRINT(_L("CPplPredictiveSearchTableBase::WriteToDbL"));
@@ -196,14 +205,9 @@
 	QStringList tokens;
 	QList<QChar> tables;
 	QT_TRYCATCH_LEAVING({
-		TBool mandatoryFieldsPresent(EFalse);
-		QStringList tableSpecificFields =
-			GetTableSpecificFields(aItem, mandatoryFieldsPresent);
-		if (mandatoryFieldsPresent)
-			{
-			tokens = GetTokens(tableSpecificFields, firstNameAsNbr, lastNameAsNbr);
-			tables = DetermineTables(tokens);
-			}
+		QStringList tableSpecificFields = GetTableSpecificFields(aItem);
+		tokens = GetTokens(tableSpecificFields, firstNameAsNbr, lastNameAsNbr);
+		tables = DetermineTables(tokens);
 		});
 
 	HBufC* tableName(NULL);
@@ -364,11 +368,7 @@
 	if (aString)
 		{
 		QString s((QChar*)aString->Ptr(), aString->Length());
-#if defined(USE_ORBIT_KEYMAP)
 		QStringList tokens = s.split(iKeyMap->Separator(), QString::SkipEmptyParts);
-#else
-		QStringList tokens = s.split(' ', QString::SkipEmptyParts);
-#endif
 
 		// Select tokens in the same order they are in original aString
 		for (TInt i = 0; i < tokens.count(); ++i)
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cqwertykeymap.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cqwertykeymap.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -134,41 +134,6 @@
 	return iKeyNames.value(static_cast<TKeyId>(aArrayIndex), PAD_CHAR);
 	}
 
-#if !defined(USE_ORBIT_KEYMAP)
-// ----------------------------------------------------------------------------
-// CQwertyKeyMap::UseHardcodedKeyMap
-// ----------------------------------------------------------------------------
-const QChar CQwertyKeyMap::UseHardcodedKeyMap(const QChar input) const
-    {
-    if (input >= 'a' && input <= 'z')
-        {
-        return input;
-        }
-    if (input >= 'A' && input <= 'Z')
-        {
-        return input.toLower(); // Return lowercase letter
-        }
-    if (input == KEY_COLON_NAME ||
-        input == KEY_DOT_NAME ||
-        input == KEY_DASH_NAME ||
-        input == KEY_AT_NAME ||
-        input == KEY_QUOTE_NAME ||
-        input == KEY_QUESTION_MARK_NAME)
-        {
-        return input;
-        }
-
-        // TODO: add rest of the keys
-
-#if defined(THAI_KEYMAP)
-    // TODO: add Thai key map
-#endif
-
-    // Other (unknown) chars
-    return PAD_CHAR;
-    }
-#endif // #if !defined(USE_ORBIT_KEYMAP)
-
 // ----------------------------------------------------------------------------
 // CQwertyKeyMap::ComputeValue
 // ----------------------------------------------------------------------------
@@ -215,7 +180,6 @@
 	return KErrNone;
 	}
 
-#if defined(USE_ORBIT_KEYMAP)
 // ----------------------------------------------------------------------------
 // CQwertyKeyMap::MapKeyNameToValue
 // ----------------------------------------------------------------------------
@@ -223,7 +187,6 @@
 	{
 	return iKeyValues.contains(aChar);
 	}
-#endif // #if defined(USE_ORBIT_KEYMAP)
 
 // ----------------------------------------------------------------------------
 // CQwertyKeyMap::MapKeyNameToValue
@@ -256,11 +219,7 @@
     QT_TRYCATCH_ERROR(err, ConstructKeyNameMap());
     User::LeaveIfError(err);
 
-#if defined(USE_ORBIT_KEYMAP)
 	CPcsKeyMap::ConstructL(HbKeyboardVirtualQwerty);
-#else
-	CPcsKeyMap::ConstructL();
-#endif
 
 	PRINT(_L("End CQwertyKeyMap::ConstructL"));
 	}
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/cqwertypredictivesearchtable.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/cqwertypredictivesearchtable.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -184,12 +184,7 @@
 
 TBool CQwertyPredictiveSearchTable::IsValidChar(const QChar aChar) const
 	{
-#if defined(USE_ORBIT_KEYMAP)
 	return static_cast<CQwertyKeyMap*>(iKeyMap)->IsValidChar(aChar);
-#else
-	const QChar PAD_CHAR = '!'; // This is a hack, must have same value as in cqwertykeymap.cpp
-	return static_cast<CQwertyKeyMap*>(iKeyMap)->UseHardcodedKeyMap(aChar) != PAD_CHAR;
-#endif
 	}
 
 
@@ -260,20 +255,18 @@
 * Fetch up to 3 mail addresses
 */
 QStringList CQwertyPredictiveSearchTable::GetTableSpecificFields(
-	const CContactItem& aItem,
-	TBool& aMandatoryFieldsPresent) const
+	const CContactItem& aItem) const
 	{
 	PRINT(_L("CQwertyPredictiveSearchTable::GetTableSpecificFields"));
 
 	QStringList mailAddresses;
 	
-	// Check that the contact item is a card, own card or ICC entry.
+	// Check the contact item is a card, own card or ICC entry.
 	const TUid KType = aItem.Type();
 	if (KType != KUidContactCard &&
 		KType != KUidContactOwnCard &&
 		KType != KUidContactICCEntry)
 		{
-		aMandatoryFieldsPresent = EFalse;
 		return mailAddresses;
 		}
 
@@ -301,13 +294,23 @@
 				PRINT1(_L("prefix removed, mail='%S'"), &log);
 #endif
 				}
-			mailAddresses.append(iKeyMap->GetMappedString(address));
-			++storedAddressCount;
+            // Ignore mail addresses that begin with unmapped character
+            QString mapped = iKeyMap->GetMappedString(address);
+            if (mapped.length() > 0 && IsValidChar(mapped[0]))
+                {
+                mailAddresses.append(mapped);
+                ++storedAddressCount;
+                }
+#if defined(WRITE_PRED_SEARCH_LOGS)
+			else
+				{
+				PRINT(_L("mail begins with unmapped char, ignore mail"));
+				}
+#endif
 			}
 		}
 	PRINT1(_L("CQwertyPredictiveSearchTable::GetTableSpecificFields found %d mail addrs"),
 		   mailAddresses.count());
-	aMandatoryFieldsPresent = (mailAddresses.count() > 0);
 	return mailAddresses;
 	}
 
--- a/plugins/contacts/symbian/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -31,7 +31,10 @@
 #include "cpredictivesearchsettingstable.h"
 #include "cpredictivesearchsynchronizer.h"
 #include "predictivesearchlog.h"
+#include "cntsqlsearch.h"
+
 //#include "cntmetadataoperation.h"
+
 #include <cntdef.h>
 #include <sqldb.h>
 #include <cntdb.h>
@@ -827,6 +830,24 @@
     return array;
     }
 
+
+CBufSeg* CPplContactItemManager::DetailsListPredictiveL(const TDesC& aSearchPattern ) const
+    {
+    
+	
+    QString qString;
+    QString queryString;
+    CntSqlSearch sqlSearch( *iPredSearch12keyTable->KeyMap(), 
+	                        *iPredSearchQwertyTable->KeyMap() );
+
+    QT_TRYCATCH_LEAVING({
+        qString = QString((QChar*)aSearchPattern.Ptr(),aSearchPattern.Length());
+        queryString = sqlSearch.CreatePredictiveSearch( qString );
+        });
+    TPtrC query (reinterpret_cast<const TText*>(queryString.constData()),queryString.length());   
+    return DetailsListL( query );
+    }
+
 /**
 Utility method used to rthe prefered card template id
 */
@@ -857,3 +878,5 @@
 	iPredictiveSearchSynchronizer->CreatePredSearchTablesL();
 #endif
 	}
+
+
--- a/plugins/contacts/symbian/contactsmodel/cntsrv/inc/ccntfilemanagermsghandler.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntsrv/inc/ccntfilemanagermsghandler.h	Mon Oct 04 01:37:06 2010 +0300
@@ -27,7 +27,7 @@
 #define CNTFILEMANAGERMSGHANDLER_H
 
 class CCntMsgHandler;
-class CntPredictiveSearch;
+
 /**
 CCntFileManagerMsgHandler class handles all file related operations. It uses
 a message handling method to handle the incoming op code.
@@ -89,8 +89,6 @@
 private:
 	void FileOpenCreateReplaceL(const RMessage2& aMessage, TCntFileMode aMode);
 	
-private:
-	CntPredictiveSearch* predictiveSearch;
 	};
 	
 #endif
--- a/plugins/contacts/symbian/contactsmodel/cntsrv/inc/persistencelayer.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntsrv/inc/persistencelayer.h	Mon Oct 04 01:37:06 2010 +0300
@@ -175,6 +175,8 @@
 	virtual CContactIdArray& CardTemplateIdsL() = 0;
 	virtual CContactIdArray& GroupIdListL() = 0;
     virtual CBufSeg* DetailsListL(const TDesC& aSearchQuery) const = 0;
+    virtual CBufSeg* DetailsListPredictiveL(const TDesC& aSearchPattern) const = 0;
+    
 	virtual void SetMachineIdL(TInt64 aMachineId) = 0;
 	virtual TPtrC UniqueIdL() = 0; 
 	
--- a/plugins/contacts/symbian/contactsmodel/cntsrv/src/ccntfilemanagermsghandler.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/cntsrv/src/ccntfilemanagermsghandler.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -37,7 +37,6 @@
 #include <cntviewstore.h>
 #include "cntviewprivate.h"
 #include "cviewsubsessions.h"
-#include "cntpredictivesearch.h"
 
 const TInt KCntFileManagerIpcCodes[] =
 	{
@@ -81,13 +80,11 @@
 // ----------------------------------------------------------------------------
 void CCntFileManagerMsgHandler::ConstructL()
     {
-    predictiveSearch = CntPredictiveSearch::NewL();
     }
 
 CCntFileManagerMsgHandler::~CCntFileManagerMsgHandler()
-	{
-    delete predictiveSearch;
-	}
+    {
+    }
 
 /**
 Delegates the incoming op code to a message handling method.
@@ -402,14 +399,12 @@
 void CCntFileManagerMsgHandler::FetchPredictiveSearchResultsL(const RMessage2& aMessage)
     {
     const TInt KSqlQueryMaxLen = aMessage.GetDesLengthL(1); 
-    HBufC* searchQuery = HBufC::NewLC(KSqlQueryMaxLen);
-    TPtr searchQueryPtr(searchQuery->Des());
-    aMessage.ReadL(1, searchQueryPtr);
+    HBufC* searchPattern = HBufC::NewLC(KSqlQueryMaxLen);
+    TPtr searchPatternPtr(searchPattern->Des());
+    aMessage.ReadL(1, searchPatternPtr);
     
     CheckForManagerL();
-    HBufC* newPredictiveQuery = predictiveSearch->CreateSQLQueryL(*searchQuery, 1 );
-    CleanupStack::PushL(newPredictiveQuery);
-    CBufSeg* buffer = iManager->GetPersistenceLayer().ContactProperties().DetailsListL(newPredictiveQuery->Des());
+    CBufSeg* buffer = iManager->GetPersistenceLayer().ContactProperties().DetailsListPredictiveL(searchPattern->Des());
     if (aMessage.GetDesMaxLength(0) >= buffer->Size())
         {
         TInt offset = 0;
@@ -427,9 +422,9 @@
         }
 
     delete buffer;
-    CleanupStack::PopAndDestroy(); //searchQuery*/
-    CleanupStack::PopAndDestroy(); //newPredictiveQuery
+    CleanupStack::PopAndDestroy( searchPattern ); 
     }
+
 void CCntFileManagerMsgHandler::FetchSearchResultsL(const RMessage2& aMessage)
     {
     const TInt KSqlQueryMaxLen = aMessage.GetDesLengthL(1); 
--- a/plugins/contacts/symbian/contactsmodel/contactsmodel.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/contactsmodel.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -13,7 +13,7 @@
 # Nokia Corporation - initial contribution.
 #
 # Contributors:
-# 
+#
 # Description:
 #
 #
@@ -24,7 +24,10 @@
                              "./group/cntview.mmp"\
                              "./group/template.mmp"\
                              "./groupsql/cntsrv.mmp"\
-                             "./groupsql/cntplsql.mmp"
+                             "./groupsql/cntplsql.mmp"\
+                             "./cntmatchlog/group/cntmatchlog.mmp"\
+                             "./cntvcard/cntvcard.mmp"\
+                             "./cntphone/cntphone.mmp"
 
 # Exports
 deploy.path = /
@@ -34,28 +37,30 @@
 iby.sources = cntmodel.iby cntplsql.iby
 
 for(iby, iby.sources):BLD_INF_RULES.prj_exports += "groupsql/$$iby $$deploy.path$$iby.path/$$iby"
+BLD_INF_RULES.prj_exports += "cntmatchlog/group/cntmatchlog.iby $$deploy.path$$iby.path/cntmatchlog.iby"
 
 # Headers
-headers.path = epoc32/include
-headers.sources = inc/cntdef.h\
-                  inc/cntdb.h\
-                  inc/cntdbobs.h\
-                  inc/cntfield.h\
-                  inc/cntfldst.h\
-                  inc/cntfilt.h\ 
-                  inc/cntitem.h\ 
-                  inc/cntview.h\
-                  inc/cntviewbase.h\
-                  inc/cntsync.h\
-                  inc/cntviewfindconfig.h\
-                  inc/cntviewfindconfig.inl\
-                  inc/cntviewsortplugin.h\
-                  inc/cntmodel.rh\
-                  inc/cntdef.hrh\
-                  inc/cntviewstore.h\
-                  inc/cntpredictivesearch.h\
-                  cntvcard/cntvcard.h\
-                 
+BLD_INF_RULES.prj_exports += "./inc/cntdef.h              /epoc32/include/cntdef.h"\
+                             "./inc/cntdb.h               /epoc32/include/cntdb.h"\
+                             "./inc/cntdbobs.h            /epoc32/include/cntdbobs.h"\
+                             "./inc/cntfield.h            /epoc32/include/cntfield.h"\
+                             "./inc/cntfldst.h            /epoc32/include/cntfldst.h"\
+                             "./inc/cntfilt.h             /epoc32/include/cntfilt.h"\
+                             "./inc/cntitem.h             /epoc32/include/cntitem.h"\
+                             "./inc/cntview.h             /epoc32/include/cntview.h"\
+                             "./inc/cntviewbase.h         /epoc32/include/cntviewbase.h"\
+                             "./inc/cntsync.h             /epoc32/include/cntsync.h"\
+                             "./inc/cntviewfindconfig.h   /epoc32/include/cntviewfindconfig.h"\
+                             "./inc/cntviewfindconfig.inl /epoc32/include/cntviewfindconfig.inl"\
+                             "./inc/cntviewsortplugin.h   /epoc32/include/cntviewsortplugin.h"\
+                             "./inc/cntmodel.rh           /epoc32/include/cntmodel.rh"\
+                             "./inc/cntdef.hrh            /epoc32/include/cntdef.hrh"\
+                             "./cntvcard/cntvcard.h       /epoc32/include/cntvcard.h"\
+                             "./inc/cntviewstore.h        /epoc32/include/cntviewstore.h"
 
-for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
+BLD_INF_RULES.prj_exports += "./inc/cntphonenumparser.h APP_LAYER_PLATFORM_EXPORT_PATH(cntphonenumparser.h)"\
+                             "./inc/cntviewsortpluginbase.h APP_LAYER_PLATFORM_EXPORT_PATH(cntviewsortpluginbase.h)"\
+                             "./inc/cntsyncecom.h APP_LAYER_PLATFORM_EXPORT_PATH(cntsyncecom.h)"\
+                             "./inc/cntconvertercallback.h APP_LAYER_PLATFORM_EXPORT_PATH(cntconvertercallback.h)"\
+                             "./inc/cntdb_internal.h APP_LAYER_PLATFORM_EXPORT_PATH(cntdb_internal.h)"
 
--- a/plugins/contacts/symbian/contactsmodel/eabi/cntmodlv2_sqliteu.def	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/eabi/cntmodlv2_sqliteu.def	Mon Oct 04 01:37:06 2010 +0300
@@ -702,4 +702,6 @@
 	_ZN16CContactDatabase16RemoveObserverV2ERK20MContactDbObserverV2 @ 701 NONAME
 	_ZN16CContactDatabase7OpenV2LENS_13TThreadAccessE @ 702 NONAME
 	_ZN16CContactDatabase9CreateV2LENS_13TThreadAccessE @ 703 NONAME
+	_ZN16CContactDatabase19AddContactsToGroupLER6RArrayIlEl @ 704 NONAME
+	_ZN16CContactDatabase24RemoveContactsFromGroupLER6RArrayIlEl @ 705 NONAME
 
--- a/plugins/contacts/symbian/contactsmodel/eabi/cntplsqlu.def	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/eabi/cntplsqlu.def	Mon Oct 04 01:37:06 2010 +0300
@@ -18,9 +18,4 @@
 	_ZTV20CContactSynchroniser @ 17 NONAME
 	_ZTV20MContactSynchroniser @ 18 NONAME
 	KContactsModelSqliteDbCacheSize @ 19 NONAME DATA 4
-	_ZN19CntPredictiveSearch15CreateSQLQueryLER7HBufC16i @ 20 NONAME
-	_ZN19CntPredictiveSearch4NewLEv @ 21 NONAME
-	_ZN19CntPredictiveSearchD0Ev @ 22 NONAME
-	_ZN19CntPredictiveSearchD1Ev @ 23 NONAME
-	_ZN19CntPredictiveSearchD2Ev @ 24 NONAME
-
+	
Binary file plugins/contacts/symbian/contactsmodel/group/1020384e.txt has changed
--- a/plugins/contacts/symbian/contactsmodel/group/common.inf	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/group/common.inf	Mon Oct 04 01:37:06 2010 +0300
@@ -22,37 +22,6 @@
 */
 
 PRJ_EXPORTS
-../inc/CNTDEF.H APP_LAYER_PUBLIC_EXPORT_PATH(cntdef.h)
-../inc/CNTDB.H APP_LAYER_PUBLIC_EXPORT_PATH(cntdb.h)         
-../inc/CNTDBOBS.H APP_LAYER_PUBLIC_EXPORT_PATH(cntdbobs.h)      
-../inc/CNTFIELD.H APP_LAYER_PUBLIC_EXPORT_PATH(cntfield.h)      
-../inc/CNTFLDST.H APP_LAYER_PUBLIC_EXPORT_PATH(cntfldst.h)	
-../inc/CNTFILT.H APP_LAYER_PUBLIC_EXPORT_PATH(cntfilt.h)	
-../inc/CNTITEM.H APP_LAYER_PUBLIC_EXPORT_PATH(cntitem.h)       
-../inc/cntview.h APP_LAYER_PUBLIC_EXPORT_PATH(cntview.h)
-../inc/cntviewbase.h APP_LAYER_PUBLIC_EXPORT_PATH(cntviewbase.h)
-../inc/cntsync.h APP_LAYER_PUBLIC_EXPORT_PATH(cntsync.h)
-//Cntmodel Find configuration Implementation definition header.
-../inc/cntviewfindconfig.h	 APP_LAYER_PLATFORM_EXPORT_PATH(cntviewfindconfig.h)
-../inc/cntviewfindconfig.inl APP_LAYER_PLATFORM_EXPORT_PATH(cntviewfindconfig.inl)
-//CntModel Sort Plug-in implementation definition header
-../inc/cntviewsortplugin.h APP_LAYER_PUBLIC_EXPORT_PATH(cntviewsortplugin.h)
-#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
-../inc/cntphonenumparser.h APP_LAYER_PLATFORM_EXPORT_PATH(cntphonenumparser.h)
-../inc/cntviewsortpluginbase.h APP_LAYER_PLATFORM_EXPORT_PATH(cntviewsortpluginbase.h)
-../inc/cntsyncecom.h APP_LAYER_PLATFORM_EXPORT_PATH(cntsyncecom.h)
-#endif
-
-../inc/CNTMODEL.RH APP_LAYER_PLATFORM_EXPORT_PATH(cntmodel.rh)
-../inc/CNTDEF.HRH APP_LAYER_PUBLIC_EXPORT_PATH(cntdef.hrh)
-
- 
-// VCard Converter Plugin
-../cntvcard/CNTVCARD.H APP_LAYER_PUBLIC_EXPORT_PATH(cntvcard.h)
-
-// Default View Definition store
-../inc/cntviewstore.h APP_LAYER_PLATFORM_EXPORT_PATH(cntviewstore.h)
-
 // Documentation (not exported until re-contributed to Symbian Foundation)
 // ../documentation/contacts_connectivityapi.doc	/epoc32/engdoc/cntmodel/contacts_connectivityapi.doc
 // ../documentation/contacts_current_itemapi.doc	/epoc32/engdoc/cntmodel/contacts_current_itemapi.doc
--- a/plugins/contacts/symbian/contactsmodel/groupsql/cntmodel.iby	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/groupsql/cntmodel.iby	Mon Oct 04 01:37:06 2010 +0300
@@ -33,9 +33,9 @@
 #define CONTACT_SERVER_MAX_HEAPSIZE  0x100000
 #endif
 
-file=ABI_DIR\BUILD_DIR\cntsrv.exe		System\Programs\cntsrv.exe       heapmax=CONTACT_SERVER_MAX_HEAPSIZE
-file=ABI_DIR\BUILD_DIR\cntmodel.dll		System\Libs\cntmodel.dll
-file=ABI_DIR\BUILD_DIR\cntview.dll		System\Libs\cntview.dll
+file=ABI_DIR/BUILD_DIR/cntsrv.exe		System/Programs/cntsrv.exe       heapmax=CONTACT_SERVER_MAX_HEAPSIZE
+file=ABI_DIR/BUILD_DIR/cntmodel.dll		System/Libs/cntmodel.dll
+file=ABI_DIR/BUILD_DIR/cntview.dll		System/Libs/cntview.dll
 
 ECOM_PLUGIN(cntvcard.dll,102035f8.rsc)
 ECOM_PLUGIN(cntphone.dll,102035fb.rsc)
--- a/plugins/contacts/symbian/contactsmodel/groupsql/cntplsql.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/groupsql/cntplsql.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -94,7 +94,6 @@
 source		cqwertykeymap.cpp
 //source		cntmetadataoperation.cpp
 source		cpplpresencetable.cpp
-source    cntpredictivesearch.cpp
 source    cntsqlsearch.cpp
 
 LIBRARY         euser.lib 
--- a/plugins/contacts/symbian/contactsmodel/inc/cntdb.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/inc/cntdb.h	Mon Oct 04 01:37:06 2010 +0300
@@ -816,8 +816,10 @@
 	IMPORT_C void AddContactToGroupL(TContactItemId aItemId, TContactItemId aGroupId);
 	IMPORT_C void AddContactToGroupL(CContactItem& aItem, CContactItem& aGroup);
 	IMPORT_C void AddContactToGroupL(TContactItemId aItemId, TContactItemId aGroupId,TBool aInTransaction);
+    IMPORT_C void AddContactsToGroupL(RArray<TContactItemId>& aItemIdList, TContactItemId aGroupId);
 	IMPORT_C void RemoveContactFromGroupL(CContactItem& aItem, CContactItem& aGroup);
 	IMPORT_C void RemoveContactFromGroupL(TContactItemId aItemId, TContactItemId aGroupId);
+    IMPORT_C void RemoveContactsFromGroupL(RArray<TContactItemId>& aItemIdList, TContactItemId aGroupId);
 	inline TInt GroupCount() const;
 	inline TInt TemplateCount() const;
 
--- a/plugins/contacts/symbian/contactsmodel/inc/cntpredictivesearch.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
-* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Class to hold the character to key mappings and provide
-*   conversion of strings to their numerical mappings. 
-*
-*/
-
-#ifndef __CNTPREDICTIVESEARCH_H__
-#define __CNTPREDICTIVESEARCH_H__
-
-// INCLUDES
-#include <e32base.h>
-
-// FORWARD DECLARATIONS
-
-
-// CLASS DECLARATION
-NONSHARABLE_CLASS (CntPredictiveSearch) : public CBase
-{
-public:
-    
-    /**
-     * Two phase construction
-     */
-    IMPORT_C static  CntPredictiveSearch* NewL();
-    
-    /**
-     * Destructor
-     */
-    IMPORT_C virtual ~CntPredictiveSearch();
-
-public:
-
-    /**
-    * Construct SQL query.
-    * aKeypad ETrue indicates key pad type.
-    *                        
-    */
-    IMPORT_C  HBufC* CreateSQLQueryL(HBufC& searchQuery, int aKeypad);
-    
-private:
-    /**
-    * Constructor
-    */
-    CntPredictiveSearch();
-      
-    /**
-    * Second phase constructor
-    */
-    void ConstructL();
-    
-};
-#endif // __CNTPREDICTIVESEARCH_H__
-
-// End of file
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_cprogressnotification.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_cprogressnotification.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -22,11 +22,11 @@
 UID				0x102744D4
 VENDORID 		0x70000001
  
-systeminclude	/epoc32/include 
-systeminclude ../../cntmodel/inc 
-systeminclude ../NbCntTestLib
+APP_LAYER_SYSTEMINCLUDE
 
 userinclude 	. 
+userinclude ../../cntmodel/inc 
+userinclude ../NbCntTestLib
 
 SOURCEPATH	.
 source		T_CProgressNotification.cpp 
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_dbtransactiontest.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_dbtransactiontest.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -23,10 +23,10 @@
 UID		0x102731D4
 VENDORID 	0x70000001
 
-systeminclude   /EPOC32/INCLUDE 
-systeminclude 	../NbCntTestLib
+APP_LAYER_SYSTEMINCLUDE
 
 userinclude 	.
+userinclude 	../NbCntTestLib
 
 SOURCEPATH	.
 source          T_DBTransactionTest.cpp
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_states.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_states.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -22,11 +22,11 @@
 UID				0x1027289C
 VENDORID 		0x70000001
  
-systeminclude	/EPOC32/INCLUDE 
-systeminclude 	../../CNTMODEL/INC 
-systeminclude 	../NbCntTestLib
+APP_LAYER_SYSTEMINCLUDE 
 
 userinclude 	. 
+userinclude 	../../CNTMODEL/INC 
+userinclude 	../NbCntTestLib
 
 SOURCEPATH	.
 source		T_CStatesTest.cpp 
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_templatecache.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntmodel2/t_templatecache.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -22,13 +22,12 @@
 UID				0x102730F8
 VENDORID 		0x70000001
 
-systeminclude	/EPOC32/INCLUDE 
-systeminclude 	../../CNTMODEL/INC 
-systeminclude 	../../src
-systeminclude 	../NbCntTestLib
+APP_LAYER_SYSTEMINCLUDE
 
 userinclude 	. 
-
+userinclude 	../../CNTMODEL/INC 
+userinclude 	../../src
+userinclude 	../NbCntTestLib
 
 SOURCEPATH	.
 source		T_TemplateCache.cpp 
Binary file plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/contacts_just_12key_tables.db has changed
Binary file plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/contacts_language_45.db has changed
Binary file plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/contacts_without_pred_search_tables.db has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/readme.txt	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,13 @@
+Unit test cases of t_cntplsql.dll related to updating database
+that does not have all predictive search tables, require the
+following database files to be copied into
+\epoc32\winscw\c directory
+
+contacts_just_12key_tables.db
+contacts_language_45.db
+contacts_without_pred_search_tables.db
+
+
+
+Note: three test cases related to Thai language will fail unless
+SDK has a Thai-keymap.
\ No newline at end of file
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -23,9 +23,7 @@
 
 // SYSTEM INCLUDES
 #include <digia/eunit/eunitmacros.h>
-#if defined(USE_ORBIT_KEYMAP)
 #include <hbinputkeymapfactory.h>
-#endif
 
 
 // 10.1 wk12 SDK's Thai keymap does not map anything to *,# keys
@@ -134,11 +132,9 @@
 //
 void UT_CPcsKeyMap::SetupL()
     {
-#if defined(USE_ORBIT_KEYMAP)
     // Create singleton outside actual test cases so that it is not treated as
     // resource leak, since it can't be deleted.
     HbKeymapFactory::instance();
-#endif
     }
 
 // -----------------------------------------------------------------------------
@@ -158,7 +154,6 @@
 //
 void UT_CPcsKeyMap::UT_NewLL()
     {
-#if defined(USE_ORBIT_KEYMAP)
 	// Must be same as in c12keykeymap.cpp
 	const TInt KAmountOfKeys = 12;
 
@@ -168,7 +163,6 @@
         {
         EUNIT_ASSERT( iKeyMap->iKeyMapping.at(i).length() > 0 );
         }
-#endif
     }
 
 // -----------------------------------------------------------------------------
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -102,20 +102,9 @@
     // It generates the test case table.
     CEUnitTestSuiteClass::ConstructL();
     
-#if defined(USE_ORBIT_KEYMAP)
     // Create singleton outside actual test cases so that it is not treated as
     // resource leak, since it can't be deleted.
     HbKeymapFactory::instance();
-#else
-    // If Orbit keymap is not used, EUnit shows there is a resource leak in the
-    // first test case of UT_CPplPredictiveSearchTable that writes something to
-    // the database.
-    // To get rid of the resource leak, the following code is here to create DB,
-    // and one contact, delete it, delete DB. 
-    SetupL();
-    UT_DeleteLL(); // Adds and deletes 1 contact
-    Teardown();
-#endif
     }
     
 // -----------------------------------------------------------------------------
@@ -143,9 +132,7 @@
                                             *iTable,
                                             *iPredSearchQwertyTable,
                                             *iPredSearchSettingsTable);  
-#if defined(USE_ORBIT_KEYMAP)
     HbKeymapFactory::instance();
-#endif
 	}
     
 // -----------------------------------------------------------------------------
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -22,9 +22,7 @@
 
 // SYSTEM INCLUDES
 #include <digia/eunit/eunitmacros.h>
-#if defined(USE_ORBIT_KEYMAP)
 #include <hbinputkeymapfactory.h>
-#endif
 
     
 // -----------------------------------------------------------------------------
@@ -89,11 +87,9 @@
 //
 void UT_CQwertyKeyMap::SetupL()
     {
-#if defined(USE_ORBIT_KEYMAP)
     // Create singleton outside actual test cases so that it is not treated as
     // resource leak, since it can't be deleted.
     HbKeymapFactory::instance();
-#endif
     }
     
 // -----------------------------------------------------------------------------
@@ -113,7 +109,6 @@
 //
 void UT_CQwertyKeyMap::UT_NewLL()
     {
-#if defined(USE_ORBIT_KEYMAP)
     // Check each key has been mapped
 	EUNIT_ASSERT_EQUALS(CQwertyKeyMap::EAmountOfKeysInQwertyKeypad,
 					    iKeyMap->iKeyMapping.count());
@@ -125,7 +120,6 @@
         {
         EUNIT_ASSERT(iKeyMap->iKeyMapping.at(i).length() > 0);
         }
-#endif
     }
 
 // -----------------------------------------------------------------------------
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -92,13 +92,10 @@
     // The ConstructL from the base class CEUnitTestSuiteClass must be called.
     // It generates the test case table.
     CEUnitTestSuiteClass::ConstructL();
-    
 
-#if defined(USE_ORBIT_KEYMAP)
     // Create singleton outside actual test cases so that it is not treated as
     // resource leak, since it can't be deleted.
     HbKeymapFactory::instance();
-#endif
     }
     
 // -----------------------------------------------------------------------------
@@ -240,6 +237,44 @@
     }
 
 // -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::UT_UnmappedMailAddressL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::UT_UnmappedMailAddressL()
+    {
+    // All names and mail addresses begin with unmapped characters, so contact
+    // is not stored to QWERTY tables at all.
+    _LIT(KUnmappedName, "8nbrAtStart");
+    _LIT(KNameWithUnmappedChars, "rname28afterNbr");
+    _LIT(KUnmappedMail, "mailto:123user@domain");
+    _LIT(KUnmappedMail2, "800@call.id");
+    _LIT(KUnmappedMail3, "5begins@by.nbr");
+    AddContactL(KTestContactId, KUnmappedName, KNullDesC, KUnmappedMail, KUnmappedMail2); 
+    // Check tables are empty
+    CheckItemCountL(InitTableVector());
+    
+    
+    // One mail address begin with a mapped character
+    AddContactL(KTestContactId2, KNullDesC, KNameWithUnmappedChars, 
+                KUnmappedMail, KUnmappedMail2, KMail);
+    
+    QVector<TInt> result = InitTableVector();
+    result[3] = 1; // KNameWithUnmappedChars
+    result[4] = 1; // KMail
+    CheckItemCountL(result);
+    
+   
+    // All mail addresses begin with unmapped characters, but contact can be
+    // searched by first name and last name. Contact is stored to QWERTY tables.
+    AddContactL(KTestContactId3, KNameWithUnmappedChars, KLastName, 
+                KUnmappedMail, KUnmappedMail2, KUnmappedMail3);
+    
+    result[2] = 1; // KLastName
+    result[3] = 2; // Second KNameWithUnmappedChars
+    CheckItemCountL(result);
+    }
+
+// -----------------------------------------------------------------------------
 // UT_CQwertyPredictiveSearchTable::InitTableVector
 // -----------------------------------------------------------------------------
 //
@@ -398,6 +433,13 @@
     "FUNCTIONALITY",
     SetupL, UT_DeleteLL, Teardown )
 
+EUNIT_TEST(
+    "CreateInDbL - unmapped mail address",
+    "UT_CQwertyPredictiveSearchTable",
+    "CreateInDbL",
+    "FUNCTIONALITY",
+    SetupL, UT_UnmappedMailAddressL, Teardown )
+
 EUNIT_END_TEST_TABLE
 
 //  END OF FILE
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.h	Mon Oct 04 01:37:06 2010 +0300
@@ -65,6 +65,7 @@
         void UT_CreateInDbLL();
 		void UT_UpdateLL();
 		void UT_DeleteLL();
+		void UT_UnmappedMailAddressL();
         
     private: // New functions
         QVector<TInt> InitTableVector() const;
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/main.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/main.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -1,43 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Retrieves the character map for each of the numeric keys.
+*/
 
 #include "testrunner.h"
 #include "ut_cntsqlsearch.h"
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/runtest.cmd	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/runtest.cmd	Mon Oct 04 01:37:06 2010 +0300
@@ -1,3 +1,20 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
 call qmake
 call sbs reallyclean
 call qmake
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -18,9 +18,12 @@
 #include <QtTest/QtTest>
 #include <QStringList>
 #include <QLocale>
+#include <sqldb.h>
 
 #include "ut_cntsqlsearch.h"
 #include "cntsqlsearch.h"
+#include "cqwertykeymap.h"
+#include "c12keykeymap.h"
 
 #define WRITE_LOGS
 #define SQL_QT_TEST
@@ -53,14 +56,17 @@
 
 
 void UT_CntSqlSearch::init()
-{
-mCntSqlSearch = new CntSqlSearch();
+{   
+    m12KeyKeyMap = C12keyKeyMap::NewL();
+    mQwertyKeyMap = CQwertyKeyMap::NewL();
+    mCntSqlSearch = new CntSqlSearch( *m12KeyKeyMap, *mQwertyKeyMap );
 }
 
 void UT_CntSqlSearch::cleanup()
 {
+    delete m12KeyKeyMap;
+    delete mQwertyKeyMap;
     delete mCntSqlSearch;
-    mCntSqlSearch = 0;
     
 }
 void UT_CntSqlSearch::testPredictiveSearch()
@@ -181,7 +187,7 @@
     pattern = "0705";
     #if defined(SEARCH_FROM_ONE_TABLE)
 #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>31613158321815551 AND nbr<31630750507859968) AND NOT(nbr2>31613158321815551 AND nbr2<31630750507859968) AND NOT(nbr3>31613158321815551 AND nbr3<31630750507859968) AND NOT(nbr4>31613158321815551 AND nbr4<31630750507859968))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>31525197391593471 AND nbr3<36028797018963968))) AND NOT(NOT(NOT(nbr2>31525197391593471 AND nbr2<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch7.contact_id, predictivesearch7.first_name, predictivesearch7.last_name FROM predictivesearch7 WHERE ((NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>504403158265495551 AND nbr3<576460752303423488))) OR(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>31613158321815551 AND predictivesearch0.nbr<31630750507859968) AND NOT(predictivesearch0.nbr2>31613158321815551 AND predictivesearch0.nbr2<31630750507859968) AND NOT(predictivesearch0.nbr3>31613158321815551 AND predictivesearch0.nbr3<31630750507859968) AND NOT(predictivesearch0.nbr4>31613158321815551 AND predictivesearch0.nbr4<31630750507859968)))) OR(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>31525197391593471 AND nbr3<36028797018963968))) OR(NOT(NOT(nbr2>31525197391593471 AND nbr2<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #else // #if defined(USE_DEMORGAN)
 
 #endif //#if defined(USE_DEMORGAN)
@@ -190,8 +196,8 @@
 #endif // #if defined(SEARCH_FROM_ONE_TABLE)
 
     result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    //qDebug() << pattern << result;
     LOG2(pattern, result);
+    //qDebug() << pattern << " -> result" << result;
     QVERIFY(!result.compare(reference));
     
     pattern.clear();
@@ -291,12 +297,11 @@
     // Leading zeros
     pattern = QString("001100");
 #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (NOT(NOT(nbr>299067162755071 AND nbr<299135882231808) AND NOT(nbr2>299067162755071 AND nbr2<299135882231808) AND NOT(nbr3>299067162755071 AND nbr3<299135882231808) AND NOT(nbr4>299067162755071 AND nbr4<299135882231808))) ORDER BY first_name, last_name ASC;");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch1.contact_id, predictivesearch1.first_name, predictivesearch1.last_name FROM predictivesearch1 WHERE ((NOT(NOT(predictivesearch1.nbr>76561193665298431 AND predictivesearch1.nbr<81064793292668928) AND NOT(predictivesearch1.nbr2>76561193665298431 AND predictivesearch1.nbr2<81064793292668928) AND NOT(predictivesearch1.nbr3>76561193665298431 AND predictivesearch1.nbr3<81064793292668928) AND NOT(predictivesearch1.nbr4>76561193665298431 AND predictivesearch1.nbr4<81064793292668928)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>299067162755071 AND predictivesearch0.nbr<299135882231808) AND NOT(predictivesearch0.nbr2>299067162755071 AND predictivesearch0.nbr2<299135882231808) AND NOT(predictivesearch0.nbr3>299067162755071 AND predictivesearch0.nbr3<299135882231808) AND NOT(predictivesearch0.nbr4>299067162755071 AND predictivesearch0.nbr4<299135882231808))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #else
     reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (nbr>299067162755071 AND nbr<299135882231808) OR (nbr2>299067162755071 AND nbr2<299135882231808) OR (nbr3>299067162755071 AND nbr3<299135882231808) OR (nbr4>299067162755071 AND nbr4<299135882231808) ORDER BY first_name, last_name ASC;");
 #endif
     result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    //qDebug() << pattern << " -> result" << result;
     LOG2(pattern, result);
     QVERIFY(!result.compare(reference));
     
@@ -309,7 +314,7 @@
 
     pattern = QString("0020030");
 #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>563156111851519 AND nbr<563160406818816) AND NOT(nbr2>563156111851519 AND nbr2<563160406818816) AND NOT(nbr3>563156111851519 AND nbr3<563160406818816) AND NOT(nbr4>563156111851519 AND nbr4<563160406818816))) AND NOT(NOT(NOT(nbr2>216172782113783807 AND nbr2<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr3>562949953421311 AND nbr3<844424930131968))) AND NOT(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>216172782113783807 AND nbr3<220676381741154304)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE ((NOT(NOT(nbr2>216172782113783807 AND nbr2<220676381741154304 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) OR(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>216172782113783807 AND nbr3<220676381741154304)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>563156111851519 AND predictivesearch0.nbr<563160406818816) AND NOT(predictivesearch0.nbr2>563156111851519 AND predictivesearch0.nbr2<563160406818816) AND NOT(predictivesearch0.nbr3>563156111851519 AND predictivesearch0.nbr3<563160406818816) AND NOT(predictivesearch0.nbr4>563156111851519 AND predictivesearch0.nbr4<563160406818816)))) OR(NOT(NOT(nbr2>216172782113783807 AND nbr2<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr3>562949953421311 AND nbr3<844424930131968))) OR(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>216172782113783807 AND nbr3<220676381741154304)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #else
     // TODO: add non-De Morgan case
 #endif
@@ -320,13 +325,13 @@
     
     pattern = QString("00430001020");
 #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>1178676735508479 AND nbr<1178676735574016) AND NOT(nbr2>1178676735508479 AND nbr2<1178676735574016) AND NOT(nbr3>1178676735508479 AND nbr3<1178676735574016) AND NOT(nbr4>1178676735508479 AND nbr4<1178676735574016))) AND NOT(NOT(NOT(nbr2>72620543991349247 AND nbr2<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr2>1178676464975871 AND nbr2<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr2>1178676464975871 AND nbr2<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr3>1178676464975871 AND nbr3<1196268651020288))) AND NOT(NOT(NOT(nbr2>1178676464975871 AND nbr2<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>1178676464975871 AND nbr3<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>1178676464975871 AND nbr3<1196268651020288 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr3>72620543991349247 AND nbr3<72638136177393664)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch4.contact_id, predictivesearch4.first_name, predictivesearch4.last_name FROM predictivesearch4 WHERE ((NOT(NOT(nbr2>72620543991349247 AND nbr2<72638136177393664 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr3>301741175033823231 AND nbr3<306244774661193728))) OR(NOT(NOT(nbr2>301741175033823231 AND nbr2<306244774661193728 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr3>72620543991349247 AND nbr3<72638136177393664)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>1178676735508479 AND predictivesearch0.nbr<1178676735574016) AND NOT(predictivesearch0.nbr2>1178676735508479 AND predictivesearch0.nbr2<1178676735574016) AND NOT(predictivesearch0.nbr3>1178676735508479 AND predictivesearch0.nbr3<1178676735574016) AND NOT(predictivesearch0.nbr4>1178676735508479 AND predictivesearch0.nbr4<1178676735574016)))) OR(NOT(NOT(nbr2>72620543991349247 AND nbr2<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr2>1178676464975871 AND nbr2<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr2>1178676464975871 AND nbr2<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr3>1178676464975871 AND nbr3<1196268651020288))) OR(NOT(NOT(nbr2>1178676464975871 AND nbr2<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>1178676464975871 AND nbr3<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>1178676464975871 AND nbr3<1196268651020288 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr3>72620543991349247 AND nbr3<72638136177393664)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #else
     // TODO: add non-De Morgan case
 #endif
     result = mCntSqlSearch->CreatePredictiveSearch(pattern);
+    LOG2(pattern, result);
     //qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
     QVERIFY(!result.compare(reference));
     
     pattern = QString("227264583788306"); // 15 digits
@@ -340,7 +345,6 @@
     LOG2(pattern, result);
     QVERIFY(!result.compare(reference));
  
-    
     pattern = QString("34096");
 #if defined(USE_DEMORGAN)
     reference = QString("SELECT contact_id FROM predictivesearch3 WHERE NOT(NOT(NOT(NOT(nbr>234352107367432191 AND nbr<234353206879059968) AND NOT(nbr2>234352107367432191 AND nbr2<234353206879059968) AND NOT(nbr3>234352107367432191 AND nbr3<234353206879059968) AND NOT(nbr4>234352107367432191 AND nbr4<234353206879059968))) AND NOT(NOT(NOT(nbr2>675539944105574399 AND nbr2<680043543732944896 AND nbr>234187180623265791 AND nbr<238690780250636288) AND NOT(nbr3>675539944105574399 AND nbr3<680043543732944896 AND nbr>234187180623265791 AND nbr<238690780250636288) AND NOT(nbr3>675539944105574399 AND nbr3<680043543732944896 AND nbr2>234187180623265791 AND nbr2<238690780250636288) AND NOT(nbr4>675539944105574399 AND nbr4<680043543732944896 AND nbr>234187180623265791 AND nbr<238690780250636288) AND NOT(nbr4>675539944105574399 AND nbr4<680043543732944896 AND nbr2>234187180623265791 AND nbr2<238690780250636288) AND NOT(nbr4>675539944105574399 AND nbr4<680043543732944896 AND nbr3>234187180623265791 AND nbr3<238690780250636288))) AND NOT(NOT(NOT(nbr2>234187180623265791 AND nbr2<238690780250636288 AND nbr>675539944105574399 AND nbr<680043543732944896) AND NOT(nbr3>234187180623265791 AND nbr3<238690780250636288 AND nbr>675539944105574399 AND nbr<680043543732944896) AND NOT(nbr3>234187180623265791 AND nbr3<238690780250636288 AND nbr2>675539944105574399 AND nbr2<680043543732944896) AND NOT(nbr4>234187180623265791 AND nbr4<238690780250636288 AND nbr>675539944105574399 AND nbr<680043543732944896) AND NOT(nbr4>234187180623265791 AND nbr4<238690780250636288 AND nbr2>675539944105574399 AND nbr2<680043543732944896) AND NOT(nbr4>234187180623265791 AND nbr4<238690780250636288 AND nbr3>675539944105574399 AND nbr3<680043543732944896)))) ORDER BY predictivesearch3.first_name, predictivesearch3.last_name ASC;");
@@ -376,7 +380,7 @@
 
     pattern = QString("200");
 #if defined(USE_DEMORGAN)
-        reference = QString("SELECT contact_id FROM predictivesearch2 WHERE (NOT(NOT(nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528))) ORDER BY first_name, last_name ASC;");
+        reference = QString("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808))) AND NOT(NOT(NOT(nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528)))) ORDER BY first_name, last_name ASC;");
 #else
     // TODO: add non-De Morgan case
 #endif
@@ -436,9 +440,15 @@
     pattern = QString("055");
     reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(predictivesearch5.nbr>382805968326492159 AND predictivesearch5.nbr<387309567953862656) AND NOT(predictivesearch5.nbr2>382805968326492159 AND predictivesearch5.nbr2<387309567953862656) AND NOT(predictivesearch5.nbr3>382805968326492159 AND predictivesearch5.nbr3<387309567953862656) AND NOT(predictivesearch5.nbr4>382805968326492159 AND predictivesearch5.nbr4<387309567953862656)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23925373020405759 AND predictivesearch0.nbr<24206847997116416) AND NOT(predictivesearch0.nbr2>23925373020405759 AND predictivesearch0.nbr2<24206847997116416) AND NOT(predictivesearch0.nbr3>23925373020405759 AND predictivesearch0.nbr3<24206847997116416) AND NOT(predictivesearch0.nbr4>23925373020405759 AND predictivesearch0.nbr4<24206847997116416))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
     result = mCntSqlSearch->CreatePredictiveSearch(pattern);   
+    //qDebug() << pattern << " -> result" << result;
     LOG2(pattern, result);
-    //qDebug() << pattern << " -> result" << result;
+   
     QVERIFY(!result.compare(reference));
+    
+    pattern = QString ("052207");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>369858119397801983 AND nbr3<370139594374512640))) OR(NOT(NOT(nbr2>369858119397801983 AND nbr2<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23116613498699775 AND predictivesearch0.nbr<23116682218176512) AND NOT(predictivesearch0.nbr2>23116613498699775 AND predictivesearch0.nbr2<23116682218176512) AND NOT(predictivesearch0.nbr3>23116613498699775 AND predictivesearch0.nbr3<23116682218176512) AND NOT(predictivesearch0.nbr4>23116613498699775 AND predictivesearch0.nbr4<23116682218176512)))) OR(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>23116132462362623 AND nbr2<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>23116132462362623 AND nbr2<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>23116132462362623 AND nbr3<23133724648407040))) OR(NOT(NOT(nbr2>23116132462362623 AND nbr2<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>23116132462362623 AND nbr3<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>23116132462362623 AND nbr3<23133724648407040 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CreatePredictiveSearch(pattern); 
+    QVERIFY( !result.compare( reference) );
     TEST_PASSED_LOG("testPredictiveSearch");
 }
 
@@ -451,11 +461,13 @@
     
     pattern = QString("000");
     result = mCntSqlSearch->selectQweryTable(pattern);
-    //QVERIFY(result == "qm0" );
+    //This case is ignore untli qwerty key map supports numbers
+    //QVERIFY(result == "" );
     
     pattern = QString("9");
     result = mCntSqlSearch->selectQweryTable(pattern);
     //QVERIFY(result == "qm9" );
+    //This case is ignore untli qwerty key map supports numbers
     TEST_PASSED_LOG("testSelectQweryTable");
     }
 
@@ -607,7 +619,7 @@
     pattern = QString("00202");
 #if defined(SEARCH_FROM_ONE_TABLE)
 #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>565148976676863 AND nbr<566248488304640) AND NOT(nbr2>565148976676863 AND nbr2<566248488304640) AND NOT(nbr3>565148976676863 AND nbr3<566248488304640) AND NOT(nbr4>565148976676863 AND nbr4<566248488304640))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>562949953421311 AND nbr3<844424930131968))) AND NOT(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<216172782113783808)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE ((NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) OR(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>144115188075855871 AND nbr3<216172782113783808)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>565148976676863 AND predictivesearch0.nbr<566248488304640) AND NOT(predictivesearch0.nbr2>565148976676863 AND predictivesearch0.nbr2<566248488304640) AND NOT(predictivesearch0.nbr3>565148976676863 AND predictivesearch0.nbr3<566248488304640) AND NOT(predictivesearch0.nbr4>565148976676863 AND predictivesearch0.nbr4<566248488304640)))) OR(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>562949953421311 AND nbr3<844424930131968))) OR(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<216172782113783808)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #else // #if defined(USE_DEMORGAN)
     reference = QString("SELECT contact_id FROM predictivesearch0 WHERE \
 ((nbr>565148976676863 AND nbr<566248488304640) OR \
@@ -633,8 +645,8 @@
     reference = QString("SELECT contact_id FROM (SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE (NOT(NOT(predictivesearch0.nbr>565148976676863 AND predictivesearch0.nbr<566248488304640) AND NOT(predictivesearch0.nbr2>565148976676863 AND predictivesearch0.nbr2<566248488304640) AND NOT(predictivesearch0.nbr3>565148976676863 AND predictivesearch0.nbr3<566248488304640) AND NOT(predictivesearch0.nbr4>565148976676863 AND predictivesearch0.nbr4<566248488304640))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 JOIN predictivesearch2 ON predictivesearch0.contact_id = predictivesearch2.contact_id WHERE(NOT(NOT(predictivesearch0.nbr>562949953421311 AND predictivesearch0.nbr<844424930131968) AND NOT(predictivesearch0.nbr2>562949953421311 AND predictivesearch0.nbr2<844424930131968) AND NOT(predictivesearch0.nbr3>562949953421311 AND predictivesearch0.nbr3<844424930131968) AND NOT(predictivesearch0.nbr4>562949953421311 AND predictivesearch0.nbr4<844424930131968)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #endif // #if defined(SEARCH_FROM_ONE_TABLE)
     result = mCntSqlSearch->CreateQuery(pattern);
-    //qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
+    //LOG2(pattern, result);
+    //qDebug() << pattern << " -> result" << result << " -> reference" << reference;
     QVERIFY( !result.compare( reference) );
 
     pattern = QString("202000");
@@ -664,13 +676,13 @@
 
     result = mCntSqlSearch->CreateQuery(pattern);
     //qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
+    //LOG2(pattern, result);
     QVERIFY( !result.compare( reference) );
 
     pattern = QString("0020200");
 #if defined(SEARCH_FROM_ONE_TABLE)
 #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>565148976676863 AND nbr<565153271644160) AND NOT(nbr2>565148976676863 AND nbr2<565153271644160) AND NOT(nbr3>565148976676863 AND nbr3<565153271644160) AND NOT(nbr4>565148976676863 AND nbr4<565153271644160))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr3>562949953421311 AND nbr3<844424930131968))) AND NOT(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<144396663052566528)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE ((NOT(NOT(nbr2>144115188075855871 AND nbr2<144396663052566528 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) OR(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>144115188075855871 AND nbr3<144396663052566528)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>565148976676863 AND predictivesearch0.nbr<565153271644160) AND NOT(predictivesearch0.nbr2>565148976676863 AND predictivesearch0.nbr2<565153271644160) AND NOT(predictivesearch0.nbr3>565148976676863 AND predictivesearch0.nbr3<565153271644160) AND NOT(predictivesearch0.nbr4>565148976676863 AND predictivesearch0.nbr4<565153271644160)))) OR(NOT(NOT(nbr2>144115188075855871 AND nbr2<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr3>562949953421311 AND nbr3<844424930131968))) OR(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<144396663052566528)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #else // #if defined(USE_DEMORGAN)
     reference = QString("SELECT contact_id FROM predictivesearch0 WHERE \
 ((nbr>565148976676863 AND nbr<565153271644160) OR (nbr2>565148976676863 AND nbr2<565153271644160) OR \
@@ -694,7 +706,7 @@
     reference = QString("SELECT contact_id FROM (SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE (NOT(NOT(predictivesearch0.nbr>565148976676863 AND predictivesearch0.nbr<565153271644160) AND NOT(predictivesearch0.nbr2>565148976676863 AND predictivesearch0.nbr2<565153271644160) AND NOT(predictivesearch0.nbr3>565148976676863 AND predictivesearch0.nbr3<565153271644160) AND NOT(predictivesearch0.nbr4>565148976676863 AND predictivesearch0.nbr4<565153271644160))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 JOIN predictivesearch2 ON predictivesearch0.contact_id = predictivesearch2.contact_id WHERE((NOT(NOT(predictivesearch0.nbr>562949953421311 AND predictivesearch0.nbr<844424930131968) AND NOT(predictivesearch0.nbr2>562949953421311 AND predictivesearch0.nbr2<844424930131968) AND NOT(predictivesearch0.nbr3>562949953421311 AND predictivesearch0.nbr3<844424930131968) AND NOT(predictivesearch0.nbr4>562949953421311 AND predictivesearch0.nbr4<844424930131968))) AND (NOT(NOT(predictivesearch2.nbr>144115188075855871 AND predictivesearch2.nbr<144396663052566528) AND NOT(predictivesearch2.nbr2>144115188075855871 AND predictivesearch2.nbr2<144396663052566528) AND NOT(predictivesearch2.nbr3>144115188075855871 AND predictivesearch2.nbr3<144396663052566528) AND NOT(predictivesearch2.nbr4>144115188075855871 AND predictivesearch2.nbr4<144396663052566528))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
 #endif //#if defined(SEARCH_FROM_ONE_TABLE) 
     result = mCntSqlSearch->CreateQuery(pattern);
-    //qDebug() << pattern << " -> result" << result;
+    qDebug() << pattern << " -> result" << result;
     LOG2(pattern, result);
     QVERIFY( !result.compare( reference) );
 
@@ -910,17 +922,72 @@
     reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(predictivesearch5.nbr>382805968326492159 AND predictivesearch5.nbr<387309567953862656) AND NOT(predictivesearch5.nbr2>382805968326492159 AND predictivesearch5.nbr2<387309567953862656) AND NOT(predictivesearch5.nbr3>382805968326492159 AND predictivesearch5.nbr3<387309567953862656) AND NOT(predictivesearch5.nbr4>382805968326492159 AND predictivesearch5.nbr4<387309567953862656)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23925373020405759 AND predictivesearch0.nbr<24206847997116416) AND NOT(predictivesearch0.nbr2>23925373020405759 AND predictivesearch0.nbr2<24206847997116416) AND NOT(predictivesearch0.nbr3>23925373020405759 AND predictivesearch0.nbr3<24206847997116416) AND NOT(predictivesearch0.nbr4>23925373020405759 AND predictivesearch0.nbr4<24206847997116416))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
     result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);  
     QVERIFY( !result.compare( reference) );
-    /*tokens.clear();
-    pattern = QString ("0550");
-    tokens << "55";
-    QString reference("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(predictivesearch5.nbr>23925373020405759 AND predictivesearch5.nbr<24206847997116416) AND NOT(predictivesearch5.nbr2>23925373020405759 AND predictivesearch5.nbr2<24206847997116416) AND NOT(predictivesearch5.nbr3>23925373020405759 AND predictivesearch5.nbr3<24206847997116416) AND NOT(predictivesearch5.nbr4>23925373020405759 AND predictivesearch5.nbr4<24206847997116416)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23925373020405759 AND predictivesearch0.nbr<24206847997116416) AND NOT(predictivesearch0.nbr2>23925373020405759 AND predictivesearch0.nbr2<24206847997116416) AND NOT(predictivesearch0.nbr3>23925373020405759 AND predictivesearch0.nbr3<24206847997116416) AND NOT(predictivesearch0.nbr4>23925373020405759 AND predictivesearch0.nbr4<24206847997116416))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-    QString result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);  
-        
+    
     tokens.clear();
     pattern = QString ("05505");
-    tokens << "55 << 5";
-    QString reference("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>145522562959409151 AND nbr<145804037936119808) AND NOT(nbr2>145522562959409151 AND nbr2<145804037936119808) AND NOT(nbr3>145522562959409151 AND nbr3<145804037936119808) AND NOT(nbr4>145522562959409151 AND nbr4<145804037936119808))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-    QString result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);*/  
+    tokens << "055" << "5";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>382805968326492159 AND nbr2<387309567953862656) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>382805968326492159 AND nbr<387309567953862656) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>382805968326492159 AND nbr2<387309567953862656) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>382805968326492159 AND nbr3<387309567953862656))) OR(NOT(NOT(nbr2>382805968326492159 AND nbr2<387309567953862656 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>382805968326492159 AND nbr3<387309567953862656 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>382805968326492159 AND nbr3<387309567953862656 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>382805968326492159 AND nbr4<387309567953862656 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23930870578544639 AND predictivesearch0.nbr<23931970090172416) AND NOT(predictivesearch0.nbr2>23930870578544639 AND predictivesearch0.nbr2<23931970090172416) AND NOT(predictivesearch0.nbr3>23930870578544639 AND predictivesearch0.nbr3<23931970090172416) AND NOT(predictivesearch0.nbr4>23930870578544639 AND predictivesearch0.nbr4<23931970090172416)))) OR(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>23925373020405759 AND nbr<24206847997116416) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>23925373020405759 AND nbr<24206847997116416) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>23925373020405759 AND nbr2<24206847997116416) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>23925373020405759 AND nbr<24206847997116416) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>23925373020405759 AND nbr2<24206847997116416) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>23925373020405759 AND nbr3<24206847997116416))) OR(NOT(NOT(nbr2>23925373020405759 AND nbr2<24206847997116416 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>23925373020405759 AND nbr3<24206847997116416 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>23925373020405759 AND nbr3<24206847997116416 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>23925373020405759 AND nbr4<24206847997116416 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>23925373020405759 AND nbr4<24206847997116416 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>23925373020405759 AND nbr4<24206847997116416 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("0550");
+    tokens << "055";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(predictivesearch5.nbr>382805968326492159 AND predictivesearch5.nbr<387309567953862656) AND NOT(predictivesearch5.nbr2>382805968326492159 AND predictivesearch5.nbr2<387309567953862656) AND NOT(predictivesearch5.nbr3>382805968326492159 AND predictivesearch5.nbr3<387309567953862656) AND NOT(predictivesearch5.nbr4>382805968326492159 AND predictivesearch5.nbr4<387309567953862656)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23925373020405759 AND predictivesearch0.nbr<23942965206450176) AND NOT(predictivesearch0.nbr2>23925373020405759 AND predictivesearch0.nbr2<23942965206450176) AND NOT(predictivesearch0.nbr3>23925373020405759 AND predictivesearch0.nbr3<23942965206450176) AND NOT(predictivesearch0.nbr4>23925373020405759 AND predictivesearch0.nbr4<23942965206450176))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("000550");
+    tokens << "00055";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(predictivesearch5.nbr>382805968326492159 AND predictivesearch5.nbr<387309567953862656) AND NOT(predictivesearch5.nbr2>382805968326492159 AND predictivesearch5.nbr2<387309567953862656) AND NOT(predictivesearch5.nbr3>382805968326492159 AND predictivesearch5.nbr3<387309567953862656) AND NOT(predictivesearch5.nbr4>382805968326492159 AND predictivesearch5.nbr4<387309567953862656)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>93458488360959 AND predictivesearch0.nbr<93527207837696) AND NOT(predictivesearch0.nbr2>93458488360959 AND predictivesearch0.nbr2<93527207837696) AND NOT(predictivesearch0.nbr3>93458488360959 AND predictivesearch0.nbr3<93527207837696) AND NOT(predictivesearch0.nbr4>93458488360959 AND predictivesearch0.nbr4<93527207837696))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);  
+    //qDebug() << pattern << " -> result" << result;
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("055000");
+    tokens << "055";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(predictivesearch5.nbr>382805968326492159 AND predictivesearch5.nbr<387309567953862656) AND NOT(predictivesearch5.nbr2>382805968326492159 AND predictivesearch5.nbr2<387309567953862656) AND NOT(predictivesearch5.nbr3>382805968326492159 AND predictivesearch5.nbr3<387309567953862656) AND NOT(predictivesearch5.nbr4>382805968326492159 AND predictivesearch5.nbr4<387309567953862656)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23925373020405759 AND predictivesearch0.nbr<23925441739882496) AND NOT(predictivesearch0.nbr2>23925373020405759 AND predictivesearch0.nbr2<23925441739882496) AND NOT(predictivesearch0.nbr3>23925373020405759 AND predictivesearch0.nbr3<23925441739882496) AND NOT(predictivesearch0.nbr4>23925373020405759 AND predictivesearch0.nbr4<23925441739882496))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    //qDebug() << pattern << " -> result" << result;
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("0500050");
+    tokens << "05" << "5";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>360287970189639679 AND nbr3<432345564227567616))) OR(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>22518341734236159 AND predictivesearch0.nbr<22518346029203456) AND NOT(predictivesearch0.nbr2>22518341734236159 AND predictivesearch0.nbr2<22518346029203456) AND NOT(predictivesearch0.nbr3>22518341734236159 AND predictivesearch0.nbr3<22518346029203456) AND NOT(predictivesearch0.nbr4>22518341734236159 AND predictivesearch0.nbr4<22518346029203456)))) OR(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>22517998136852479 AND nbr<27021597764222976) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>22517998136852479 AND nbr<27021597764222976) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>22517998136852479 AND nbr2<27021597764222976) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>22517998136852479 AND nbr<27021597764222976) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>22517998136852479 AND nbr2<27021597764222976) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>22517998136852479 AND nbr3<27021597764222976))) OR(NOT(NOT(nbr2>22517998136852479 AND nbr2<27021597764222976 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>22517998136852479 AND nbr3<27021597764222976 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>22517998136852479 AND nbr3<27021597764222976 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>22517998136852479 AND nbr4<27021597764222976 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>22517998136852479 AND nbr4<27021597764222976 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>22517998136852479 AND nbr4<27021597764222976 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("052207");
+    tokens << "0522" << "7";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>369858119397801983 AND nbr3<370139594374512640))) OR(NOT(NOT(nbr2>369858119397801983 AND nbr2<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23116613498699775 AND predictivesearch0.nbr<23116682218176512) AND NOT(predictivesearch0.nbr2>23116613498699775 AND predictivesearch0.nbr2<23116682218176512) AND NOT(predictivesearch0.nbr3>23116613498699775 AND predictivesearch0.nbr3<23116682218176512) AND NOT(predictivesearch0.nbr4>23116613498699775 AND predictivesearch0.nbr4<23116682218176512)))) OR(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>23116132462362623 AND nbr2<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>23116132462362623 AND nbr2<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>23116132462362623 AND nbr3<23133724648407040))) OR(NOT(NOT(nbr2>23116132462362623 AND nbr2<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>23116132462362623 AND nbr3<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>23116132462362623 AND nbr3<23133724648407040 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("052200007");
+    tokens << "0522" << "7";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>369858119397801983 AND nbr3<370139594374512640))) OR(NOT(NOT(nbr2>369858119397801983 AND nbr2<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>23116132579803135 AND predictivesearch0.nbr<23116132596580352) AND NOT(predictivesearch0.nbr2>23116132579803135 AND predictivesearch0.nbr2<23116132596580352) AND NOT(predictivesearch0.nbr3>23116132579803135 AND predictivesearch0.nbr3<23116132596580352) AND NOT(predictivesearch0.nbr4>23116132579803135 AND predictivesearch0.nbr4<23116132596580352)))) OR(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>23116132462362623 AND nbr2<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>23116132462362623 AND nbr<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>23116132462362623 AND nbr2<23133724648407040) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>23116132462362623 AND nbr3<23133724648407040))) OR(NOT(NOT(nbr2>23116132462362623 AND nbr2<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>23116132462362623 AND nbr3<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>23116132462362623 AND nbr3<23133724648407040 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>23116132462362623 AND nbr4<23133724648407040 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("0709");
+    tokens << "07" << "9";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch7.contact_id, predictivesearch7.first_name, predictivesearch7.last_name FROM predictivesearch7 WHERE ((NOT(NOT(nbr2>648518346341351423 AND nbr2<720575940379279360 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>648518346341351423 AND nbr3<720575940379279360 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>648518346341351423 AND nbr3<720575940379279360 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>648518346341351423 AND nbr4<720575940379279360 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>648518346341351423 AND nbr4<720575940379279360 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>648518346341351423 AND nbr4<720575940379279360 AND nbr3>504403158265495551 AND nbr3<576460752303423488))) OR(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>648518346341351423 AND nbr<720575940379279360) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>648518346341351423 AND nbr<720575940379279360) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>648518346341351423 AND nbr2<720575940379279360) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>648518346341351423 AND nbr<720575940379279360) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>648518346341351423 AND nbr2<720575940379279360) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>648518346341351423 AND nbr3<720575940379279360)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>31683527065993215 AND predictivesearch0.nbr<31701119252037632) AND NOT(predictivesearch0.nbr2>31683527065993215 AND predictivesearch0.nbr2<31701119252037632) AND NOT(predictivesearch0.nbr3>31683527065993215 AND predictivesearch0.nbr3<31701119252037632) AND NOT(predictivesearch0.nbr4>31683527065993215 AND predictivesearch0.nbr4<31701119252037632)))) OR(NOT(NOT(nbr2>648518346341351423 AND nbr2<720575940379279360 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>648518346341351423 AND nbr3<720575940379279360 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>648518346341351423 AND nbr3<720575940379279360 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>648518346341351423 AND nbr4<720575940379279360 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr4>648518346341351423 AND nbr4<720575940379279360 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>648518346341351423 AND nbr4<720575940379279360 AND nbr3>31525197391593471 AND nbr3<36028797018963968))) OR(NOT(NOT(nbr2>31525197391593471 AND nbr2<36028797018963968 AND nbr>648518346341351423 AND nbr<720575940379279360) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr>648518346341351423 AND nbr<720575940379279360) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr2>648518346341351423 AND nbr2<720575940379279360) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr>648518346341351423 AND nbr<720575940379279360) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr2>648518346341351423 AND nbr2<720575940379279360) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr3>648518346341351423 AND nbr3<720575940379279360)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
+    tokens.clear();
+    pattern = QString ("00052200007");
+    tokens << "000522" << "7";
+    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE ((NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>369858119397801983 AND nbr3<370139594374512640))) OR(NOT(NOT(nbr2>369858119397801983 AND nbr2<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE ((NOT(NOT(predictivesearch0.nbr>90297392889855 AND predictivesearch0.nbr<90297392955392) AND NOT(predictivesearch0.nbr2>90297392889855 AND predictivesearch0.nbr2<90297392955392) AND NOT(predictivesearch0.nbr3>90297392889855 AND predictivesearch0.nbr3<90297392955392) AND NOT(predictivesearch0.nbr4>90297392889855 AND predictivesearch0.nbr4<90297392955392)))) OR(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>90297392431103 AND nbr<90366111907840) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>90297392431103 AND nbr<90366111907840) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>90297392431103 AND nbr2<90366111907840) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>90297392431103 AND nbr<90366111907840) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>90297392431103 AND nbr2<90366111907840) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>90297392431103 AND nbr3<90366111907840))) OR(NOT(NOT(nbr2>90297392431103 AND nbr2<90366111907840 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>90297392431103 AND nbr3<90366111907840 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>90297392431103 AND nbr3<90366111907840 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>90297392431103 AND nbr4<90366111907840 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>90297392431103 AND nbr4<90366111907840 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>90297392431103 AND nbr4<90366111907840 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
+    result = mCntSqlSearch->CompareTwoColumnsWithModifiedPattern(pattern, tokens);
+    QVERIFY( !result.compare( reference) );
+    
     TEST_PASSED_LOG("testCompareTwoColumnsWithModifiedPattern");
     }
 void UT_CntSqlSearch::testModifiedMatchColumns()
@@ -1304,6 +1371,10 @@
     tokens = mCntSqlSearch->GetTokens("000019700");
     QVERIFY(tokens.count() == 1);
     QVERIFY(tokens.at(0) == "197");
+    
+    tokens = mCntSqlSearch->GetTokens("200");
+    QVERIFY(tokens.count() == 1);
+    QVERIFY(tokens.at(0) == "2");
 
     tokens = mCntSqlSearch->GetTokens("101");
     QVERIFY(tokens.count() == 2);
@@ -1373,12 +1444,12 @@
     QCOMPARE( result, reference );
 
     pattern = QString("200");
-    reference = false;
+    reference = true;
     result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
     QCOMPARE( result, reference );
 
     pattern = QString("2000");
-    reference = false;
+    reference = true;
     result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
     QCOMPARE( result, reference );
 
@@ -1444,7 +1515,12 @@
     QCOMPARE( result, reference );
     
     pattern = QString("00232");
-    reference = false;
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("052207");
+    reference = true;
     result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
     QCOMPARE( result, reference );
     
--- a/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.h	Mon Oct 04 01:37:06 2010 +0300
@@ -1,43 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Retrieves the character map for each of the numeric keys.
+*/
 
 #ifndef UT_CNTSQLSEARCH_H
 #define UT_CNTSQLSEARCH_H
@@ -45,6 +20,8 @@
 #include <QObject>
 
 class CntSqlSearch;
+class C12keyKeyMap;
+class CQwertyKeyMap;
 
 class UT_CntSqlSearch : public QObject                 
 {
@@ -69,6 +46,7 @@
 
 private slots: //test methods
 
+    void testCompareTwoColumnsWithModifiedPattern();
     void testPredictiveSearch();
     void testSelectQweryTable();
     void testSelectTableView();
@@ -78,7 +56,7 @@
     void testExactMatchSearchQwerty();
     void testIntersectionSearch();
     void testSearchTokensFromOneTable();
-    void testCompareTwoColumnsWithModifiedPattern();   
+    //void testCompareTwoColumnsWithModifiedPattern();   
     void testModifiedMatchColumns();
     void testExactMatch();
     void testExactMatchQwerty();
@@ -95,7 +73,9 @@
     
 private:
  
-    CntSqlSearch* mCntSqlSearch;  
+    C12keyKeyMap* m12KeyKeyMap;
+    CQwertyKeyMap* mQwertyKeyMap;
+    CntSqlSearch* mCntSqlSearch; 
 };
 
 #endif // UT_CNTSQLSEARCH_H
Binary file plugins/contacts/symbian/contactsmodel/tsrc/cntviewstore/10003a73.txt has changed
--- a/plugins/contacts/symbian/contactsmodel/tsrc/integration/tcntpolice/group/te_cntsrv_api_policing.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/integration/tcntpolice/group/te_cntsrv_api_policing.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -127,7 +127,7 @@
 USERINCLUDE   ../inc
 USERINCLUDE   ../../../../cntsrv/inc\
 
-SYSTEMINCLUDE /epoc32/include /epoc32/include/test
+APP_LAYER_SYSTEMINCLUDE
 LIBRARY       euser.lib 
 
 //For TEF 
--- a/plugins/contacts/symbian/contactsmodel/tsrc/integration/tcntpolice/template/te_cntsrv_api_policing.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/integration/tcntpolice/template/te_cntsrv_api_policing.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -23,7 +23,7 @@
 PARAM_FOREACH_MESS_END
 USERINCLUDE   PARAM_SVR_USERINCLUDE
 
-SYSTEMINCLUDE PARAM_SVR_SYSTEMINCLUDE /epoc32/include/test
+APP_LAYER_SYSTEMINCLUDE PARAM_SVR_SYSTEMINCLUDE
 LIBRARY       PARAM_SVR_LIBRARIES
 
 //For TEF 
Binary file plugins/contacts/symbian/contactsmodel/tsrc/t_apac_initial_contacts.txt has changed
--- a/plugins/contacts/symbian/contactsmodel/tsrc/t_mults.mmp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/contactsmodel/tsrc/t_mults.mmp	Mon Oct 04 01:37:06 2010 +0300
@@ -24,7 +24,9 @@
 
 SOURCEPATH	../TSRC
 
-systeminclude   ../INC  /EPOC32/INCLUDE
+APP_LAYER_SYSTEMINCLUDE
+
+userinclude   ../INC
 
 source          T_MULTS.CPP
 source 		t_utils2.cpp
Binary file plugins/contacts/symbian/contactsmodel/tsrc/t_view2_initial_contacts.txt has changed
Binary file plugins/contacts/symbian/contactsmodel/tsrc/t_view2_initial_contacts_small.txt has changed
Binary file plugins/contacts/symbian/contactsmodel/tsrc/t_view2_more_contacts_1.txt has changed
Binary file plugins/contacts/symbian/contactsmodel/tsrc/t_view2_more_contacts_2.txt has changed
Binary file plugins/contacts/symbian/contactsmodel/tsrc/testsyncplugin/1020384e.txt has changed
--- a/plugins/contacts/symbian/plugin/inc/cntabstractrelationship.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/inc/cntabstractrelationship.h	Mon Oct 04 01:37:06 2010 +0300
@@ -59,6 +59,10 @@
     virtual QList<QContactRelationship> relationshipsL(const QContactId &participantId, QContactRelationship::Role role, QContactManager::Error *error) = 0;
     virtual bool saveRelationshipL(QSet<QContactLocalId> *affectedContactIds, QContactRelationship *relationship, QContactManager::Error *error) = 0;
     virtual bool removeRelationshipL(QSet<QContactLocalId> *affectedContactIds, const QContactRelationship &relationship, QContactManager::Error *error) = 0;
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    virtual bool saveRelationshipsL(QSet<QContactLocalId> *affectedContactIds, QList<QContactRelationship> *relationships, QContactManager::Error *error) = 0;
+    virtual bool removeRelationshipsL(QSet<QContactLocalId> *affectedContactIds, const QList<QContactRelationship> &relationships, QContactManager::Error *error) = 0;
+#endif
     virtual bool validateRelationship(const QContactRelationship &relationship, QContactManager::Error *error) = 0;
     QString relationshipType() const;
 
--- a/plugins/contacts/symbian/plugin/inc/cntdisplaylabel.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/inc/cntdisplaylabel.h	Mon Oct 04 01:37:06 2010 +0300
@@ -102,9 +102,6 @@
     int                         iValue;
 };
 
-#else
-// No problem on earlier platforms
-#include <cntuids.h>
 #endif
 
 class CntDisplayLabel : public QObject
@@ -137,8 +134,8 @@
     QList<QList<QPair<QLatin1String, QLatin1String> > > m_groupDisplayLabelDetails;
 #ifdef SYMBIAN_BACKEND_USE_SQLITE
     CntCenrep* m_settings;
+    int m_nameOrder;
 #endif
-    int m_nameOrder;
 };
 
 #endif /* CNTDISPLAYLABEL_H_ */
--- a/plugins/contacts/symbian/plugin/inc/cntrelationship.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/inc/cntrelationship.h	Mon Oct 04 01:37:06 2010 +0300
@@ -64,7 +64,9 @@
     bool removeRelationship(QSet<QContactLocalId> *affectedContactIds, const QContactRelationship &relationship, QContactManager::Error *error);
     bool removeRelationships(QSet<QContactLocalId> *affectedContactIds, const QList<QContactRelationship> &relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error *error);
     bool validateRelationship(const QContactRelationship &relationship, QContactManager::Error *error);
-    
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    bool validateRelationships(const QList<QContactRelationship> &relationship, QString &relationshipType, QContactManager::Error *error);
+#endif
 private:
     CContactDatabase *m_contactDatabase;
     QString m_managerUri;
--- a/plugins/contacts/symbian/plugin/inc/cntrelationshipgroup.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/inc/cntrelationshipgroup.h	Mon Oct 04 01:37:06 2010 +0300
@@ -55,6 +55,10 @@
     QList<QContactRelationship> relationshipsL(const QContactId &participantId, QContactRelationship::Role role, QContactManager::Error *error);
     bool saveRelationshipL(QSet<QContactLocalId> *affectedContactIds, QContactRelationship *relationship, QContactManager::Error *error);
     bool removeRelationshipL(QSet<QContactLocalId> *affectedContactIds, const QContactRelationship &relationship, QContactManager::Error *error);
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    bool saveRelationshipsL(QSet<QContactLocalId> *affectedContactIds, QList<QContactRelationship> *relationships, QContactManager::Error *error);
+    bool removeRelationshipsL(QSet<QContactLocalId> *affectedContactIds, const QList<QContactRelationship> &relationships, QContactManager::Error *error);
+#endif
     bool validateRelationship(const QContactRelationship &relationship, QContactManager::Error *error);
     
 private:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/contacts/symbian/plugin/inc/contactbackendsdefs.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONTACTBACKENDSDEFS_H
+#define CONTACTBACKENDSDEFS_H
+
+/*!
+ * The definitions below are to be used as argument when constructiong a QContactManager.
+ */
+
+/*!
+ * Default backend in Symbian devices.
+ */
+const QString SYMBIAN_BACKEND     = "qtcontacts:symbian:";
+
+/*!
+ * SIM backend. (ADN contacts)
+ */
+const QString SIM_BACKEND         = "qtcontacts:symbiansim:";
+
+/*!
+ * SIM backend for ADN contacts.
+ */
+const QString SIM_BACKEND_ADN     = "qtcontacts:symbiansim:store=ADN";
+
+/*!
+ * SIM backend for SDN contacts.
+ */
+const QString SIM_BACKEND_SDN     = "qtcontacts:symbiansim:store=SDN";
+
+/*!
+ * SIM backend for FDN contacts.
+ */
+const QString SIM_BACKEND_FDN     = "qtcontacts:symbiansim:store=FDN";
+
+/*!
+ * SIM backend for Own Number contacts.
+ *
+ */
+const QString SIM_BACKEND_ON     = "qtcontacts:symbiansim:store=ON";
+
+
+
+#endif
--- a/plugins/contacts/symbian/plugin/inc/filtering/cntsqlsearch.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-//#ifdef SYMBIAN_BACKEND_USE_SQLITE
-
-#include <QObject>
-#include <QString>
-
-// If this macro is defined, searches like "102" are made on one table only
-#define SEARCH_FROM_ONE_TABLE
-
-// If defined, De Morgan's laws are used to replace ORs with ANDs in the
-// SELECT statement.
-#define USE_DEMORGAN
-
-
-class CntSqlSearch : public QObject
-{
-    Q_OBJECT
-
-public:
-    CntSqlSearch();
-
-    QString CreatePredictiveSearch(const QString &pattern);
-    
-
-private:
-    
-    QString SelectTable(const QString &pattern) const;
-    
-    QStringList GetTokens(const QString& pattern) const;
-    
-    QString CreateQuery(const QString& pattern) const;
-    
-    QString ExactMatchSearch(const QString& pattern) const;
-    
-    QString CreateSpaceStringSearch(QStringList numbers, const QString &pattern) const;
-
-    QString IntersectionSearch(const QString& pattern,
-                               const QStringList& numbers) const;
-    QString SearchTokensFromOneTable(const QString& pattern,
-								     const QStringList& tokens) const;
-
-    QString IdenticalTokensSearch(const QString& pattern,
-								  const QStringList& tokens) const;
-
-    QString CompareTwoColumns(const QString& lower,
-						 	  const QString& upper,
-							  const QString& lower2,
-							  const QString& upper2) const;
-
-    QString ExactMatch(const QString& pattern, QString table = "") const;
-
-    QString CreateJoinTableSearch(QString pattern, QStringList numbers) const;
-
-    QString ExactMatchColumns(QStringList numbers) const;
-
-    QString Order(QStringList numbers) const;
-
-    QString UpperLimit( const QString &pattern ) const;
-    
-    QString LowerLimit( const QString &pattern ) const;
-    
-    QString Pad( const QString &pattern, char padChar ) const;
-    
-    friend class UT_CntSqlSearch;
-};
-//#endif
--- a/plugins/contacts/symbian/plugin/inc/filtering/cntsymbiansrvconnection.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/inc/filtering/cntsymbiansrvconnection.h	Mon Oct 04 01:37:06 2010 +0300
@@ -59,6 +59,13 @@
 class CntSymbianSrvConnection : public RSessionBase
 {
 public:
+
+    enum QueryType {
+            CntNotdefined = 0,
+            CntPredictiveSearchList = 98,
+            CntSearchResultList = 99
+        };
+public:
     /*Constructor and destructor*/
     CntSymbianSrvConnection(QContactManagerEngine* engine);
     ~CntSymbianSrvConnection();
@@ -69,13 +76,19 @@
                                           QContactManager::Error* error);
     QContact searchContactName(QContactLocalId contactId,
                                QContactManager::Error* error);
+    QList<QContactLocalId> searchOnServer(const QString& searchQuery,
+                            QueryType aQueryType,
+                            QContactManager::Error* error);
     QList<QContact> searchAllContactNames(QContactManager::Error* error);
+    QList<QPair<QContactLocalId, QString> > searchPhoneNumbers(const QString& searchQuery, 
+                                                  QContactManager::Error* error);
 
 private:
     /* Symbian Leaving functions */
-    QList<QContactLocalId> searchContactIdsL(const TDesC& aSqlQuery);
+    QList<QContactLocalId> searchContactIdsL(const TDesC& aSqlQuery, QueryType aQueryType);
     QList<QContact> searchContactNamesL(const TDesC& aSqlQuery);
-    void readContactsToBufferL(const TDesC& aSqlQuery);
+    QList<QPair<QContactLocalId, QString> > searchPhoneNumbersL(const TDesC& aSqlQuery, QueryType aQueryType);
+    void readContactsToBufferL(const TDesC& aSqlQuery, QueryType aQueryType);
     void ConnectSrvL();
     void OpenDatabaseL();
     TVersion Version() const;
--- a/plugins/contacts/symbian/plugin/plugin.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/plugin.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -68,8 +68,7 @@
         inc/filtering/cntsymbianfiltersql.h \
         inc/filtering/cntsymbiansorterdbms.h \
         inc/filtering/cntsymbiansrvconnection.h \
-        inc/filtering/cntdisplaylabelsqlfilter.h \
-        inc/filtering/cntsqlsearch.h
+        inc/filtering/cntdisplaylabelsqlfilter.h
         
     SOURCES += \
         src/transform/cnttransformcontact.cpp \
@@ -109,7 +108,6 @@
         src/filtering/cntsymbiansorterdbms.cpp \
         src/filtering/cntsymbiansrvconnection.cpp \
         src/filtering/cntdisplaylabelsqlfilter.cpp \
-        src/filtering/cntsqlsearch.cpp \
         src/cntsymbianengine.cpp \
         src/cntabstractrelationship.cpp \
         src/cntrelationshipgroup.cpp \
@@ -147,4 +145,9 @@
     symbianplugin.sources = $${TARGET}.dll
     symbianplugin.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE}
     DEPLOYMENT += symbianplugin
+    
+    # Public header
+    headers.path = epoc32/include
+    headers.sources = inc/contactbackendsdefs.h
+    for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
 }
--- a/plugins/contacts/symbian/plugin/src/cntdisplaylabel.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/cntdisplaylabel.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -46,8 +46,7 @@
  * Constructor
  */
 
-CntDisplayLabel::CntDisplayLabel() :
-m_nameOrder(CntOrderFirstLast)
+CntDisplayLabel::CntDisplayLabel()
 {
 #ifdef SYMBIAN_BACKEND_USE_SQLITE
     m_settings = new CntCenrep(KCntNameOrdering, *this);
@@ -97,11 +96,6 @@
     contactPrefferedDisplayLabelDetails.append(qMakePair(QLatin1String(QContactName::DefinitionName), firstLatin));
     contactPrefferedDisplayLabelDetails.append(qMakePair(QLatin1String(QContactName::DefinitionName), secondLatin));
     m_contactDisplayLabelDetails.append(contactPrefferedDisplayLabelDetails);
-
-    //if preferred details doesn't exist use these
-    QList<QPair<QLatin1String, QLatin1String> > contactSecondaryDisplayLabelDetails;
-    contactSecondaryDisplayLabelDetails.append(qMakePair(QLatin1String(QContactOrganization::DefinitionName), QLatin1String(QContactOrganization::FieldName)));
-    m_contactDisplayLabelDetails.append(contactSecondaryDisplayLabelDetails);
     
     //Group
     QList<QPair<QLatin1String, QLatin1String> > preferredGroupDisplayLabelDetails;
@@ -175,9 +169,11 @@
                 
                 if(!label.isEmpty())
                 {
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
                     // Inlcude a comma if needed in the display label
                     if (m_nameOrder == CntOrderLastCommaFirst)
                         displayLabel.append(comma());
+#endif
                     displayLabel.append(delimiter());                        
                     displayLabel.append(label);
                 }  
--- a/plugins/contacts/symbian/plugin/src/cntrelationship.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/cntrelationship.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -211,24 +211,43 @@
 {
     QContactManager::Error singleError;    
     bool returnValue(true);
+    bool hasManyRelationshipTypes(false);
 
     *error = QContactManager::NoError;
 
-    // loop through the relationships
-    for (int i = 0; i < relationships->count(); i++)
-    {
-        // save the relationship
-        saveRelationship(affectedContactIds, &(relationships->operator[](i)), &singleError);
-        if (errorMap && singleError != QContactManager::NoError) {
-            errorMap->insert(i, singleError);
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    TInt symbianError = KErrNone;
+    QString relationshipType;
+
+    // validate relationships
+    returnValue = validateRelationships(*relationships, relationshipType, error);
+    hasManyRelationshipTypes = relationshipType.isEmpty();
+
+    // if all relationships are valid and of the same type, we can try to use the batch save, which is much faster
+    if (returnValue && !hasManyRelationshipTypes) {
+        if (!relationships->isEmpty()) {
+            CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationshipType);
+            TRAP(symbianError, returnValue = abstractRelationship->saveRelationshipsL(affectedContactIds, relationships, &singleError));
+            returnValue = returnValue && singleError == QContactManager::NoError && symbianError == KErrNone;
         }
-        
-        // update the total error
-        if (singleError != QContactManager::NoError) {
-            *error = singleError;
-            returnValue = false;
+    }
+#endif
+    // if validation or batch save failed, or if there are many different relationship types,
+    // the relationships need to be added one by one
+    if (!returnValue || hasManyRelationshipTypes) {
+        for (int i = 0; i < relationships->count(); ++i) {
+            // save the relationship
+            saveRelationship(affectedContactIds, &(relationships->operator[](i)), &singleError);
+            if (errorMap && singleError != QContactManager::NoError) {
+                errorMap->insert(i, singleError);
+            }
+            
+            // update the total error
+            if (singleError != QContactManager::NoError) {
+                *error = singleError;
+                returnValue = false;
+            } 
         }
-
     }
 
     return returnValue;
@@ -272,24 +291,47 @@
  */
 bool CntRelationship::removeRelationships(QSet<QContactLocalId> *affectedContactIds, const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
 {
+    QContactManager::Error singleError;    
     bool returnValue(true);
+    bool hasManyRelationshipTypes(false);
+
     *error = QContactManager::NoError;
-    QContactManager::Error qtError(QContactManager::NoError);
+
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    TInt symbianError = KErrNone;
+    QString relationshipType;
 
-    //loop through the relationships
-    for(int i = 0; i < relationships.count(); i++)
-    {
-        //remove the relationships
-        removeRelationship(affectedContactIds, relationships.at(i), &qtError);
-        if (errorMap && qtError != QContactManager::NoError)
-            errorMap->insert(i, qtError);
-        
-        // update the total error
-        if (qtError != QContactManager::NoError) {
-            returnValue = false;
-            *error = qtError;
+    // validate relationships
+    returnValue = validateRelationships(relationships, relationshipType, error);
+    hasManyRelationshipTypes = relationshipType.isEmpty();
+
+    // if all relationships are valid and of the same type, we can try to use the batch remove, which is much faster
+    if (returnValue && !hasManyRelationshipTypes) {
+        if (!relationships.isEmpty()) {
+            CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationshipType);
+            TRAP(symbianError, returnValue = abstractRelationship->removeRelationshipsL(affectedContactIds, relationships, &singleError));
+            returnValue = returnValue && singleError == QContactManager::NoError && symbianError == KErrNone;
         }
     }
+#endif
+    // if validation or batch remove failed, or if there are many relationship types,
+    // the relationships need to be removed one by one
+    if (!returnValue || hasManyRelationshipTypes) {
+        for (int i = 0; i < relationships.count(); ++i) {
+            //remove the relationships
+            removeRelationship(affectedContactIds, relationships.at(i), &singleError);
+            if (errorMap && singleError != QContactManager::NoError) {
+                errorMap->insert(i, singleError);
+            }
+                
+            // update the total error
+            if (singleError != QContactManager::NoError) {
+                returnValue = false;
+                *error = singleError;
+            }
+        }
+    }
+
     return returnValue;
 }
 
@@ -350,3 +392,45 @@
     CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationship.relationshipType());
     return abstractRelationship->validateRelationship(relationship, error);
 }
+
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+/*
+ *  Validates the relationships. If all valid relationships are of the same type,
+ *  the type will be passed back in relationshipType. Otherwise it will be empty.
+ */
+bool CntRelationship::validateRelationships(const QList<QContactRelationship> &relationships, QString &relationshipType, QContactManager::Error *error)
+{
+    QContactManager::Error validationError;
+    bool hasManyRelationshipTypes = false;
+    bool returnValue = true;
+
+    foreach (QContactRelationship relationship, relationships) {
+        if (validateRelationship(relationship, &validationError)) {
+            // Update manager uri to this manager if it is empty
+            if (relationship.second().managerUri().isEmpty()) {
+                QContactId second = relationship.second();
+                second.setManagerUri(m_managerUri);
+                relationship.setSecond(second);
+            }
+            
+            // get the relationship type
+            if (relationship.relationshipType() != relationshipType && !relationshipType.isEmpty()) {
+                hasManyRelationshipTypes = true;
+            }
+            else if (relationshipType.isEmpty()) {
+                relationshipType = relationship.relationshipType();
+            }
+        }
+        else {
+            *error = validationError;
+            returnValue = false;
+        }
+    }
+
+    if (hasManyRelationshipTypes) {
+        relationshipType.clear();
+    }
+
+    return returnValue;
+}
+#endif
--- a/plugins/contacts/symbian/plugin/src/cntrelationshipgroup.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/cntrelationshipgroup.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -114,6 +114,59 @@
     return true;
 }
 
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+/*!
+ * Save many relationships
+ * 
+ * \a affectedContactIds will include the affected contact ids 
+ * \a relationship to be saved
+ * \a error t
+ */
+bool CntRelationshipGroup::saveRelationshipsL(QSet<QContactLocalId> *affectedContactIds, QList<QContactRelationship> *relationships, QContactManager::Error* error)
+{
+    RArray<TContactItemId> idList;
+
+    if (relationships->count() == 0) {
+        return true;
+    }
+
+    QContactLocalId groupId = relationships->at(0).first().localId();
+    affectedContactIds->insert(groupId);
+    
+    foreach (QContactRelationship relationship, *relationships) {
+        affectedContactIds->insert(relationship.second().localId());
+        idList.AppendL(TContactItemId(relationship.second().localId()));
+    }
+
+    database()->AddContactsToGroupL(idList, TContactItemId(groupId));
+
+    *error = QContactManager::NoError;
+    return true;
+}
+
+bool CntRelationshipGroup::removeRelationshipsL(QSet<QContactLocalId> *affectedContactIds, const QList<QContactRelationship> &relationships, QContactManager::Error* error)
+{
+    RArray<TContactItemId> idList;
+
+    if (relationships.count() == 0) {
+        return true;
+    }
+
+    QContactLocalId groupId = relationships.at(0).first().localId();
+    affectedContactIds->insert(groupId);
+
+    foreach (QContactRelationship relationship, relationships) {
+        affectedContactIds->insert(relationship.second().localId());
+        idList.AppendL(TContactItemId(relationship.second().localId()));
+    }
+
+    database()->RemoveContactsFromGroupL(idList, TContactItemId(groupId));
+
+    *error = QContactManager::NoError;
+    return true;
+}
+#endif
+
 bool CntRelationshipGroup::validateRelationship(const QContactRelationship &relationship, QContactManager::Error* error)
 {
     // check that "second" is in this manager
--- a/plugins/contacts/symbian/plugin/src/cntsymbianengine.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/cntsymbianengine.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -79,7 +79,6 @@
 CntSymbianEngine::CntSymbianEngine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
     : m_dataBase(0),
       m_srvConnection(0),
-      m_managerUri(0),
       m_transformContact(0),
       m_contactFilter(0),
 #ifndef SYMBIAN_BACKEND_USE_SQLITE
@@ -649,6 +648,7 @@
 
 bool CntSymbianEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error> *errorMap, QContactManager::Error* error)
 {
+    QContactChangeSet changeSet;
     *error = QContactManager::NoError;
     
     if (errorMap) {
@@ -656,15 +656,39 @@
         errorMap->clear();
     }
     
-    if (contactIds.count() == 0) {
+    if (contactIds.count() == 0 || contactIds.contains(0)) {
         *error = QContactManager::BadArgumentError;
         return false;
     }
     
-    QContactManager::Error err;
-    QContactLocalId selfCntId = selfContactId(&err); // err ignored
+    QContactManager::Error selfContactError;
+    QContactLocalId selfCntId = selfContactId(&selfContactError); // selfContactError ignored
+
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    // try to batch remove all contacts
+    TRAPD(err,
+        CContactIdArray* idList = CContactIdArray::NewLC();
+        foreach (QContactLocalId contactId, contactIds) {
+            idList->AddL(TContactItemId(contactId));
+        }
+        m_dataBase->contactDatabase()->DeleteContactsL(*idList);
+        CleanupStack::PopAndDestroy(idList);
+    );
 
-    QContactChangeSet changeSet;
+    if (err == KErrNone) {
+        foreach (QContactLocalId contactId, contactIds) {
+            changeSet.insertRemovedContact(contactId);
+            m_dataBase->appendContactEmitted(contactId);
+        }
+        if (contactIds.contains(selfCntId)) {
+            QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
+            changeSet.setOldAndNewSelfContactId(ownCard);
+        }
+    }
+    else {
+        CntSymbianTransformError::transformError(err, error);
+    }
+#else
     for (int i = 0; i < contactIds.count(); i++) {
         QContactLocalId current = contactIds.at(i);
         QContactManager::Error functionError = QContactManager::NoError;
@@ -674,16 +698,11 @@
                 errorMap->insert(i, functionError);
             }
         }
-#ifdef SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
-        else {
-            if (current == selfCntId ) {
-                QOwnCardPair ownCard(selfCntId, QContactLocalId(0));
-                changeSet.setOldAndNewSelfContactId(ownCard);
-            }
-        }
+    }
 #endif
-    }
+
     changeSet.emitSignals(this);
+
     return (*error == QContactManager::NoError);
 }
 
--- a/plugins/contacts/symbian/plugin/src/filtering/cntdbinfo.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/filtering/cntdbinfo.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -207,9 +207,9 @@
             // ORDER BY CASE <concatenated string fields> WHEN "" THEN 1 ELSE 0 END, <concatenated string fields & other fields> <order>
             if (blanksLast) {
                 // If concatString is blank, do not evaluate ORDER BY. All unevaluated rows are pushed to the end
-                sortQuery += " ORDER BY CASE " + concatString + " WHEN \"\" THEN 1 ELSE 0 END, " + clause;
+                sortQuery += " ORDER BY CASE WHEN " + concatString + " = \"\" THEN 1 " + " WHEN " + concatString + " IS NULL THEN 1 ELSE 0 END, " + clause;
             } else {
-                sortQuery += " ORDER BY CASE " + concatString + " WHEN \"\" THEN 0 ELSE 1 END, " + clause;
+                sortQuery += " ORDER BY CASE WHEN " + concatString + " = \"\" THEN 0 " + " WHEN " + concatString + " IS NULL THEN 0 ELSE 1 END, " + clause;
             }
         }
     }
--- a/plugins/contacts/symbian/plugin/src/filtering/cntfilterdetail.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/filtering/cntfilterdetail.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -44,7 +44,6 @@
 
 #include "cntfilterdetail.h"
 #include "cntfilterdetaildisplaylabel.h" //todo rename class to follow naming pattern CntFilterDetailDisplayLabel
-#include "cntsqlsearch.h"
 #include "cntsymbianengine.h"
 #include "cnttransformphonenumber.h"
 
@@ -76,10 +75,10 @@
         bool &filterSupportedflag,
         QContactManager::Error* error)
 {
-    Q_UNUSED(filterSupportedflag);
     //Check if any invalid filter is passed 
     if (!filterSupported(filter) ) {
         *error =  QContactManager::NotSupportedError;
+        filterSupportedflag = false;
         return QList<QContactLocalId>();
     }
     QList<QContactLocalId> idList;
@@ -118,7 +117,16 @@
 {
     bool result = false;
     if (QContactFilter::ContactDetailFilter == filter.type()) {
-        result = true;
+        QContactDetailFilter detailFilter = static_cast<QContactFilter>(filter);
+        if (m_dbInfo.SupportsDetail(detailFilter.detailDefinitionName(),
+                detailFilter.detailFieldName())) {
+            result = true;
+        }
+        if (detailFilter.detailDefinitionName() == QContactPhoneNumber::DefinitionName &&
+            detailFilter.detailFieldName() == QContactPhoneNumber::FieldNumber) {
+            //cpecial case - phone number matching 
+            result = true;
+        }
     }
     return result;
 }
@@ -255,26 +263,26 @@
 QList<QContactLocalId>  CntFilterDetail::HandlePredictiveSearchFilter(const QContactFilter& filter,
                                                                       QContactManager::Error* error)
 {
-    QString sqlQuery;
-    
     if (filter.type() == QContactFilter::ContactDetailFilter) {
-       const QContactDetailFilter detailFilter(filter);
-       if (detailFilter.matchFlags() == QContactFilter::MatchKeypadCollation) {
-           CntSqlSearch sqlSearch;
-           //convert string to numeric format
+        const QContactDetailFilter detailFilter(filter);
+        if (detailFilter.matchFlags() == QContactFilter::MatchKeypadCollation) {
             QString pattern = detailFilter.value().toString();
-            sqlQuery = sqlSearch.CreatePredictiveSearch(pattern);
-            return  m_srvConnection.searchContacts(sqlQuery, error);  
-       }
-       else {
-           return QList<QContactLocalId>();
-       }
+            //if ( detailFilter.detailFieldName() == QContactEmailAddress::FieldEmailAddress ) {
+                return  m_srvConnection.searchOnServer(
+                        pattern, CntSymbianSrvConnection::CntPredictiveSearchList, error);
+            /*} else {
+                QString sqlQuery;
+                CntSqlSearch sqlSearch;
+                //convert string to numeric format
+                sqlQuery = sqlSearch.CreatePredictiveSearch(pattern);
+                return  m_srvConnection.searchContacts(sqlQuery, error);
+            }*/
+        }
     }
-    else {
-        return QList<QContactLocalId>();
-    }
+    return QList<QContactLocalId>();
 }
 
+
 /*
  * Creates an sql query to fetch contact item IDs for all the contact items
  * which may contain the specified telephone number in a telephone, fax
@@ -339,11 +347,55 @@
         }
         else {
             // Checking the upper digits...
-            TMatch phoneNumber = createPhoneMatchNumber(
-                                  numberPtr, numLowerDigits, numUpperDigits, error);
-            QString fieldToMatch = QString(" LIKE '%1").arg(phoneNumber.iUpperDigits) + "%'"  ;
-            whereClause += " AND extra_value" + fieldToMatch;
-            sqlQuery = "SELECT contact_id FROM comm_addr" + whereClause;
+        
+            // select fields for contacts that match phone lookup
+            //  SELECT contact_id, extra_value FROM comm_addr
+            //      WHERE value = [value string] AND type = [type value];
+            //
+            QString type =  QString(" type = %1").arg(CntDbInfo::EPhoneNumber);
+            QString value =  QString(" value = %1").arg(phoneDigits.iLowerSevenDigits);
+            QString whereClause = " WHERE" + value + " AND" + type;
+            sqlQuery = "SELECT contact_id, extra_value FROM comm_addr" + whereClause;
+            
+            QList<QPair<QContactLocalId, QString> > contactMatches =  m_srvConnection.searchPhoneNumbers(sqlQuery, error);
+            
+            // Check if search query was successful
+            if (*error != QContactManager::NoError) {
+                  return;
+                }
+            
+            QStringList list;
+            for (int i=0; i<contactMatches.count(); ++i) {
+                // Check the upper digits...
+                TInt32 storedUpperDigits(0);
+                QString extraValue = contactMatches.at(i).second;
+                TPtrC extValString(reinterpret_cast<const TUint16*>(extraValue.utf16()));
+                if (TLex(extValString).Val(storedUpperDigits) == KErrNone) {
+                
+                    const TInt KDigitsToRemove = KMaxPhoneMatchLength - KLowerSevenDigits - phoneDigits.iNumUpperDigits;
+                    for (TInt j = 0; j < KDigitsToRemove; ++j) {
+                        // repeatedly divide by 10 to lop off the appropriate number of digits from the right
+                        storedUpperDigits /= 10;
+                    }
+                
+                    storedUpperDigits = TMatch::padOutPhoneMatchNumber(storedUpperDigits, KDigitsToRemove);
+                
+                    if (phoneDigits.iUpperDigits == storedUpperDigits) {
+                        list.append(QString("%1").arg(contactMatches.at(i).first));
+                    }
+                }
+                else {
+                    *error = QContactManager::UnspecifiedError;
+                }
+            }
+            // Recreate query to fetch all match ids
+            // SELECT DISTINCT contact_id FROM contact WHERE contact_id in (
+            //      ..
+            // )  
+            QString ids = list.join(" ,");
+            sqlQuery = "SELECT DISTINCT contact_id FROM contact WHERE contact_id in (";
+            sqlQuery += ids;
+            sqlQuery += ')';
         }
       
         // refine search
@@ -439,7 +491,7 @@
     TMatch phoneNumber = createPhoneMatchNumber(
                                             number, numLowerDigits, numUpperDigits, error);
     if (*error == QContactManager::NoError) {
-        if (phoneNumber.iNumLowerDigits + phoneNumber.iUpperDigits == 0) {
+        if (phoneNumber.iNumLowerDigits + phoneNumber.iNumUpperDigits == 0) {
             // No digits, do nothing
         }
         else if (phoneNumber.iNumLowerDigits < KLowerSevenDigits) {
--- a/plugins/contacts/symbian/plugin/src/filtering/cntsqlsearch.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,613 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QStringList>
-
-#include "cntsqlsearch.h"
-
-const char KLimitLength = 15;
-const int KTwoTokens = 2;
-const char KLowerLimitPadding = '0';
-const char KUpperLimitPadding = 'F';
-const int KMinimumSearchPatternLength = 1;
-
-
-#define ORDER_BY_FIRSTNAME_LASTNAME " ORDER BY first_name, last_name ASC;"
-#define SELECT_CONTACT_ID			"SELECT contact_id FROM "
-
-// TODO: Since the column names are repeated several times, replace them with
-// shorter names like w, x, y & z. Also replace contact_id by id etc.
-
-// Predictive search table's columns
-const QString KColumn1 = "nbr";
-const QString KColumn2 = "nbr2";
-const QString KColumn3 = "nbr3";
-const QString KColumn4 = "nbr4";
-
-
-CntSqlSearch::CntSqlSearch()
-	{
-	}
-
-// Basic cases:
-// 1: "0", "5"
-// Just one digit. Select all contact ids from the table. No need to compare
-// values.
-//
-// 2: "123", "01", "10", "010", "00"
-// No zeros which have non-zeros in their both sides
-// One or zero tokens, when pattern is split using '0'.
-//
-// 3: "101", "1001"
-// Same digit of both sides of the zero
-// Two tokens, each with length of 1 and tokens are the same.
-// The queries of case 3 could also be handled with case 4 query, but that
-// would yield a longer SQL statement.
-//
-// 4: "102", "1002"
-// One or more zeros in the middle, just one digit on either side of the zero(s)
-// and those digits are not the same.
-// Two tokens, each with length of 1 and tokens are different.
-//
-// 5: "1023", "0102", "1010", "00100200", "10203", "01020304050"
-// Two tokens, at least one of them has length > 1.
-// If tokens are identical, handle as case 3, otherwise handle as case 4.
-// ("10203" -> tokens "1" and "203"
-//  "0010023004560" -> tokens "001" and "23004560")
-QString CntSqlSearch::CreatePredictiveSearch(const QString &pattern)
-	{
-	int len = pattern.length();
-	// For best performance, handle 1 digit case first
-	if (len == KMinimumSearchPatternLength)
-        {
-		// Case 1
-        return SELECT_CONTACT_ID + SelectTable(pattern) + ORDER_BY_FIRSTNAME_LASTNAME;
-        }
-    if (len <= KLimitLength && len > KMinimumSearchPatternLength)
-        {
-		return CreateQuery(pattern);
-		}
-
-	return QString(""); // Invalid pattern
-	}
-
-QString CntSqlSearch::SelectTable(const QString &pattern) const
-	{
-    QString predictivesearch;
-	if (pattern.length() == 0)
-		{
-		return "";
-		}
-    switch (pattern.at(0).digitValue())
-        {
-        case 0:
-            {
-            predictivesearch = QString("predictivesearch0");
-            }
-        break;
-        case 1:
-            {
-            predictivesearch = QString("predictivesearch1");
-            }
-        break;
-        case 2:
-            {
-            predictivesearch = QString("predictivesearch2");
-            }
-        break;
-        case 3:
-            {
-            predictivesearch = QString("predictivesearch3");
-            }
-        break;
-        case 4:
-            {
-            predictivesearch = QString("predictivesearch4");
-            }
-        break;
-        case 5:
-            {
-            predictivesearch = QString("predictivesearch5");
-            }
-        break;
-        case 6:
-            {
-            predictivesearch = QString("predictivesearch6");
-            }
-        break;
-        case 7:
-            {
-            predictivesearch = QString("predictivesearch7");
-            }
-        break;
-        case 8:
-            {
-            predictivesearch = QString("predictivesearch8");
-            }
-        break;
-        case 9:
-            {
-            predictivesearch = QString("predictivesearch9");
-            }
-        break;
-		default: // error
-			predictivesearch = "";
-			break;
-        }
-	return predictivesearch;
-	}
-
-// Even if there are over 2 tokens, make 2 tokens.
-// If there are two or more tokens, include the leading zeros in the first
-// token the and trailing zeros in the second token.
-// E.g. "0010230" results tokens "001" and "230" and
-// "001230045067800900" tokens "00123" and "45067800900".
-QStringList CntSqlSearch::GetTokens(const QString& pattern) const
-	{
-    const QChar KZero('0');
-    QStringList tokens = pattern.split(KZero, QString::SkipEmptyParts);
-    if (tokens.count() < KTwoTokens)
-        {
-        return tokens;
-        }
-
-    QStringList twoTokens;
-    int i(0);
-    while (pattern[i] == KZero) // Skip leading zeros
-        {
-        ++i;
-        }
-    while (pattern[i] != KZero) // Skip non-zeros to find where first token ends
-        {
-        ++i;
-        }
-    twoTokens.append(pattern.left(i));
-    
-    while (pattern[i] == KZero) // Skip zeros to find where second token begins
-        {
-        ++i;
-        }
-    twoTokens.append(pattern.mid(i));
-    return twoTokens;
-	}
-
-// pattern length is between KMinimumSearchPatternLength...KLimitLength
-QString CntSqlSearch::CreateQuery(const QString& pattern) const
-	{
-	QStringList tokens = GetTokens(pattern);
-	if (tokens.count() < KTwoTokens)
-		{
-		return ExactMatchSearch(pattern) + Order(tokens);; // Case 2
-		}
-	else
-	    {
-		if (tokens.at(0) == tokens.at(1))
-            {
-            return IdenticalTokensSearch(pattern, tokens); // Case 3
-            }
-        else
-            {
-            return IntersectionSearch(pattern, tokens); // Case 4
-            }
-        }
-	}
-
-QString CntSqlSearch::ExactMatchSearch(const QString& pattern) const
-	{
-	return QString(SELECT_CONTACT_ID + SelectTable(pattern) +
-		           " WHERE " + ExactMatch(pattern)); 
-	}
-
-// It has been checked that tokens are different, but they might begin with
-// the same digit.
-QString CntSqlSearch::IntersectionSearch(const QString& pattern,
-									     const QStringList& tokens) const
-	{
-#if defined(SEARCH_FROM_ONE_TABLE)
-	return SearchTokensFromOneTable(pattern, tokens);
-#else
-/* Query for pattern = "205":
-SELECT predictivesearch2.contact_id FROM predictivesearch2 WHERE EXISTS
-(SELECT contact_id FROM predictivesearch5 WHERE predictivesearch2.contact_id = predictivesearch5.contact_id)
-OR
-(SELECT contact_id FROM predictivesearch2 
-WHERE(predictivesearch2.nbr>145522562959409152 AND predictivesearch2.nbr<145804037936119807) OR
-(predictivesearch2.nbr2>145522562959409152 AND predictivesearch2.nbr2<145804037936119807) OR
-(predictivesearch2.nbr3>145522562959409152 AND predictivesearch2.nbr3<145804037936119807) OR
-(predictivesearch2.nbr4>145522562959409152 AND predictivesearch2.nbr4<145804037936119807))
-ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;
-
-This query works if both tokens have just one digit (e.g. "102", but not "1023")
-*/	
-	if (tokens.at(0).length() == KMinimumSearchPatternLength &&
-		tokens.at(1).length() == KMinimumSearchPatternLength) 
-		{
-		// Case 4
-		QString firstTable = SelectTable(tokens.at(0));
-		QString secondTable = SelectTable(tokens.at(1));
-		QString query =
-			"SELECT " + firstTable + ".contact_id FROM " + firstTable +
-			" WHERE EXISTS (" + SELECT_CONTACT_ID + secondTable + " WHERE " +
-			firstTable + ".contact_id = " + secondTable + ".contact_id) OR (" +
-			SELECT_CONTACT_ID + firstTable + " WHERE " + ExactMatch(pattern, firstTable) + ")";
-		return query  + Order(tokens);
-		}
-	if (tokens.at(0).at(0) == tokens.at(1).at(0) ||
-	    tokens.at(0).length() > 1 && tokens.at(1).length() > 1)
-		{
-		// Tokens begin with same digit or both tokens are longer than one digit.
-		// Must search from one table.
-		return SearchTokensFromOneTable(pattern, tokens);
-		}
-	return CreateJoinTableSearch(pattern, tokens); // Case 5
-#endif
-	}
-
-// Find the exact match, or a column whose value is within
-// lower..upper(exclusive) and another column whose value is within
-// lower2..upper2(exclusive).
-// In this case the limits are is different, so there are 12 combinations the
-// two values can exist in four columns:
-// 
-// (column = X  AND column2 = Y) OR
-// (column = X  AND column3 = Y) OR
-// (column = X  AND column4 = Y) OR
-// (column2 = X AND column3 = Y) OR
-// (column2 = X AND column4 = Y) OR
-// (column3 = X AND column4 = Y) OR
-// (column = Y  AND column2 = X) OR
-// (column = Y  AND column3 = X) OR
-// (column = Y  AND column4 = X) OR
-// (column2 = Y AND column3 = X) OR
-// (column2 = Y AND column4 = X) OR
-// (column3 = Y AND column4 = X)
-//
-// Where X means: (value > lower-limit AND value < upper-limit)
-// and Y means: (value > lower-limit-2 AND value < upper-limit-2)
-QString CntSqlSearch::SearchTokensFromOneTable(const QString& pattern,
-											   const QStringList& tokens) const
-	{
-	QString token = tokens.at(0);
-    QString lower = LowerLimit(token);
-    QString upper = UpperLimit(token);
-    QString lower2 = LowerLimit(tokens.at(1));
-    QString upper2 = UpperLimit(tokens.at(1));
-
-    QString query =
-#if defined(USE_DEMORGAN)
-		SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE NOT(NOT" +
-	    ExactMatch(pattern) + " AND NOT" +
-		CompareTwoColumns(lower, upper, lower2, upper2) + " AND NOT" +
-        CompareTwoColumns(lower2, upper2, lower, upper) + ")";
-#else
-        SELECT_CONTACT_ID + SelectTable(token) + " WHERE (" +
-		// exact match (e.g. "102")
-        ExactMatch(pattern) + ") OR " +
-        CompareTwoColumns(lower, upper, lower2, upper2) + " OR " +
-        CompareTwoColumns(lower2, upper2, lower, upper);
-#endif
-	query += Order(tokens);
-	return query;
-	}
-
-// Either an exact match is required, or tokens must be found, but not in the
-// same column.
-// Since tokens are identical, they have same limits, and one call to
-// CompareTwoColumns() is enough.
-QString CntSqlSearch::IdenticalTokensSearch(const QString& pattern,
-										    const QStringList& tokens) const
-	{
-	QString token = tokens.at(0);
-	QString lower = LowerLimit(token);
-	QString upper = UpperLimit(token);
-#if defined(USE_DEMORGAN)
-	QString query(SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE NOT(NOT" +
-	    ExactMatch(pattern) +
-        " AND NOT" + CompareTwoColumns(lower, upper, lower, upper) + ")");
-#else
-	QString query(SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE (" +
-	    ExactMatch(pattern) +  // exact match (e.g. "101")
-        ") OR " + CompareTwoColumns(lower, upper, lower, upper));
-#endif
-	query += Order(tokens);
-	return query;
-	}
-
-// Put individual AND / OR operations in such order that in most cases there is
-// no need to evaluate all arguments of the AND / OR.
-// In case of AND, put the less likely condition on the left side of AND.
-// In case of OR, put the more likely condition on the left side of OR.
-// Since 2nd column is more likely to be empty, compare it before 1st column.
-// Since 1st & 2nd columns are more likely to contain a match, compare them
-// before other column combinations (1st & 3rd, 2nd & 3rd etc)
-QString CntSqlSearch::CompareTwoColumns(const QString& lower,
-										const QString& upper,
-										const QString& lower2,
-										const QString& upper2) const
-	{
-#if defined(USE_DEMORGAN)
-	// Using De Morgan's law to replace ORs with ANDs:
-	// A || B || C || D || E || F --> !(!A && !B && !C && !D && !E && !F)
-	//
-	// As A (match found in columns 1 and 2) is more likely true than other
-	// combinations, then !A is more likely false than other combinations, so
-	// it is put first in the AND statement.	
-	QString query =
-		"(NOT(NOT(" +
-		// 2nd & 1st column (='A')
-		KColumn2 + ">" + lower2 + " AND " + KColumn2 + "<" + upper2 + " AND " +
-		KColumn1 + ">" + lower + " AND " + KColumn1 + "<" + upper +
-		") AND NOT(" +
-		// 3nd & 1st column (='B')
-		KColumn3 + ">" + lower2 + " AND " + KColumn3 + "<" + upper2 + " AND " +
-		KColumn1 + ">" + lower + " AND " + KColumn1 + "<" + upper +
-		") AND NOT(" +
-		// 3rd & 2nd column (='C')
-		KColumn3 + ">" + lower2 + " AND " + KColumn3 + "<" + upper2 + " AND " +
-		KColumn2 + ">" + lower + " AND " + KColumn2 + "<" + upper +
-		") AND NOT(" +
-		// 4th & 1st column (='D')
-		KColumn4 + ">" + lower2 + " AND " + KColumn4 + "<" + upper2 + " AND " +
-		KColumn1 + ">" + lower + " AND " + KColumn1 + "<" + upper +
-		") AND NOT(" +
-		// 4th & 2nd column (='E')
-		KColumn4 + ">" + lower2 + " AND " + KColumn4 + "<" + upper2 + " AND " +
-		KColumn2 + ">" + lower + " AND " + KColumn2 + "<" + upper +
-		") AND NOT(" +
-		// 4th & 3rd column (='F')
-		KColumn4 + ">" + lower2 + " AND " + KColumn4 + "<" + upper2 + " AND " +
-		KColumn3 + ">" + lower + " AND " + KColumn3 + "<" + upper + ")))";
-#else
-	QString query =
-		"(" +
-		// 2nd & 1st column
-		KColumn2 + ">" + lower2 + " AND " + KColumn2 + "<" + upper2 + " AND " +
-		KColumn1 + ">" + lower + " AND " + KColumn1 + "<" + upper +
-		") OR (" +
-		// 3nd & 1st column
-		KColumn3 + ">" + lower2 + " AND " + KColumn3 + "<" + upper2 + " AND " +
-		KColumn1 + ">" + lower + " AND " + KColumn1 + "<" + upper +
-		") OR (" +
-		// 3rd & 2nd column
-		KColumn3 + ">" + lower2 + " AND " + KColumn3 + "<" + upper2 + " AND " +
-		KColumn2 + ">" + lower + " AND " + KColumn2 + "<" + upper +
-		") OR (" +
-		// 4th & 1st column
-		KColumn4 + ">" + lower2 + " AND " + KColumn4 + "<" + upper2 + " AND " +
-		KColumn1 + ">" + lower + " AND " + KColumn1 + "<" + upper +
-		") OR (" +
-		// 4th & 2nd column
-		KColumn4 + ">" + lower2 + " AND " + KColumn4 + "<" + upper2 + " AND " +
-		KColumn2 + ">" + lower + " AND " + KColumn2 + "<" + upper +
-		") OR (" +
-		// 4th & 3rd column
-		KColumn4 + ">" + lower2 + " AND " + KColumn4 + "<" + upper2 + " AND " +
-		KColumn3 + ">" + lower + " AND " + KColumn3 + "<" + upper + ")";
-#endif
-	return query;
-	}
-
-QString CntSqlSearch::ExactMatch(const QString& pattern, QString table) const
-    {
-    QString lower = LowerLimit(pattern);
-    QString upper = UpperLimit(pattern);
-    
-    if (table.length() > 0)
-        {
-        table += ".";
-        }
-#if defined(USE_DEMORGAN)
-	// Using De Morgan's law to replace ORs with ANDs:
-	// column1 || column2 || column3 || column4
-	// ->
-	// (NOT(NOT(column1) AND NOT(column2) AND NOT(column3) AND NOT(column4))
-	//
-	// Which means:
-	// (NOT(NOT(N>lower  && < N<upper)  AND NOT(N2>lower && < N2<upper) AND
-	//      NOT(N3>lower && < N3<upper) AND NOT(N>lower && < N<upper))
-	//
-	// As KColumn1 is most likely to contain a match, "NOT(KColumn1)" is more
-	// likely to be false than "NOT(KColumn2)" etc. So put KColumn1 first in the
-	// AND statement.
-	return QString("(NOT(NOT(" +
-        table + KColumn1 + ">" + lower + " AND " + table + KColumn1 + "<" + upper + ") AND NOT(" +
-        table + KColumn2 + ">" + lower + " AND " + table + KColumn2 + "<" + upper + ") AND NOT(" +
-        table + KColumn3 + ">" + lower + " AND " + table + KColumn3 + "<" + upper + ") AND NOT(" +
-        table + KColumn4 + ">" + lower + " AND " + table + KColumn4 + "<" + upper + ")))");
-#else
-	// Since first column has always some value, and 2nd column is more likely to
-	// have a value than 3rd column etc. Put columns in that order:
-	// (column 1 comparison) OR (column 2 comparison) OR (column 3 comparison) OR
-	// (column 4 comparison)
-	// If 1st column results true, there is no need to compare other columns etc.
-    return QString("(" +
-        table + KColumn1 + ">" + lower + " AND " + table + KColumn1 + "<" + upper + ") OR (" +
-        table + KColumn2 + ">" + lower + " AND " + table + KColumn2 + "<" + upper + ") OR (" +
-        table + KColumn3 + ">" + lower + " AND " + table + KColumn3 + "<" + upper + ") OR (" +
-        table + KColumn4 + ">" + lower + " AND " + table + KColumn4 + "<" + upper + ")");
-#endif
-    }
-
-
-// TODO: if SEARCH_FROM_ONE_TABLE case is slower than the one that searches from
-// two tables, then this function is needed for cases where pattern is:
-// "1023", "12300450"
-//
-/* This query makes sub-query into table 5 and searches for a number that begins
-with 56606. but it does not support cases where both tokens are longer than one digit.
-
-SELECT predictivesearch5.contact_id FROM predictivesearch5 WHERE EXISTS (SELECT contact_id FROM predictivesearch5 
-WHERE (predictivesearch5.nbr>389005014883893248 AND predictivesearch5.nbr<389006114395521023) OR
-(predictivesearch5.nbr2>389005014883893248 AND predictivesearch5.nbr2<389006114395521023) OR
-(predictivesearch5.nbr3>389005014883893248 AND predictivesearch5.nbr3<389006114395521023) OR
-(predictivesearch5.nbr4>389005014883893248 AND predictivesearch5.nbr4<389006114395521023))
-OR
-(SELECT predictivesearch5.contact_id FROM predictivesearch5 JOIN predictivesearch6 ON
-predictivesearch5.contact_id = predictivesearch6.contact_id
-WHERE(predictivesearch5.nbr>388998417814126592 AND predictivesearch5.nbr<389279892790837247) OR
-(predictivesearch5.nbr2>388998417814126592 AND predictivesearch5.nbr2<389279892790837247) OR
-(predictivesearch5.nbr3>388998417814126592 AND predictivesearch5.nbr3<389279892790837247) OR
-(predictivesearch5.nbr4>388998417814126592 AND predictivesearch5.nbr4<389279892790837247))
-ORDER BY predictivesearch5.first_name, predictivesearch5.last_name ASC;
-
-SELECT contact_id
-FROM
-(
-SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name  FROM predictivesearch5
-WHERE (predictivesearch5.nbr>387415121070129152 AND predictivesearch5.nbr<387432713256173567) OR
-(predictivesearch5.nbr2>387415121070129152 AND predictivesearch5.nbr2<387432713256173567) OR
-(predictivesearch5.nbr3>387415121070129152 AND predictivesearch5.nbr3<387432713256173567) OR
-(predictivesearch5.nbr4>387415121070129152 AND predictivesearch5.nbr4<387432713256173567)
-UNION
-SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name  FROM predictivesearch5 JOIN predictivesearch6 ON predictivesearch5.contact_id = predictivesearch6.contact_id
-WHERE((predictivesearch5.nbr>387309567953862656 AND predictivesearch5.nbr<391813167581233151) OR (predictivesearch5.nbr2>387309567953862656 AND predictivesearch5.nbr2<391813167581233151) OR (predictivesearch5.nbr3>387309567953862656 AND predictivesearch5.nbr3<391813167581233151) OR (predictivesearch5.nbr4>387309567953862656 AND predictivesearch5.nbr4<391813167581233151)
-AND
-(predictivesearch6.nbr>387309567953862656 AND predictivesearch6.nbr<391813167581233151) OR (predictivesearch6.nbr2>387309567953862656 AND predictivesearch6.nbr2<391813167581233151) OR (predictivesearch6.nbr3>387309567953862656 AND predictivesearch6.nbr3<391813167581233151) OR (predictivesearch6.nbr4>387309567953862656 AND predictivesearch6.nbr4<391813167581233151))
-) AS PR
-ORDER BY PR.first_name, PR.last_name ASC;
-
-Here is a De Morgan version
-
-SELECT contact_id
-FROM
-(
-SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name  FROM predictivesearch5
-WHERE NOT((NOT (predictivesearch5.nbr >= 387415121070129152 AND predictivesearch5.nbr <= 387432713256173567)) AND (NOT (predictivesearch5.nbr2 >= 387415121070129152 AND predictivesearch5.nbr2 <= 387432713256173567)) AND (NOT (predictivesearch5.nbr3 >= 387415121070129152 AND predictivesearch5.nbr3 <= 387432713256173567)) AND (NOT (predictivesearch5.nbr4 >= 387415121070129152 AND predictivesearch5.nbr4 <= 387432713256173567)))
-UNION
-SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name  FROM predictivesearch5 JOIN predictivesearch6 ON predictivesearch5.contact_id = predictivesearch6.contact_id
-WHERE NOT((NOT (predictivesearch5.nbr >= 387309567953862656 AND predictivesearch5.nbr <= 391813167581233151)) AND (NOT (predictivesearch5.nbr2 >= 387309567953862656 AND predictivesearch5.nbr2 <= 391813167581233151)) AND (NOT (predictivesearch5.nbr3 >= 387309567953862656 AND predictivesearch5.nbr3 <= 391813167581233151)) AND (NOT (predictivesearch5.nbr4 >= 387309567953862656 AND predictivesearch5.nbr4 <= 391813167581233151)))
-AND
-NOT((NOT (predictivesearch6.nbr >= 387309567953862656 AND predictivesearch6.nbr <= 391813167581233151)) AND (NOT (predictivesearch6.nbr2 >= 387309567953862656 AND predictivesearch6.nbr2 <= 391813167581233151)) AND (NOT (predictivesearch6.nbr3 >= 387309567953862656 AND predictivesearch6.nbr3 <= 391813167581233151)) AND (NOT (predictivesearch6.nbr4 >= 387309567953862656 AND predictivesearch6.nbr4 <= 391813167581233151)))
-) AS PR
-ORDER BY PR.first_name, PR.last_name ASC;
-
-*/
-QString CntSqlSearch::CreateJoinTableSearch(QString pattern, QStringList numbers) const
-	{
-	// It has been checked earlier that tables are not same
-	QString firstTable = SelectTable(numbers.at(0));
-	QString secondTable = SelectTable(numbers.at(1));
-
-    QString queryString = QString("SELECT contact_id FROM (SELECT "
-                                  + firstTable + ".contact_id, " + firstTable + ".first_name, " + firstTable + ".last_name FROM " + firstTable +
-                                    " WHERE " + ExactMatch(pattern, firstTable) +
-                                    " UNION SELECT " + firstTable + ".contact_id, " + firstTable + ".first_name, " + firstTable + ".last_name FROM " + firstTable + " JOIN " + secondTable + " ON " + firstTable + ".contact_id = " + secondTable +  ".contact_id WHERE" +
-                                ExactMatchColumns(numbers) + ") AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-	return queryString;
-	}
-
-QString CntSqlSearch::ExactMatchColumns(QStringList numbers) const
-        {
-
-        QString firstColumn = numbers.at(0);
-        QString secondColumn = numbers.at(1);
-
-        if( firstColumn.count() >  1 && secondColumn.count() > 1)
-            {
-            return "(" + ExactMatch(numbers.at(0), SelectTable(numbers.at(0))) + " AND " + ExactMatch(numbers.at(1), SelectTable(numbers.at(1))) + ")";
-            }
-        else if(firstColumn.count() > 1)
-            {
-            return ExactMatch(numbers.at(0), SelectTable(numbers.at(0)));
-            }
-        else
-            {
-            return ExactMatch(numbers.at(1), SelectTable(numbers.at(1)));
-            }
-        }
-
-QString CntSqlSearch::Order(QStringList tokens) const
-	{
-	if (tokens.count() > 1 )
-		{
-		QString table = SelectTable(tokens.at(0));
-		return QString(" ORDER BY " + table + ".first_name, " + table + ".last_name ASC;");
-		}
-	return QString(ORDER_BY_FIRSTNAME_LASTNAME);
-	}
-
-QString CntSqlSearch::Pad( const QString &pattern, char padChar ) const
-    {
-    int padCount = KLimitLength - pattern.length();    
-    QString result;
-    if ( padCount < 0 )
-        {
-        result = pattern.left(KLimitLength);
-        }
-    else
-        {
-        result = pattern;
-        for( int i = 0; i < padCount ;i++ )
-            {
-            result.append(padChar);
-            }
-        }
-    const int KHexadecimalBase = 16;
-    bool ok;
-    // Use signed int to prevent underflow when replaced is "00...00"
-    qint64 value = result.toLongLong(&ok, KHexadecimalBase); 
-    if (!ok)
-    	{
-    	// TODO: handle error (=invalid characters in pattern)
-    	}
-
-	// In order to write queries using '>' and '<' instead of '>=' and '<=',
-	// expand the limit by one.
-	if (padChar == KUpperLimitPadding)
-		{
-		++value;
-		}
-	else
-		{
-		--value;
-		}
-
-    return QString::number(value, 10);
-    }
-
-QString CntSqlSearch::UpperLimit( const QString &pattern ) const
-    {
-    return Pad( pattern, KUpperLimitPadding );
-    }
-
-QString CntSqlSearch::LowerLimit( const QString &pattern ) const
-    {
-    return Pad( pattern, KLowerLimitPadding );
-    }
--- a/plugins/contacts/symbian/plugin/src/filtering/cntsymbiansrvconnection.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/src/filtering/cntsymbiansrvconnection.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -51,7 +51,7 @@
 
 // Constants
 // To be removed. Should be defined in a header file
-#define KCntSearchResultList 99
+
 #define KCntOpenDataBase 100 // = KCapabilityReadUserData
 
 _LIT(KCntServerExe,"CNTSRV.EXE");   // Name of the exe for the Contacts server.
@@ -101,12 +101,49 @@
 {
     QList<QContactLocalId> list;
     TPtrC queryPtr(reinterpret_cast<const TUint16*>(sqlQuery.utf16()));
-    TRAPD(err, list = searchContactIdsL(queryPtr));
+    TRAPD(err, list = searchContactIdsL(queryPtr, CntSymbianSrvConnection::CntSearchResultList));
     CntSymbianTransformError::transformError(err, error);
     return list;
 }
 
 /*!
+ * Fetches list of matched contact ids with phonenumber fields
+ * SELECT contact_id, extra_value FROM comm_addr
+ * WHERE value = [value string] AND type = [type value];
+ * 
+ * \a sqlQuery An SQL query
+ * \a error On return, contains the possible error.
+ * \return the list of matched contact ids and values
+ */
+QList<QPair<QContactLocalId, QString> > CntSymbianSrvConnection::searchPhoneNumbers(const QString& sqlQuery, 
+                                              QContactManager::Error* error)
+{
+    QList<QPair<QContactLocalId, QString> > list;
+    TPtrC queryPtr(reinterpret_cast<const TUint16*>(sqlQuery.utf16()));
+    TRAPD(err, list = searchPhoneNumbersL(queryPtr, CntSymbianSrvConnection::CntSearchResultList));
+    CntSymbianTransformError::transformError(err, error);
+    return list;
+}
+
+/*!
+ * Query the SQL database
+ * 
+ * \a sqlQuery An SQL query
+ * a QueryType query type
+ * \a error On return, contains the possible error.
+ * \return the list of matched contact ids
+ */
+QList<QContactLocalId> CntSymbianSrvConnection::searchOnServer(const QString& sqlQuery,
+                                                                QueryType aQueryType,
+                                                                QContactManager::Error* error)
+{
+    QList<QContactLocalId> list;
+    TPtrC queryPtr(reinterpret_cast<const TUint16*>(sqlQuery.utf16()));
+    TRAPD(err, list = searchContactIdsL(queryPtr, aQueryType));
+        CntSymbianTransformError::transformError(err, error);
+    return list;
+}
+/*!
  * Fetches all contact names from the database. If there are more than 3000 contacts,
  * only the first (by id) 3000 contacts will be fetched due to RAM restrictions.
  * 
@@ -153,9 +190,9 @@
  * \a aSqlQuery An SQL query
  * \return the list of matched contact ids
  */
-QList<QContactLocalId> CntSymbianSrvConnection::searchContactIdsL(const TDesC& aSqlQuery)
+QList<QContactLocalId> CntSymbianSrvConnection::searchContactIdsL(const TDesC& aSqlQuery, QueryType aQueryType)
 {
-    readContactsToBufferL(aSqlQuery);
+    readContactsToBufferL(aSqlQuery, aQueryType);
 
     RBufReadStream readStream;
     QList<QContactLocalId> list;
@@ -173,11 +210,36 @@
  * The leaving function that queries the SQL database
  * 
  * \a aSqlQuery An SQL query
+ * \return the list of matched contact ids and phonenumber values
+ */
+QList<QPair<QContactLocalId, QString> > CntSymbianSrvConnection::searchPhoneNumbersL(const TDesC& aSqlQuery, QueryType aQueryType)
+{
+    readContactsToBufferL(aSqlQuery, aQueryType);
+
+    RBufReadStream readStream;
+    QList<QPair<QContactLocalId, QString> > list;
+    TInt item;
+    TBuf<256> extraValue;
+    
+    readStream.Open(*m_buffer);
+    while ((item = readStream.ReadInt32L()) != 0) {
+        readStream >> extraValue;
+        QContactLocalId id = item;
+        list.append(qMakePair(id,QString::fromUtf16(extraValue.Ptr(), extraValue.Length())));
+    }
+
+    return list;
+}
+
+/*!
+ * The leaving function that queries the SQL database
+ * 
+ * \a aSqlQuery An SQL query
  * \return the list of matched contact ids
  */
 QList<QContact> CntSymbianSrvConnection::searchContactNamesL(const TDesC& aSqlQuery)
 {
-    readContactsToBufferL(aSqlQuery);
+    readContactsToBufferL(aSqlQuery, CntSymbianSrvConnection::CntSearchResultList);
 
     RBufReadStream readStream;
     QList<QContact> contacts;
@@ -230,7 +292,7 @@
  * \a id database id of the contact
  * \return the list of matched contact names
  */
-void CntSymbianSrvConnection::readContactsToBufferL(const TDesC& sqlQuery)
+void CntSymbianSrvConnection::readContactsToBufferL(const TDesC& sqlQuery, QueryType aQueryType)
 {
     // Initialize connection if it is not initialized yet.
     if (!m_isInitialized) {
@@ -242,15 +304,16 @@
     TIpcArgs args;
     args.Set(0, &GetReceivingBufferL());
     args.Set(1, &sqlQuery);
-    TInt newBuffSize = SendReceive(KCntSearchResultList, args);
+    TInt newBuffSize = SendReceive(aQueryType, args);
     User::LeaveIfError(newBuffSize);
     if (newBuffSize > 0) {
         args.Set(0, &GetReceivingBufferL(newBuffSize));
         args.Set(1, &sqlQuery);
-        User::LeaveIfError(SendReceive(KCntSearchResultList, args));
+        User::LeaveIfError(SendReceive(aQueryType, args));
     }
 }
 
+    
 /*!
  * Connect to / create a cntsrv server session
  */
--- a/plugins/contacts/symbian/plugin/symbian_defines.pri	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/symbian_defines.pri	Mon Oct 04 01:37:06 2010 +0300
@@ -1,23 +1,23 @@
 
 symbian: {
-    exists($${EPOCROOT}epoc32/data/z/system/install/Series60v5.2.sis) {
-        exists($${EPOCROOT}epoc32/release/winscw/udeb/VPbkEng.dll) \
-        | exists($${EPOCROOT}epoc32/release/armv5/urel/VPbkEng.dll) {
-            message("TB 9.2 platform")
-        } else {
-            message("TB 10.1 or later platform")
+#    exists($${EPOCROOT}epoc32/data/z/system/install/Series60v5.2.sis) {
+#        exists($${EPOCROOT}epoc32/release/winscw/udeb/VPbkEng.dll) \
+#        | exists($${EPOCROOT}epoc32/release/armv5/urel/VPbkEng.dll) {
+#            message("S^3 platform")
+#        } else {
+            message("S^4 or later platform")
             DEFINES += SYMBIAN_BACKEND_USE_SQLITE
             
             # This will enable signals to be emitted sychronously with every
             # operation instead of them beeing emitted when database event observer
             # interface if called (HandleDatabaseEventL). This is an optimization
-            # for 10.1 platform. However enabling this will cause some problems
+            # for S^4 platform. However enabling this will cause some problems
             # with signals concerning adding/removing groups/group participants. 
             DEFINES += SYMBIAN_BACKEND_SIGNAL_EMISSION_TWEAK
-        }
-    }
-    
-    contains(S60_VERSION, 3.2) {
-    	DEFINES += SYMBIAN_BACKEND_S60_VERSION_32
-    }
-}
\ No newline at end of file
+#        }
+#    }
+#    
+#    contains(S60_VERSION, 3.2) {
+#    	DEFINES += SYMBIAN_BACKEND_S60_VERSION_32
+#    }
+}
--- a/plugins/contacts/symbian/plugin/tsrc/tsrc.pri	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/tsrc.pri	Mon Oct 04 01:37:06 2010 +0300
@@ -50,7 +50,6 @@
         ../../inc/cntsymbiandatabase.h \
         ../../inc/cntdisplaylabel.h \
         ../../inc/filtering/cntdisplaylabelsqlfilter.h \
-        ../../inc/filtering/cntsqlsearch.h \
         ../../inc/filtering/cntdbinfo.h \
         ../../inc/filtering/cntfilterdetail.h \
         ../../inc/filtering/cntfilterdefault.h \
@@ -98,7 +97,6 @@
         ../../src/cntsymbiandatabase.cpp \
         ../../src/cntdisplaylabel.cpp \
         ../../src/filtering/cntdisplaylabelsqlfilter.cpp \
-        ../../src/filtering/cntsqlsearch.cpp \
         ../../src/filtering/cntdbinfo.cpp \
         ../../src/filtering/cntfilterdetail.cpp \
         ../../src/filtering/cntfilterdefault.cpp \
--- a/plugins/contacts/symbian/plugin/tsrc/tst_qcontactmanagersymbian/tst_qcontactmanagersymbian.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/tst_qcontactmanagersymbian/tst_qcontactmanagersymbian.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -6,7 +6,7 @@
 include(../tsrc.pri)
 
 symbian: {
-    INCLUDEPATH += .\inc
+    INCLUDEPATH += ./inc
     INCLUDEPATH += $$SYMBIAN_PATHS
     INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
     
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/main.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/ut_symbian/main.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -46,7 +46,6 @@
 #include "ut_cntrelationship.h"
 #include "ut_cntsymbiandatabase.h"
 #include "ut_transformcontactdata.h"
-#include "ut_cntsqlsearch.h"
 #include "mt_cntsqlsort.h"
 
 #include <QtTest/QtTest>
@@ -82,12 +81,6 @@
     TestCntTransformContactData ut_transformContactData;
     testRunner.runTests(ut_transformContactData);
     
-    UT_CntSqlSearch ut_sqlSearch;
-    testRunner.runTests(ut_sqlSearch);
-    
-    MT_CntSqlSort mt_sqlSort;
-    testRunner.runTests(mt_sqlSort);
-    
     testRunner.printResults();
 
     /*if (promptOnExit) {
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/test_data.txt	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/ut_symbian/test_data.txt	Mon Oct 04 01:37:06 2010 +0300
@@ -28,7 +28,7 @@
 [ContactDetailFilter2: Name, LastName, Daniel,MatchExactly, 1, 0]
          //Name - MatchContains
 [ContactDetailFilter3: Name, FirstName, nn,MatchContains, 3, 0]
-[ContactDetailFilter4: Name, LastName, n,MatchContains, 4, 0]
+[ContactDetailFilter4: Name, LastName, n,MatchContains, 5, 0]
          //Name - MatchStartsWith
 [ContactDetailFilter5: Name, FirstName, Jo,MatchStartsWith, 2, 0]
 [ContactDetailFilter6: Name, LastName, Len,MatchStartsWith, 1, 0]
@@ -46,7 +46,7 @@
 //Email - MatchStartsWith
 [ContactDetailFilter13: EmailAddress, EmailAddress, Joronn,MatchStartsWith, 1, 0]
 //Email - MatchEndsWith
-[ContactDetailFilter14: EmailAddress, EmailAddress, com,MatchEndsWith, 5, 0]
+[ContactDetailFilter14: EmailAddress, EmailAddress, com,MatchEndsWith, 8, 0]
 //Email - No results search
 [ContactDetailFilter15: EmailAddress, EmailAddress, andrewf,MatchEndsWith, 0, 0]
 //-----------------------------------------------------------------------
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntfiltering.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntfiltering.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -243,16 +243,11 @@
     createContact_7();
     createContact_8();
     createContact_9();
-    // Empty contact
-    //QContact empty;
-    //mCntMng->saveContact(&empty);
     
     QContactManager::Error err;
     QList<QContactLocalId> cnt_ids = m_engine->contactIds(QContactFilter(),QList<QContactSortOrder>(), &err);
     int j = cnt_ids.count();
-    // 7contacts created in code, so check if all 5 were created
     QVERIFY(9 == j);
-    
 }
 
 
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsqlsearch.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1039 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-#include <QStringList>
-
-#include "ut_cntsqlsearch.h"
-#include "cntsqlsearch.h"
-
-#define WRITE_LOGS
-//#define SQL_QT_TEST
-
-#if defined(WRITE_LOGS)
-#include <e32debug.h> // RDebug
-
-#define LOG(a)              WriteLog(a, "")
-#define LOG2(a, b)          WriteLog(a, b)
-#define TEST_BEGIN_LOG(a)   LOG(a##" begins")
-#define TEST_PASSED_LOG(a)  LOG(a##" passed")
-
-void WriteLog(const QString a, const QString b);
-void WritePart(const TDesC& s);
-#else
-#define LOG(a)
-#define LOG2(a, b)
-#define TEST_BEGIN_LOG(a)
-#define TEST_PASSED_LOG(a)
-#endif
-
-
-void UT_CntSqlSearch::initTestCase()
-{
-}
-
-void UT_CntSqlSearch::cleanupTestCase()
-{
-}
-
-
-void UT_CntSqlSearch::init()
-{
-mCntSqlSearch = new CntSqlSearch();
-}
-
-void UT_CntSqlSearch::cleanup()
-{
-    delete mCntSqlSearch;
-    mCntSqlSearch = 0;
-    
-}
-void UT_CntSqlSearch::testPredictiveSearch()
-{
-    TEST_BEGIN_LOG("testPredictiveSearch");
-    
-    QString pattern = QString("205");
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>145522562959409151 AND nbr<145804037936119808) AND NOT(nbr2>145522562959409151 AND nbr2<145804037936119808) AND NOT(nbr3>145522562959409151 AND nbr3<145804037936119808) AND NOT(nbr4>145522562959409151 AND nbr4<145804037936119808))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch2 WHERE \
-((nbr>145522562959409151 AND nbr<145804037936119808) OR (nbr2>145522562959409151 AND nbr2<145804037936119808) \
-OR (nbr3>145522562959409151 AND nbr3<145804037936119808) OR (nbr4>145522562959409151 AND nbr4<145804037936119808)) OR \
-(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>144115188075855871 AND nbr3<216172782113783808) OR \
-(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>360287970189639679 AND nbr3<432345564227567616) \
-ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#endif // #if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE) 
-    QString reference("SELECT predictivesearch2.contact_id FROM predictivesearch2 WHERE EXISTS (SELECT contact_id FROM predictivesearch5 WHERE predictivesearch2.contact_id = predictivesearch5.contact_id) OR (SELECT contact_id FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>145522562959409151 AND predictivesearch2.nbr<145804037936119808) AND NOT(predictivesearch2.nbr2>145522562959409151 AND predictivesearch2.nbr2<145804037936119808) AND NOT(predictivesearch2.nbr3>145522562959409151 AND predictivesearch2.nbr3<145804037936119808) AND NOT(predictivesearch2.nbr4>145522562959409151 AND predictivesearch2.nbr4<145804037936119808)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    QString result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << "-> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern = QString("101");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch1 WHERE NOT(NOT(NOT(NOT(nbr>72339069014638591 AND nbr<72620543991349248) AND NOT(nbr2>72339069014638591 AND nbr2<72620543991349248) AND NOT(nbr3>72339069014638591 AND nbr3<72620543991349248) AND NOT(nbr4>72339069014638591 AND nbr4<72620543991349248))) AND NOT(NOT(NOT(nbr2>72057594037927935 AND nbr2<144115188075855872 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr2>72057594037927935 AND nbr2<144115188075855872) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr2>72057594037927935 AND nbr2<144115188075855872) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr3>72057594037927935 AND nbr3<144115188075855872)))) ORDER BY predictivesearch1.first_name, predictivesearch1.last_name ASC;");
-#else
-    reference = QString("SELECT contact_id FROM predictivesearch1 WHERE ((nbr>72339069014638591 AND nbr<72620543991349248) OR (nbr2>72339069014638591 AND nbr2<72620543991349248) OR (nbr3>72339069014638591 AND nbr3<72620543991349248) OR (nbr4>72339069014638591 AND nbr4<72620543991349248)) OR (nbr2>72057594037927935 AND nbr2<144115188075855872 AND nbr>72057594037927935 AND nbr<144115188075855872) OR (nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr>72057594037927935 AND nbr<144115188075855872) OR (nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr2>72057594037927935 AND nbr2<144115188075855872) OR (nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr>72057594037927935 AND nbr<144115188075855872) OR (nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr2>72057594037927935 AND nbr2<144115188075855872) OR (nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr3>72057594037927935 AND nbr3<144115188075855872) ORDER BY predictivesearch1.first_name, predictivesearch1.last_name ASC;");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern = QString("202");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>144678138029277183 AND nbr<144959613005987840) AND NOT(nbr2>144678138029277183 AND nbr2<144959613005987840) AND NOT(nbr3>144678138029277183 AND nbr3<144959613005987840) AND NOT(nbr4>144678138029277183 AND nbr4<144959613005987840))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>144115188075855871 AND nbr3<216172782113783808)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#else
-    reference = QString("TODO");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);    
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-        
-    pattern = QString("25");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch2 WHERE (NOT(NOT(nbr>166633186212708351 AND nbr<171136785840078848) AND NOT(nbr2>166633186212708351 AND nbr2<171136785840078848) AND NOT(nbr3>166633186212708351 AND nbr3<171136785840078848) AND NOT(nbr4>166633186212708351 AND nbr4<171136785840078848))) ORDER BY first_name, last_name ASC;");
-#else
-    reference = QString("SELECT contact_id FROM predictivesearch2 WHERE (NOT(NOT(nbr>166633186212708351 AND nbr<171136785840078848) AND NOT(nbr2>166633186212708351 AND nbr2<171136785840078848) AND NOT(nbr3>166633186212708351 AND nbr3<171136785840078848) AND NOT(nbr4>166633186212708351 AND nbr4<171136785840078848))) ORDER BY first_name, last_name ASC;");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare( reference));
-
-
-    pattern = QString("56606");
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch5 WHERE NOT(NOT(NOT(NOT(nbr>389005014883893247 AND nbr<389006114395521024) AND NOT(nbr2>389005014883893247 AND nbr2<389006114395521024) AND NOT(nbr3>389005014883893247 AND nbr3<389006114395521024) AND NOT(nbr4>389005014883893247 AND nbr4<389006114395521024))) AND NOT(NOT(NOT(nbr2>432345564227567615 AND nbr2<504403158265495552 AND nbr>388998417814126591 AND nbr<389279892790837248) AND NOT(nbr3>432345564227567615 AND nbr3<504403158265495552 AND nbr>388998417814126591 AND nbr<389279892790837248) AND NOT(nbr3>432345564227567615 AND nbr3<504403158265495552 AND nbr2>388998417814126591 AND nbr2<389279892790837248) AND NOT(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr>388998417814126591 AND nbr<389279892790837248) AND NOT(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr2>388998417814126591 AND nbr2<389279892790837248) AND NOT(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr3>388998417814126591 AND nbr3<389279892790837248))) AND NOT(NOT(NOT(nbr2>388998417814126591 AND nbr2<389279892790837248 AND nbr>432345564227567615 AND nbr<504403158265495552) AND NOT(nbr3>388998417814126591 AND nbr3<389279892790837248 AND nbr>432345564227567615 AND nbr<504403158265495552) AND NOT(nbr3>388998417814126591 AND nbr3<389279892790837248 AND nbr2>432345564227567615 AND nbr2<504403158265495552) AND NOT(nbr4>388998417814126591 AND nbr4<389279892790837248 AND nbr>432345564227567615 AND nbr<504403158265495552) AND NOT(nbr4>388998417814126591 AND nbr4<389279892790837248 AND nbr2>432345564227567615 AND nbr2<504403158265495552) AND NOT(nbr4>388998417814126591 AND nbr4<389279892790837248 AND nbr3>432345564227567615 AND nbr3<504403158265495552)))) ORDER BY predictivesearch5.first_name, predictivesearch5.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch5 WHERE \
-((nbr>389005014883893247 AND nbr<389006114395521024) OR (nbr2>389005014883893247 AND nbr2<389006114395521024) OR \
-(nbr3>389005014883893247 AND nbr3<389006114395521024) OR (nbr4>389005014883893247 AND nbr4<389006114395521024)) OR \
-(nbr2>432345564227567615 AND nbr2<504403158265495552 AND nbr>388998417814126591 AND nbr<389279892790837248) OR \
-(nbr3>432345564227567615 AND nbr3<504403158265495552 AND nbr>388998417814126591 AND nbr<389279892790837248) OR \
-(nbr3>432345564227567615 AND nbr3<504403158265495552 AND nbr2>388998417814126591 AND nbr2<389279892790837248) OR \
-(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr>388998417814126591 AND nbr<389279892790837248) OR \
-(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr2>388998417814126591 AND nbr2<389279892790837248) OR \
-(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr3>388998417814126591 AND nbr3<389279892790837248) OR \
-(nbr2>388998417814126591 AND nbr2<389279892790837248 AND nbr>432345564227567615 AND nbr<504403158265495552) OR \
-(nbr3>388998417814126591 AND nbr3<389279892790837248 AND nbr>432345564227567615 AND nbr<504403158265495552) OR \
-(nbr3>388998417814126591 AND nbr3<389279892790837248 AND nbr2>432345564227567615 AND nbr2<504403158265495552) OR \
-(nbr4>388998417814126591 AND nbr4<389279892790837248 AND nbr>432345564227567615 AND nbr<504403158265495552) OR \
-(nbr4>388998417814126591 AND nbr4<389279892790837248 AND nbr2>432345564227567615 AND nbr2<504403158265495552) OR \
-(nbr4>388998417814126591 AND nbr4<389279892790837248 AND nbr3>432345564227567615 AND nbr3<504403158265495552) \
-ORDER BY predictivesearch5.first_name, predictivesearch5.last_name ASC;");
-#endif //#if defined(USE_DEMORGAN) 
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE (NOT(NOT(predictivesearch5.nbr>389005014883893247 AND predictivesearch5.nbr<389006114395521024) AND NOT(predictivesearch5.nbr2>389005014883893247 AND predictivesearch5.nbr2<389006114395521024) AND NOT(predictivesearch5.nbr3>389005014883893247 AND predictivesearch5.nbr3<389006114395521024) AND NOT(predictivesearch5.nbr4>389005014883893247 AND predictivesearch5.nbr4<389006114395521024))) UNION SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 JOIN predictivesearch6 ON predictivesearch5.contact_id = predictivesearch6.contact_id WHERE(NOT(NOT(predictivesearch5.nbr>388998417814126591 AND predictivesearch5.nbr<389279892790837248) AND NOT(predictivesearch5.nbr2>388998417814126591 AND predictivesearch5.nbr2<389279892790837248) AND NOT(predictivesearch5.nbr3>388998417814126591 AND predictivesearch5.nbr3<389279892790837248) AND NOT(predictivesearch5.nbr4>388998417814126591 AND predictivesearch5.nbr4<389279892790837248)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("3");
-    reference = QString ("SELECT contact_id FROM predictivesearch3 ORDER BY first_name, last_name ASC;");
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-    
-    pattern = QString("0");
-    reference = QString ("SELECT contact_id FROM predictivesearch0 ORDER BY first_name, last_name ASC;");
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare( reference));
-
-    // TODO: Test this case on HW and verify leading zeros.
-    pattern.clear();
-    pattern = "0705";
-    #if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>31613158321815551 AND nbr<31630750507859968) AND NOT(nbr2>31613158321815551 AND nbr2<31630750507859968) AND NOT(nbr3>31613158321815551 AND nbr3<31630750507859968) AND NOT(nbr4>31613158321815551 AND nbr4<31630750507859968))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>31525197391593471 AND nbr<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>31525197391593471 AND nbr2<36028797018963968) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>31525197391593471 AND nbr3<36028797018963968))) AND NOT(NOT(NOT(nbr2>31525197391593471 AND nbr2<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>31525197391593471 AND nbr3<36028797018963968 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>31525197391593471 AND nbr4<36028797018963968 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-
-#endif //#if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE (NOT(NOT(predictivesearch0.nbr>31613158321815551 AND predictivesearch0.nbr<31630750507859968) AND NOT(predictivesearch0.nbr2>31613158321815551 AND predictivesearch0.nbr2<31630750507859968) AND NOT(predictivesearch0.nbr3>31613158321815551 AND predictivesearch0.nbr3<31630750507859968) AND NOT(predictivesearch0.nbr4>31613158321815551 AND predictivesearch0.nbr4<31630750507859968))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 JOIN predictivesearch5 ON predictivesearch0.contact_id = predictivesearch5.contact_id WHERE(NOT(NOT(predictivesearch0.nbr>31525197391593471 AND predictivesearch0.nbr<36028797018963968) AND NOT(predictivesearch0.nbr2>31525197391593471 AND predictivesearch0.nbr2<36028797018963968) AND NOT(predictivesearch0.nbr3>31525197391593471 AND predictivesearch0.nbr3<36028797018963968) AND NOT(predictivesearch0.nbr4>31525197391593471 AND predictivesearch0.nbr4<36028797018963968)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    //qDebug() << pattern << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-    
-    pattern.clear();
-    pattern = "4301";  
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch4 WHERE NOT(NOT(NOT(NOT(nbr>301758767219867647 AND nbr<301776359405912064) AND NOT(nbr2>301758767219867647 AND nbr2<301776359405912064) AND NOT(nbr3>301758767219867647 AND nbr3<301776359405912064) AND NOT(nbr4>301758767219867647 AND nbr4<301776359405912064))) AND NOT(NOT(NOT(nbr2>72057594037927935 AND nbr2<144115188075855872 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr3>301741175033823231 AND nbr3<306244774661193728))) AND NOT(NOT(NOT(nbr2>301741175033823231 AND nbr2<306244774661193728 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr2>72057594037927935 AND nbr2<144115188075855872) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr2>72057594037927935 AND nbr2<144115188075855872) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr3>72057594037927935 AND nbr3<144115188075855872)))) ORDER BY predictivesearch4.first_name, predictivesearch4.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-
-#endif //#if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch4.contact_id, predictivesearch4.first_name, predictivesearch4.last_name FROM predictivesearch4 WHERE (NOT(NOT(predictivesearch4.nbr>301758767219867647 AND predictivesearch4.nbr<301776359405912064) AND NOT(predictivesearch4.nbr2>301758767219867647 AND predictivesearch4.nbr2<301776359405912064) AND NOT(predictivesearch4.nbr3>301758767219867647 AND predictivesearch4.nbr3<301776359405912064) AND NOT(predictivesearch4.nbr4>301758767219867647 AND predictivesearch4.nbr4<301776359405912064))) UNION SELECT predictivesearch4.contact_id, predictivesearch4.first_name, predictivesearch4.last_name FROM predictivesearch4 JOIN predictivesearch1 ON predictivesearch4.contact_id = predictivesearch1.contact_id WHERE(NOT(NOT(predictivesearch4.nbr>301741175033823231 AND predictivesearch4.nbr<306244774661193728) AND NOT(predictivesearch4.nbr2>301741175033823231 AND predictivesearch4.nbr2<306244774661193728) AND NOT(predictivesearch4.nbr3>301741175033823231 AND predictivesearch4.nbr3<306244774661193728) AND NOT(predictivesearch4.nbr4>301741175033823231 AND predictivesearch4.nbr4<306244774661193728)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    //qDebug() << pattern << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern.clear();
-    pattern = "4304";
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch4 WHERE NOT(NOT(NOT(NOT(nbr>301811543778000895 AND nbr<301829135964045312) AND NOT(nbr2>301811543778000895 AND nbr2<301829135964045312) AND NOT(nbr3>301811543778000895 AND nbr3<301829135964045312) AND NOT(nbr4>301811543778000895 AND nbr4<301829135964045312))) AND NOT(NOT(NOT(nbr2>288230376151711743 AND nbr2<360287970189639680 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>288230376151711743 AND nbr3<360287970189639680 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>288230376151711743 AND nbr3<360287970189639680 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>288230376151711743 AND nbr4<360287970189639680 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr4>288230376151711743 AND nbr4<360287970189639680 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>288230376151711743 AND nbr4<360287970189639680 AND nbr3>301741175033823231 AND nbr3<306244774661193728))) AND NOT(NOT(NOT(nbr2>301741175033823231 AND nbr2<306244774661193728 AND nbr>288230376151711743 AND nbr<360287970189639680) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr>288230376151711743 AND nbr<360287970189639680) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr2>288230376151711743 AND nbr2<360287970189639680) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr>288230376151711743 AND nbr<360287970189639680) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr2>288230376151711743 AND nbr2<360287970189639680) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr3>288230376151711743 AND nbr3<360287970189639680)))) ORDER BY predictivesearch4.first_name, predictivesearch4.last_name ASC;");
-#else
-	//TODO:
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    //qDebug() << pattern << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-	pattern.clear();
-    pattern = "4043";
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch4 WHERE NOT(NOT(NOT(NOT(nbr>289409052616687615 AND nbr<289426644802732032) AND NOT(nbr2>289409052616687615 AND nbr2<289426644802732032) AND NOT(nbr3>289409052616687615 AND nbr3<289426644802732032) AND NOT(nbr4>289409052616687615 AND nbr4<289426644802732032))) AND NOT(NOT(NOT(nbr2>301741175033823231 AND nbr2<306244774661193728 AND nbr>288230376151711743 AND nbr<360287970189639680) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr>288230376151711743 AND nbr<360287970189639680) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr2>288230376151711743 AND nbr2<360287970189639680) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr>288230376151711743 AND nbr<360287970189639680) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr2>288230376151711743 AND nbr2<360287970189639680) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr3>288230376151711743 AND nbr3<360287970189639680))) AND NOT(NOT(NOT(nbr2>288230376151711743 AND nbr2<360287970189639680 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>288230376151711743 AND nbr3<360287970189639680 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>288230376151711743 AND nbr3<360287970189639680 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>288230376151711743 AND nbr4<360287970189639680 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr4>288230376151711743 AND nbr4<360287970189639680 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>288230376151711743 AND nbr4<360287970189639680 AND nbr3>301741175033823231 AND nbr3<306244774661193728)))) ORDER BY predictivesearch4.first_name, predictivesearch4.last_name ASC;");
-#else
-	//TODO:
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    //qDebug() << pattern << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern = QString("03");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (NOT(NOT(nbr>13510798882111487 AND nbr<18014398509481984) AND NOT(nbr2>13510798882111487 AND nbr2<18014398509481984) AND NOT(nbr3>13510798882111487 AND nbr3<18014398509481984) AND NOT(nbr4>13510798882111487 AND nbr4<18014398509481984))) ORDER BY first_name, last_name ASC;");
-#else
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (nbr>13510798882111487 AND nbr<18014398509481984) OR (nbr2>13510798882111487 AND nbr2<18014398509481984) OR (nbr3>13510798882111487 AND nbr3<18014398509481984) OR (nbr4>13510798882111487 AND nbr4<18014398509481984) ORDER BY first_name, last_name ASC;");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare( reference));
-
-    // Empty pattern
-    pattern = QString("");
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(result.length() == 0);
-        
-    // Too long pattern (16 digits)
-    pattern = QString("0123456789012345");
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(result.length() == 0);
-
-    pattern = QString("0000000000000000"); // 16 zeros
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(result.length() == 0);
-    
-    // Full of zeros
-    pattern = QString("000000000000000"); // 15 zeros
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (NOT(NOT(nbr>-1 AND nbr<1) AND NOT(nbr2>-1 AND nbr2<1) AND NOT(nbr3>-1 AND nbr3<1) AND NOT(nbr4>-1 AND nbr4<1))) ORDER BY first_name, last_name ASC;");
-#else
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (nbr>-1 AND nbr<1) OR (nbr2>-1 AND nbr2<1) OR (nbr3>-1 AND nbr3<1) OR (nbr4>-1 AND nbr4<1) ORDER BY first_name, last_name ASC;");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-    
-    // Full of nines
-    pattern = QString("999999999999999"); // 15 nines
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch9 WHERE (NOT(NOT(nbr>691752902764108184 AND nbr<691752902764108186) AND NOT(nbr2>691752902764108184 AND nbr2<691752902764108186) AND NOT(nbr3>691752902764108184 AND nbr3<691752902764108186) AND NOT(nbr4>691752902764108184 AND nbr4<691752902764108186))) ORDER BY first_name, last_name ASC;");
-#else
-    reference = QString("SELECT contact_id FROM predictivesearch9 WHERE (nbr>691752902764108184 AND nbr<691752902764108186) OR (nbr2>691752902764108184 AND nbr2<691752902764108186) OR (nbr3>691752902764108184 AND nbr3<691752902764108186) OR (nbr4>691752902764108184 AND nbr4<691752902764108186) ORDER BY first_name, last_name ASC;");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    // Leading zeros
-    pattern = QString("001100");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (NOT(NOT(nbr>299067162755071 AND nbr<299135882231808) AND NOT(nbr2>299067162755071 AND nbr2<299135882231808) AND NOT(nbr3>299067162755071 AND nbr3<299135882231808) AND NOT(nbr4>299067162755071 AND nbr4<299135882231808))) ORDER BY first_name, last_name ASC;");
-#else
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE (nbr>299067162755071 AND nbr<299135882231808) OR (nbr2>299067162755071 AND nbr2<299135882231808) OR (nbr3>299067162755071 AND nbr3<299135882231808) OR (nbr4>299067162755071 AND nbr4<299135882231808) ORDER BY first_name, last_name ASC;");
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-    
-    pattern = QString("43043");
-    reference = QString("SELECT contact_id FROM predictivesearch4 WHERE NOT(NOT(NOT(NOT(nbr>301814842312884223 AND nbr<301815941824512000) AND NOT(nbr2>301814842312884223 AND nbr2<301815941824512000) AND NOT(nbr3>301814842312884223 AND nbr3<301815941824512000) AND NOT(nbr4>301814842312884223 AND nbr4<301815941824512000))) AND NOT(NOT(NOT(nbr2>301741175033823231 AND nbr2<306244774661193728 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr3>301741175033823231 AND nbr3<306244774661193728 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr>301741175033823231 AND nbr<306244774661193728) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr2>301741175033823231 AND nbr2<306244774661193728) AND NOT(nbr4>301741175033823231 AND nbr4<306244774661193728 AND nbr3>301741175033823231 AND nbr3<306244774661193728)))) ORDER BY predictivesearch4.first_name, predictivesearch4.last_name ASC;");
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern = QString("0020030");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>563156111851519 AND nbr<563160406818816) AND NOT(nbr2>563156111851519 AND nbr2<563160406818816) AND NOT(nbr3>563156111851519 AND nbr3<563160406818816) AND NOT(nbr4>563156111851519 AND nbr4<563160406818816))) AND NOT(NOT(NOT(nbr2>216172782113783807 AND nbr2<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>216172782113783807 AND nbr3<220676381741154304 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>216172782113783807 AND nbr4<220676381741154304 AND nbr3>562949953421311 AND nbr3<844424930131968))) AND NOT(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>216172782113783807 AND nbr<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>216172782113783807 AND nbr2<220676381741154304) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>216172782113783807 AND nbr3<220676381741154304)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#else
-    // TODO: add non-De Morgan case
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-    
-    pattern = QString("00430001020");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>1178676735508479 AND nbr<1178676735574016) AND NOT(nbr2>1178676735508479 AND nbr2<1178676735574016) AND NOT(nbr3>1178676735508479 AND nbr3<1178676735574016) AND NOT(nbr4>1178676735508479 AND nbr4<1178676735574016))) AND NOT(NOT(NOT(nbr2>72620543991349247 AND nbr2<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr3>72620543991349247 AND nbr3<72638136177393664 AND nbr2>1178676464975871 AND nbr2<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr>1178676464975871 AND nbr<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr2>1178676464975871 AND nbr2<1196268651020288) AND NOT(nbr4>72620543991349247 AND nbr4<72638136177393664 AND nbr3>1178676464975871 AND nbr3<1196268651020288))) AND NOT(NOT(NOT(nbr2>1178676464975871 AND nbr2<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>1178676464975871 AND nbr3<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr3>1178676464975871 AND nbr3<1196268651020288 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr>72620543991349247 AND nbr<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr2>72620543991349247 AND nbr2<72638136177393664) AND NOT(nbr4>1178676464975871 AND nbr4<1196268651020288 AND nbr3>72620543991349247 AND nbr3<72638136177393664)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#else
-    // TODO: add non-De Morgan case
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-    
-    pattern = QString("227264583788306"); // 15 digits
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>155134792167883525 AND nbr<155134792167883527) AND NOT(nbr2>155134792167883525 AND nbr2<155134792167883527) AND NOT(nbr3>155134792167883525 AND nbr3<155134792167883527) AND NOT(nbr4>155134792167883525 AND nbr4<155134792167883527))) AND NOT(NOT(NOT(nbr2>432345564227567615 AND nbr2<504403158265495552 AND nbr>155134792167883519 AND nbr<155134792167883776) AND NOT(nbr3>432345564227567615 AND nbr3<504403158265495552 AND nbr>155134792167883519 AND nbr<155134792167883776) AND NOT(nbr3>432345564227567615 AND nbr3<504403158265495552 AND nbr2>155134792167883519 AND nbr2<155134792167883776) AND NOT(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr>155134792167883519 AND nbr<155134792167883776) AND NOT(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr2>155134792167883519 AND nbr2<155134792167883776) AND NOT(nbr4>432345564227567615 AND nbr4<504403158265495552 AND nbr3>155134792167883519 AND nbr3<155134792167883776))) AND NOT(NOT(NOT(nbr2>155134792167883519 AND nbr2<155134792167883776 AND nbr>432345564227567615 AND nbr<504403158265495552) AND NOT(nbr3>155134792167883519 AND nbr3<155134792167883776 AND nbr>432345564227567615 AND nbr<504403158265495552) AND NOT(nbr3>155134792167883519 AND nbr3<155134792167883776 AND nbr2>432345564227567615 AND nbr2<504403158265495552) AND NOT(nbr4>155134792167883519 AND nbr4<155134792167883776 AND nbr>432345564227567615 AND nbr<504403158265495552) AND NOT(nbr4>155134792167883519 AND nbr4<155134792167883776 AND nbr2>432345564227567615 AND nbr2<504403158265495552) AND NOT(nbr4>155134792167883519 AND nbr4<155134792167883776 AND nbr3>432345564227567615 AND nbr3<504403158265495552)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#else
-    // TODO: add non-De Morgan case
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
- 
-    
-    pattern = QString("34096");
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch3 WHERE NOT(NOT(NOT(NOT(nbr>234352107367432191 AND nbr<234353206879059968) AND NOT(nbr2>234352107367432191 AND nbr2<234353206879059968) AND NOT(nbr3>234352107367432191 AND nbr3<234353206879059968) AND NOT(nbr4>234352107367432191 AND nbr4<234353206879059968))) AND NOT(NOT(NOT(nbr2>675539944105574399 AND nbr2<680043543732944896 AND nbr>234187180623265791 AND nbr<238690780250636288) AND NOT(nbr3>675539944105574399 AND nbr3<680043543732944896 AND nbr>234187180623265791 AND nbr<238690780250636288) AND NOT(nbr3>675539944105574399 AND nbr3<680043543732944896 AND nbr2>234187180623265791 AND nbr2<238690780250636288) AND NOT(nbr4>675539944105574399 AND nbr4<680043543732944896 AND nbr>234187180623265791 AND nbr<238690780250636288) AND NOT(nbr4>675539944105574399 AND nbr4<680043543732944896 AND nbr2>234187180623265791 AND nbr2<238690780250636288) AND NOT(nbr4>675539944105574399 AND nbr4<680043543732944896 AND nbr3>234187180623265791 AND nbr3<238690780250636288))) AND NOT(NOT(NOT(nbr2>234187180623265791 AND nbr2<238690780250636288 AND nbr>675539944105574399 AND nbr<680043543732944896) AND NOT(nbr3>234187180623265791 AND nbr3<238690780250636288 AND nbr>675539944105574399 AND nbr<680043543732944896) AND NOT(nbr3>234187180623265791 AND nbr3<238690780250636288 AND nbr2>675539944105574399 AND nbr2<680043543732944896) AND NOT(nbr4>234187180623265791 AND nbr4<238690780250636288 AND nbr>675539944105574399 AND nbr<680043543732944896) AND NOT(nbr4>234187180623265791 AND nbr4<238690780250636288 AND nbr2>675539944105574399 AND nbr2<680043543732944896) AND NOT(nbr4>234187180623265791 AND nbr4<238690780250636288 AND nbr3>675539944105574399 AND nbr3<680043543732944896)))) ORDER BY predictivesearch3.first_name, predictivesearch3.last_name ASC;");
-#else
-    // TODO: add non-De Morgan case
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-	pattern = QString("522000000000007"); // 15 digits
-#if defined(USE_DEMORGAN)
-	reference = QString("SELECT contact_id FROM predictivesearch5 WHERE NOT(NOT(NOT(NOT(nbr>369858119397801990 AND nbr<369858119397801992) AND NOT(nbr2>369858119397801990 AND nbr2<369858119397801992) AND NOT(nbr3>369858119397801990 AND nbr3<369858119397801992) AND NOT(nbr4>369858119397801990 AND nbr4<369858119397801992))) AND NOT(NOT(NOT(nbr2>504403158265495551 AND nbr2<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr3>504403158265495551 AND nbr3<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr>369858119397801983 AND nbr<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr2>369858119397801983 AND nbr2<370139594374512640) AND NOT(nbr4>504403158265495551 AND nbr4<576460752303423488 AND nbr3>369858119397801983 AND nbr3<370139594374512640))) AND NOT(NOT(NOT(nbr2>369858119397801983 AND nbr2<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr3>369858119397801983 AND nbr3<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr>504403158265495551 AND nbr<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr2>504403158265495551 AND nbr2<576460752303423488) AND NOT(nbr4>369858119397801983 AND nbr4<370139594374512640 AND nbr3>504403158265495551 AND nbr3<576460752303423488)))) ORDER BY predictivesearch5.first_name, predictivesearch5.last_name ASC;");
-#else
-    // TODO: add non-De Morgan case
-#endif
-    result = mCntSqlSearch->CreatePredictiveSearch(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    TEST_PASSED_LOG("testPredictiveSearch");
-}
-
-void UT_CntSqlSearch::testSelectTableView()
-{
-    TEST_BEGIN_LOG("testSelectTableView");
-    
-    QString pattern = QString("0");
-    QString reference = QString("predictivesearch0");
-    QString result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("1");
-    reference = QString("predictivesearch1");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("2");
-    reference = QString("predictivesearch2");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("3");
-    reference = QString("predictivesearch3");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("4");
-    reference = QString("predictivesearch4");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("5");
-    reference = QString("predictivesearch5");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("6");
-    reference = QString("predictivesearch6");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("7");
-    reference = QString("predictivesearch7");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("8");
-    reference = QString("predictivesearch8");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("9");
-    reference = QString("predictivesearch9");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("09");
-    reference = QString("predictivesearch0");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("090");
-    reference = QString("predictivesearch0");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("909");
-    reference = QString("predictivesearch9");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("99");
-    reference = QString("predictivesearch9");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("000");
-    reference = QString("predictivesearch0");
-    result = mCntSqlSearch->SelectTable(pattern);
-    QVERIFY( !result.compare( reference) );
-    
-    TEST_PASSED_LOG("testSelectTableView");
-}
-
-void UT_CntSqlSearch::testCreateQuery()
-{   
-    TEST_BEGIN_LOG("testCreateQuery");
-    QString pattern = QString("102");
-
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch1 WHERE NOT(NOT(NOT(NOT(nbr>72620543991349247 AND nbr<72902018968059904) AND NOT(nbr2>72620543991349247 AND nbr2<72902018968059904) AND NOT(nbr3>72620543991349247 AND nbr3<72902018968059904) AND NOT(nbr4>72620543991349247 AND nbr4<72902018968059904))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>72057594037927935 AND nbr2<144115188075855872) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>72057594037927935 AND nbr<144115188075855872) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>72057594037927935 AND nbr2<144115188075855872) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>72057594037927935 AND nbr3<144115188075855872))) AND NOT(NOT(NOT(nbr2>72057594037927935 AND nbr2<144115188075855872 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr3>144115188075855871 AND nbr3<216172782113783808)))) ORDER BY predictivesearch1.first_name, predictivesearch1.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch1 WHERE \
-((nbr>72620543991349247 AND nbr<72902018968059904) OR \
-(nbr2>72620543991349247 AND nbr2<72902018968059904) OR \
-(nbr3>72620543991349247 AND nbr3<72902018968059904) OR \
-(nbr4>72620543991349247 AND nbr4<72902018968059904)) OR \
-(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>72057594037927935 AND nbr<144115188075855872) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>72057594037927935 AND nbr<144115188075855872) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>72057594037927935 AND nbr2<144115188075855872) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>72057594037927935 AND nbr<144115188075855872) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>72057594037927935 AND nbr2<144115188075855872) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>72057594037927935 AND nbr3<144115188075855872) OR \
-(nbr2>72057594037927935 AND nbr2<144115188075855872 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>72057594037927935 AND nbr3<144115188075855872 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>72057594037927935 AND nbr4<144115188075855872 AND nbr3>144115188075855871 AND nbr3<216172782113783808) \
-ORDER BY predictivesearch1.first_name, predictivesearch1.last_name ASC;");
-#endif // #if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    QString reference("SELECT predictivesearch1.contact_id FROM predictivesearch1 WHERE EXISTS (SELECT contact_id FROM predictivesearch2 WHERE predictivesearch1.contact_id = predictivesearch2.contact_id) OR (SELECT contact_id FROM predictivesearch1 WHERE (NOT(NOT(predictivesearch1.nbr>72620543991349247 AND predictivesearch1.nbr<72902018968059904) AND NOT(predictivesearch1.nbr2>72620543991349247 AND predictivesearch1.nbr2<72902018968059904) AND NOT(predictivesearch1.nbr3>72620543991349247 AND predictivesearch1.nbr3<72902018968059904) AND NOT(predictivesearch1.nbr4>72620543991349247 AND predictivesearch1.nbr4<72902018968059904)))) ORDER BY predictivesearch1.first_name, predictivesearch1.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    QString result = mCntSqlSearch->CreateQuery(pattern);
-    //qDebug() << pattern << " -> result" << result;
-	//TODO: Fix test result
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern = QString("00202");
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>565148976676863 AND nbr<566248488304640) AND NOT(nbr2>565148976676863 AND nbr2<566248488304640) AND NOT(nbr3>565148976676863 AND nbr3<566248488304640) AND NOT(nbr4>565148976676863 AND nbr4<566248488304640))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>562949953421311 AND nbr3<844424930131968))) AND NOT(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<216172782113783808)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE \
-((nbr>565148976676863 AND nbr<566248488304640) OR \
-(nbr2>565148976676863 AND nbr2<566248488304640) OR \
-(nbr3>565148976676863 AND nbr3<566248488304640) OR \
-(nbr4>565148976676863 AND nbr4<566248488304640)) OR \
-(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>562949953421311 AND nbr<844424930131968) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>562949953421311 AND nbr2<844424930131968) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>562949953421311 AND nbr3<844424930131968) OR \
-(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<216172782113783808) \
-ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#endif // #if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    // TODO: Test this case on HW and verify leading zeros.
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE (NOT(NOT(predictivesearch0.nbr>565148976676863 AND predictivesearch0.nbr<566248488304640) AND NOT(predictivesearch0.nbr2>565148976676863 AND predictivesearch0.nbr2<566248488304640) AND NOT(predictivesearch0.nbr3>565148976676863 AND predictivesearch0.nbr3<566248488304640) AND NOT(predictivesearch0.nbr4>565148976676863 AND predictivesearch0.nbr4<566248488304640))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 JOIN predictivesearch2 ON predictivesearch0.contact_id = predictivesearch2.contact_id WHERE(NOT(NOT(predictivesearch0.nbr>562949953421311 AND predictivesearch0.nbr<844424930131968) AND NOT(predictivesearch0.nbr2>562949953421311 AND predictivesearch0.nbr2<844424930131968) AND NOT(predictivesearch0.nbr3>562949953421311 AND predictivesearch0.nbr3<844424930131968) AND NOT(predictivesearch0.nbr4>562949953421311 AND predictivesearch0.nbr4<844424930131968)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    result = mCntSqlSearch->CreateQuery(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("202000");
-#if defined(USE_DEMORGAN)
-    // TODO: Test this case on HW and verify trailing zeros.
-	reference = QString("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>144678138029277183 AND nbr<144678206748753920) AND NOT(nbr2>144678138029277183 AND nbr2<144678206748753920) AND NOT(nbr3>144678138029277183 AND nbr3<144678206748753920) AND NOT(nbr4>144678138029277183 AND nbr4<144678206748753920))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<144132780261900288 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<144132780261900288 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>144115188075855871 AND nbr3<144132780261900288 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<144132780261900288 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<144132780261900288 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>144115188075855871 AND nbr4<144132780261900288 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>144115188075855871 AND nbr<144132780261900288) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>144115188075855871 AND nbr<144132780261900288) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>144115188075855871 AND nbr2<144132780261900288) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>144115188075855871 AND nbr<144132780261900288) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>144115188075855871 AND nbr2<144132780261900288) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>144115188075855871 AND nbr3<144132780261900288)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#else
-	// TODO: add non-De Morgan version
-#endif    
-
-    /*reference = QString("SELECT contact_id FROM predictivesearch2 WHERE \
-((nbr>144678138029277183 AND nbr<144678206748753920) OR (nbr2>144678138029277183 AND nbr2<144678206748753920) OR \
-(nbr3>144678138029277183 AND nbr3<144678206748753920) OR (nbr4>144678138029277183 AND nbr4<144678206748753920)) OR \
-(nbr2>144115188075855871 AND nbr2<144132780261900288 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>144115188075855871 AND nbr3<144132780261900288 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>144115188075855871 AND nbr3<144132780261900288 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>144115188075855871 AND nbr4<144132780261900288 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr4>144115188075855871 AND nbr4<144132780261900288 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>144115188075855871 AND nbr4<144132780261900288 AND nbr3>144115188075855871 AND nbr3<216172782113783808) OR \
-(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>144115188075855871 AND nbr<144132780261900288) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>144115188075855871 AND nbr<144132780261900288) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>144115188075855871 AND nbr2<144132780261900288) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>144115188075855871 AND nbr<144132780261900288) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>144115188075855871 AND nbr2<144132780261900288) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>144115188075855871 AND nbr3<144132780261900288) \
-ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");*/
-
-    result = mCntSqlSearch->CreateQuery(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("0020200");
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE NOT(NOT(NOT(NOT(nbr>565148976676863 AND nbr<565153271644160) AND NOT(nbr2>565148976676863 AND nbr2<565153271644160) AND NOT(nbr3>565148976676863 AND nbr3<565153271644160) AND NOT(nbr4>565148976676863 AND nbr4<565153271644160))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) AND NOT(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr3>562949953421311 AND nbr3<844424930131968))) AND NOT(NOT(NOT(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) AND NOT(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<144396663052566528)))) ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch0 WHERE \
-((nbr>565148976676863 AND nbr<565153271644160) OR (nbr2>565148976676863 AND nbr2<565153271644160) OR \
-(nbr3>565148976676863 AND nbr3<565153271644160) OR (nbr4>565148976676863 AND nbr4<565153271644160)) OR \
-(nbr2>144115188075855871 AND nbr2<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) OR \
-(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) OR \
-(nbr3>144115188075855871 AND nbr3<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) OR \
-(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr>562949953421311 AND nbr<844424930131968) OR \
-(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr2>562949953421311 AND nbr2<844424930131968) OR \
-(nbr4>144115188075855871 AND nbr4<144396663052566528 AND nbr3>562949953421311 AND nbr3<844424930131968) OR \
-(nbr2>562949953421311 AND nbr2<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) OR \
-(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) OR \
-(nbr3>562949953421311 AND nbr3<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) OR \
-(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr>144115188075855871 AND nbr<144396663052566528) OR \
-(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr2>144115188075855871 AND nbr2<144396663052566528) OR \
-(nbr4>562949953421311 AND nbr4<844424930131968 AND nbr3>144115188075855871 AND nbr3<144396663052566528) \
-ORDER BY predictivesearch0.first_name, predictivesearch0.last_name ASC;");
-#endif // #if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    // TODO: Test this case on HW and verify leading zeros.
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 WHERE (NOT(NOT(predictivesearch0.nbr>565148976676863 AND predictivesearch0.nbr<565153271644160) AND NOT(predictivesearch0.nbr2>565148976676863 AND predictivesearch0.nbr2<565153271644160) AND NOT(predictivesearch0.nbr3>565148976676863 AND predictivesearch0.nbr3<565153271644160) AND NOT(predictivesearch0.nbr4>565148976676863 AND predictivesearch0.nbr4<565153271644160))) UNION SELECT predictivesearch0.contact_id, predictivesearch0.first_name, predictivesearch0.last_name FROM predictivesearch0 JOIN predictivesearch2 ON predictivesearch0.contact_id = predictivesearch2.contact_id WHERE((NOT(NOT(predictivesearch0.nbr>562949953421311 AND predictivesearch0.nbr<844424930131968) AND NOT(predictivesearch0.nbr2>562949953421311 AND predictivesearch0.nbr2<844424930131968) AND NOT(predictivesearch0.nbr3>562949953421311 AND predictivesearch0.nbr3<844424930131968) AND NOT(predictivesearch0.nbr4>562949953421311 AND predictivesearch0.nbr4<844424930131968))) AND (NOT(NOT(predictivesearch2.nbr>144115188075855871 AND predictivesearch2.nbr<144396663052566528) AND NOT(predictivesearch2.nbr2>144115188075855871 AND predictivesearch2.nbr2<144396663052566528) AND NOT(predictivesearch2.nbr3>144115188075855871 AND predictivesearch2.nbr3<144396663052566528) AND NOT(predictivesearch2.nbr4>144115188075855871 AND predictivesearch2.nbr4<144396663052566528))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#endif //#if defined(SEARCH_FROM_ONE_TABLE) 
-    result = mCntSqlSearch->CreateQuery(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-
-    pattern = QString("20322");
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>144996996401332223 AND nbr<144998095912960000) AND NOT(nbr2>144996996401332223 AND nbr2<144998095912960000) AND NOT(nbr3>144996996401332223 AND nbr3<144998095912960000) AND NOT(nbr4>144996996401332223 AND nbr4<144998095912960000))) AND NOT(NOT(NOT(nbr2>225742931321946111 AND nbr2<226024406298656768 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>225742931321946111 AND nbr3<226024406298656768 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>225742931321946111 AND nbr3<226024406298656768 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>225742931321946111 AND nbr4<226024406298656768 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>225742931321946111 AND nbr4<226024406298656768 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>225742931321946111 AND nbr4<226024406298656768 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>225742931321946111 AND nbr<226024406298656768) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>225742931321946111 AND nbr<226024406298656768) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>225742931321946111 AND nbr2<226024406298656768) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>225742931321946111 AND nbr<226024406298656768) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>225742931321946111 AND nbr2<226024406298656768) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>225742931321946111 AND nbr3<226024406298656768)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM predictivesearch2 WHERE \
-((nbr>144996996401332223 AND nbr<144998095912960000) OR (nbr2>144996996401332223 AND nbr2<144998095912960000) OR \
-(nbr3>144996996401332223 AND nbr3<144998095912960000) OR (nbr4>144996996401332223 AND nbr4<144998095912960000)) OR \
-(nbr2>225742931321946111 AND nbr2<226024406298656768 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>225742931321946111 AND nbr3<226024406298656768 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>225742931321946111 AND nbr3<226024406298656768 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>225742931321946111 AND nbr4<226024406298656768 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr4>225742931321946111 AND nbr4<226024406298656768 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>225742931321946111 AND nbr4<226024406298656768 AND nbr3>144115188075855871 AND nbr3<216172782113783808) OR \
-(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>225742931321946111 AND nbr<226024406298656768) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>225742931321946111 AND nbr<226024406298656768) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>225742931321946111 AND nbr2<226024406298656768) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>225742931321946111 AND nbr<226024406298656768) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>225742931321946111 AND nbr2<226024406298656768) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>225742931321946111 AND nbr3<226024406298656768) \
-ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;"); 
-#endif // #if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>144996996401332223 AND predictivesearch2.nbr<144998095912960000) AND NOT(predictivesearch2.nbr2>144996996401332223 AND predictivesearch2.nbr2<144998095912960000) AND NOT(predictivesearch2.nbr3>144996996401332223 AND predictivesearch2.nbr3<144998095912960000) AND NOT(predictivesearch2.nbr4>144996996401332223 AND predictivesearch2.nbr4<144998095912960000))) UNION SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 JOIN predictivesearch3 ON predictivesearch2.contact_id = predictivesearch3.contact_id WHERE(NOT(NOT(predictivesearch3.nbr>225742931321946111 AND predictivesearch3.nbr<226024406298656768) AND NOT(predictivesearch3.nbr2>225742931321946111 AND predictivesearch3.nbr2<226024406298656768) AND NOT(predictivesearch3.nbr3>225742931321946111 AND predictivesearch3.nbr3<226024406298656768) AND NOT(predictivesearch3.nbr4>225742931321946111 AND predictivesearch3.nbr4<226024406298656768)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    result = mCntSqlSearch->CreateQuery(pattern);
-    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-    
-    TEST_PASSED_LOG("testCreateQuery");
-}
-
-void UT_CntSqlSearch::testExactMatchSearch()
-{
-    TEST_BEGIN_LOG("testExactMatchSearch");
-
-    QString pattern("120");
-#if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch1 WHERE (NOT(NOT(nbr>81064793292668927 AND nbr<81346268269379584) AND NOT(nbr2>81064793292668927 AND nbr2<81346268269379584) AND NOT(nbr3>81064793292668927 AND nbr3<81346268269379584) AND NOT(nbr4>81064793292668927 AND nbr4<81346268269379584)))");
-#else // #if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch1 WHERE (nbr>81064793292668927 AND nbr<81346268269379584) OR (nbr2>81064793292668927 AND nbr2<81346268269379584) OR (nbr3>81064793292668927 AND nbr3<81346268269379584) OR (nbr4>81064793292668927 AND nbr4<81346268269379584)");
-#endif // #if defined(USE_DEMORGAN)
-    QString result = mCntSqlSearch->ExactMatchSearch(pattern);
-//    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(result == reference);
-    
-
-    pattern = QString("5");
-#if defined(USE_DEMORGAN)
-    reference = "SELECT contact_id FROM predictivesearch5 WHERE (NOT(NOT(nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616)))";
-#else // #if defined(USE_DEMORGAN)
-    reference = "SELECT contact_id FROM predictivesearch5 WHERE (nbr>360287970189639679 AND nbr<432345564227567616) OR (nbr2>360287970189639679 AND nbr2<432345564227567616) OR (nbr3>360287970189639679 AND nbr3<432345564227567616) OR (nbr4>360287970189639679 AND nbr4<432345564227567616)";
-#endif // #if defined(USE_DEMORGAN)
-    result = mCntSqlSearch->ExactMatchSearch(pattern);
-//    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(result == reference);
-
-    
-    pattern = QString("25");
-#if defined(USE_DEMORGAN)
-    reference = "SELECT contact_id FROM predictivesearch2 WHERE (NOT(NOT(nbr>166633186212708351 AND nbr<171136785840078848) AND NOT(nbr2>166633186212708351 AND nbr2<171136785840078848) AND NOT(nbr3>166633186212708351 AND nbr3<171136785840078848) AND NOT(nbr4>166633186212708351 AND nbr4<171136785840078848)))";
-#else // #if defined(USE_DEMORGAN)
-    reference = "SELECT contact_id FROM predictivesearch2 WHERE (nbr>166633186212708351 AND nbr<171136785840078848) OR (nbr2>166633186212708351 AND nbr2<171136785840078848) OR (nbr3>166633186212708351 AND nbr3<171136785840078848) OR (nbr4>166633186212708351 AND nbr4<171136785840078848)";
-#endif // #if defined(USE_DEMORGAN)
-    result = mCntSqlSearch->ExactMatchSearch(pattern);
-//    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(result == reference);
-    
-    TEST_PASSED_LOG("testExactMatchSearch");
-}
-
-void UT_CntSqlSearch::testIntersectionSearch()
-{
-    TEST_BEGIN_LOG("testIntersectionSearch");
-
-    QString pattern("205");
-    QStringList tokens;
-    tokens << "2" << "5";
-#if defined(SEARCH_FROM_ONE_TABLE)
-#if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch2 WHERE NOT(NOT(NOT(NOT(nbr>145522562959409151 AND nbr<145804037936119808) AND NOT(nbr2>145522562959409151 AND nbr2<145804037936119808) AND NOT(nbr3>145522562959409151 AND nbr3<145804037936119808) AND NOT(nbr4>145522562959409151 AND nbr4<145804037936119808))) AND NOT(NOT(NOT(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) AND NOT(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>144115188075855871 AND nbr3<216172782113783808))) AND NOT(NOT(NOT(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) AND NOT(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>360287970189639679 AND nbr3<432345564227567616)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM predictivesearch2 WHERE \
-((nbr>145522562959409151 AND nbr<145804037936119808) OR (nbr2>145522562959409151 AND nbr2<145804037936119808) OR \
-(nbr3>145522562959409151 AND nbr3<145804037936119808) OR (nbr4>145522562959409151 AND nbr4<145804037936119808)) OR \
-(nbr2>360287970189639679 AND nbr2<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr3>360287970189639679 AND nbr3<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr>144115188075855871 AND nbr<216172782113783808) OR \
-(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr2>144115188075855871 AND nbr2<216172782113783808) OR \
-(nbr4>360287970189639679 AND nbr4<432345564227567616 AND nbr3>144115188075855871 AND nbr3<216172782113783808) OR \
-(nbr2>144115188075855871 AND nbr2<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) OR \
-(nbr3>144115188075855871 AND nbr3<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr>360287970189639679 AND nbr<432345564227567616) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr2>360287970189639679 AND nbr2<432345564227567616) OR \
-(nbr4>144115188075855871 AND nbr4<216172782113783808 AND nbr3>360287970189639679 AND nbr3<432345564227567616) \
-ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#endif // #if defined(USE_DEMORGAN)
-#else // #if defined(SEARCH_FROM_ONE_TABLE)
-    QString reference("SELECT predictivesearch2.contact_id FROM predictivesearch2 WHERE EXISTS (SELECT contact_id FROM predictivesearch5 WHERE predictivesearch2.contact_id = predictivesearch5.contact_id) OR (SELECT contact_id FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>145522562959409151 AND predictivesearch2.nbr<145804037936119808) AND NOT(predictivesearch2.nbr2>145522562959409151 AND predictivesearch2.nbr2<145804037936119808) AND NOT(predictivesearch2.nbr3>145522562959409151 AND predictivesearch2.nbr3<145804037936119808) AND NOT(predictivesearch2.nbr4>145522562959409151 AND predictivesearch2.nbr4<145804037936119808)))) ORDER BY predictivesearch2.first_name, predictivesearch2.last_name ASC;");
-#endif // #if defined(SEARCH_FROM_ONE_TABLE)
-    QString result = mCntSqlSearch->IntersectionSearch(pattern, tokens);
-//    qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY( !result.compare( reference) );
-    
-    TEST_PASSED_LOG("testIntersectionSearch");
-}
-
-void UT_CntSqlSearch::testExactMatch()
-{
-    TEST_BEGIN_LOG("testExactMatch");
-
-    QString pattern("25");
-#if defined(USE_DEMORGAN)
-    QString reference("(NOT(NOT(nbr>166633186212708351 AND nbr<171136785840078848) AND NOT(nbr2>166633186212708351 AND nbr2<171136785840078848) AND NOT(nbr3>166633186212708351 AND nbr3<171136785840078848) AND NOT(nbr4>166633186212708351 AND nbr4<171136785840078848)))");
-#else // #if defined(USE_DEMORGAN)
-    QString reference("(nbr>166633186212708351 AND nbr<171136785840078848) OR (nbr2>166633186212708351 AND nbr2<171136785840078848) OR (nbr3>166633186212708351 AND nbr3<171136785840078848) OR (nbr4>166633186212708351 AND nbr4<171136785840078848)");
-#endif // #if defined(USE_DEMORGAN)
-    QString result = mCntSqlSearch->ExactMatch(pattern);
-//    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    TEST_PASSED_LOG("testExactMatch");
-}
-
-void UT_CntSqlSearch::testCreateJoinTableSearch()
-{
-    TEST_BEGIN_LOG("testCreateJoinTableSearch");
-    
-    QString pattern("5606");
-    QStringList tokens;
-    tokens << "56" << "6";
-#if defined(USE_DEMORGAN)
-    QString reference("SELECT contact_id FROM (SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 WHERE (NOT(NOT(predictivesearch5.nbr>387415121070129151 AND predictivesearch5.nbr<387432713256173568) AND NOT(predictivesearch5.nbr2>387415121070129151 AND predictivesearch5.nbr2<387432713256173568) AND NOT(predictivesearch5.nbr3>387415121070129151 AND predictivesearch5.nbr3<387432713256173568) AND NOT(predictivesearch5.nbr4>387415121070129151 AND predictivesearch5.nbr4<387432713256173568))) UNION SELECT predictivesearch5.contact_id, predictivesearch5.first_name, predictivesearch5.last_name FROM predictivesearch5 JOIN predictivesearch6 ON predictivesearch5.contact_id = predictivesearch6.contact_id WHERE(NOT(NOT(predictivesearch5.nbr>387309567953862655 AND predictivesearch5.nbr<391813167581233152) AND NOT(predictivesearch5.nbr2>387309567953862655 AND predictivesearch5.nbr2<391813167581233152) AND NOT(predictivesearch5.nbr3>387309567953862655 AND predictivesearch5.nbr3<391813167581233152) AND NOT(predictivesearch5.nbr4>387309567953862655 AND predictivesearch5.nbr4<391813167581233152)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    // TODO: add non-De Morgan cases
-#endif // #if defined(USE_DEMORGAN)
-    QString result = mCntSqlSearch->CreateJoinTableSearch(pattern, tokens);
-    //qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern = QString ("250052");
-    tokens.clear();
-    tokens << "25" << "52";
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>166638821209800703 AND predictivesearch2.nbr<166638889929277440) AND NOT(predictivesearch2.nbr2>166638821209800703 AND predictivesearch2.nbr2<166638889929277440) AND NOT(predictivesearch2.nbr3>166638821209800703 AND predictivesearch2.nbr3<166638889929277440) AND NOT(predictivesearch2.nbr4>166638821209800703 AND predictivesearch2.nbr4<166638889929277440))) UNION SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 JOIN predictivesearch5 ON predictivesearch2.contact_id = predictivesearch5.contact_id WHERE((NOT(NOT(predictivesearch2.nbr>166633186212708351 AND predictivesearch2.nbr<171136785840078848) AND NOT(predictivesearch2.nbr2>166633186212708351 AND predictivesearch2.nbr2<171136785840078848) AND NOT(predictivesearch2.nbr3>166633186212708351 AND predictivesearch2.nbr3<171136785840078848) AND NOT(predictivesearch2.nbr4>166633186212708351 AND predictivesearch2.nbr4<171136785840078848))) AND (NOT(NOT(predictivesearch5.nbr>369295169444380671 AND predictivesearch5.nbr<373798769071751168) AND NOT(predictivesearch5.nbr2>369295169444380671 AND predictivesearch5.nbr2<373798769071751168) AND NOT(predictivesearch5.nbr3>369295169444380671 AND predictivesearch5.nbr3<373798769071751168) AND NOT(predictivesearch5.nbr4>369295169444380671 AND predictivesearch5.nbr4<373798769071751168))))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    // TODO: add non-De Morgan cases
-#endif // #if defined(USE_DEMORGAN)
-    result = mCntSqlSearch->CreateJoinTableSearch(pattern, tokens);
-    //qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    pattern.clear();
-    pattern = "2505";
-    tokens.clear();
-    tokens << "25" << "5";
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>166721147142930431 AND predictivesearch2.nbr<166738739328974848) AND NOT(predictivesearch2.nbr2>166721147142930431 AND predictivesearch2.nbr2<166738739328974848) AND NOT(predictivesearch2.nbr3>166721147142930431 AND predictivesearch2.nbr3<166738739328974848) AND NOT(predictivesearch2.nbr4>166721147142930431 AND predictivesearch2.nbr4<166738739328974848))) UNION SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 JOIN predictivesearch5 ON predictivesearch2.contact_id = predictivesearch5.contact_id WHERE(NOT(NOT(predictivesearch2.nbr>166633186212708351 AND predictivesearch2.nbr<171136785840078848) AND NOT(predictivesearch2.nbr2>166633186212708351 AND predictivesearch2.nbr2<171136785840078848) AND NOT(predictivesearch2.nbr3>166633186212708351 AND predictivesearch2.nbr3<171136785840078848) AND NOT(predictivesearch2.nbr4>166633186212708351 AND predictivesearch2.nbr4<171136785840078848)))) AS PR ORDER BY PR.first_name, PR.last_name ASC;");
-#else // #if defined(USE_DEMORGAN)
-    // TODO: add non-De Morgan cases
-#endif // #if defined(USE_DEMORGAN)
-    result = mCntSqlSearch->CreateJoinTableSearch(pattern, tokens);
-    //qDebug() << pattern << " -> result" << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(reference));
-
-    // TODO: Test this case on HW and verify leading zeros.
-    pattern.clear();
-    pattern = "0705";
-    tokens.clear();
-    tokens << "7" << "5";
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>145557747331497983 AND predictivesearch2.nbr<145575339517542400) AND NOT(predictivesearch2.nbr2>145557747331497983 AND predictivesearch2.nbr2<145575339517542400) AND NOT(predictivesearch2.nbr3>145557747331497983 AND predictivesearch2.nbr3<145575339517542400) AND NOT(predictivesearch2.nbr4>145557747331497983 AND predictivesearch2.nbr4<145575339517542400))) UNION SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 JOIN predictivesearch5 ON predictivesearch2.contact_id = predictivesearch5.contact_id WHERE(NOT(NOT(predictivesearch5.nbr>369295169444380671 AND predictivesearch5.nbr<373798769071751168) AND NOT(predictivesearch5.nbr2>369295169444380671 AND predictivesearch5.nbr2<373798769071751168) AND NOT(predictivesearch5.nbr3>369295169444380671 AND predictivesearch5.nbr3<373798769071751168) AND NOT(predictivesearch5.nbr4>369295169444380671 AND predictivesearch5.nbr4<373798769071751168)))) AS PR ORDER BY PR.first_name, PR.last_name ASC");
-#else // #if defined(USE_DEMORGAN)
-    // TODO: add non-De Morgan cases
-#endif // #if defined(USE_DEMORGAN)
-    result = mCntSqlSearch->CreateJoinTableSearch(pattern, tokens);
-    //qDebug() << pattern << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(result));
-
-    pattern.clear();
-    pattern = "2052";
-    tokens.clear();
-    tokens << "2" << "52";
-#if defined(USE_DEMORGAN)
-    reference = QString("SELECT contact_id FROM (SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 WHERE (NOT(NOT(predictivesearch2.nbr>145557747331497983 AND predictivesearch2.nbr<145575339517542400) AND NOT(predictivesearch2.nbr2>145557747331497983 AND predictivesearch2.nbr2<145575339517542400) AND NOT(predictivesearch2.nbr3>145557747331497983 AND predictivesearch2.nbr3<145575339517542400) AND NOT(predictivesearch2.nbr4>145557747331497983 AND predictivesearch2.nbr4<145575339517542400))) UNION SELECT predictivesearch2.contact_id, predictivesearch2.first_name, predictivesearch2.last_name FROM predictivesearch2 JOIN predictivesearch5 ON predictivesearch2.contact_id = predictivesearch5.contact_id WHERE(NOT(NOT(predictivesearch5.nbr>369295169444380671 AND predictivesearch5.nbr<373798769071751168) AND NOT(predictivesearch5.nbr2>369295169444380671 AND predictivesearch5.nbr2<373798769071751168) AND NOT(predictivesearch5.nbr3>369295169444380671 AND predictivesearch5.nbr3<373798769071751168) AND NOT(predictivesearch5.nbr4>369295169444380671 AND predictivesearch5.nbr4<373798769071751168)))) AS PR ORDER BY PR.first_name, PR.last_name ASC");
-#else // #if defined(USE_DEMORGAN)
-    // TODO: add non-De Morgan cases
-#endif // #if defined(USE_DEMORGAN)
-    result = mCntSqlSearch->CreateJoinTableSearch(pattern, tokens);
-    //qDebug() << "pattern " << result;
-    LOG2(pattern, result);
-    QVERIFY(!result.compare(result));
-    
-    TEST_PASSED_LOG("testCreateJoinTableSearch");
-}
-
-void UT_CntSqlSearch::testUpperLimit()
-{
-    TEST_BEGIN_LOG("testUpperLimit");
-    
-    QString pattern("234");
-    QString result;
-    QString reference("159033361841520640"); 
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    pattern = QString("234456576687687");
-    reference = QString("158828188945381000");
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    // Same result as above case, characters beyond 15th are ignored
-    pattern = QString("2344565766876874906754968");
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-
-    pattern = QString("004456");
-    reference = QString("1202247245496320");
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    pattern = QString("");
-    reference = QString("1152921504606846976");
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    
-    pattern = QString("000000000000000");
-    reference = QString("1");
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    pattern = QString("0000000000000");
-    reference = QString("256");
-    result = mCntSqlSearch->UpperLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    TEST_PASSED_LOG("testUpperLimit");
-}
-
-void UT_CntSqlSearch::testLowerLimit()
-{
-    TEST_BEGIN_LOG("testLowerLimit");
-    
-    QString pattern("234");
-    QString result;
-    QString reference("158751886864809983");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    pattern = QString("234456576687687");
-    reference = QString("158828188945380998");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    // Same result as above case, characters beyond 15th are ignored
-    pattern = QString("23445657668768749067549685");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-
-    pattern = QString("001021");
-    reference = QString("283742719442943");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-
-    pattern = QString("1021500");
-    reference = QString("72643633735532543");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    pattern = QString("");
-    reference = QString("-1");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-        
-    // Lower limit for this is -1
-    pattern = QString("000000000000000");
-    reference = QString("-1"); // Lower limit is now zero minus one
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    // Lower limit for this is -1
-    pattern = QString("00");
-    reference = QString("-1");
-    result = mCntSqlSearch->LowerLimit(pattern);
-    qDebug() << pattern << " -> result" << result;
-    QVERIFY( result == reference );
-    
-    TEST_PASSED_LOG("testLowerLimit");
-}
-
-void UT_CntSqlSearch::testGetTokens()
-    {
-    TEST_BEGIN_LOG("testGetTokens");
-    
-    QStringList tokens = mCntSqlSearch->GetTokens("");
-    QVERIFY(tokens.count() == 0);
-        
-    tokens = mCntSqlSearch->GetTokens("0");
-    QVERIFY(tokens.count() == 0);
-    
-    tokens = mCntSqlSearch->GetTokens("00");
-    QVERIFY(tokens.count() == 0);
-
-    tokens = mCntSqlSearch->GetTokens("000000000000000000000000");
-    QVERIFY(tokens.count() == 0);
-        
-    tokens = mCntSqlSearch->GetTokens("1");
-    QVERIFY(tokens.count() == 1);
-    QVERIFY(tokens.at(0) == "1");
-    
-    tokens = mCntSqlSearch->GetTokens("01");
-    QVERIFY(tokens.count() == 1);
-    QVERIFY(tokens.at(0) == "1");
-    
-    tokens = mCntSqlSearch->GetTokens("1");
-    QVERIFY(tokens.count() == 1);
-    QVERIFY(tokens.at(0) == "1");
-    
-    tokens = mCntSqlSearch->GetTokens("000028");
-    QVERIFY(tokens.count() == 1);
-    QVERIFY(tokens.at(0) == "28");
-    
-    tokens = mCntSqlSearch->GetTokens("000019700");
-    QVERIFY(tokens.count() == 1);
-    QVERIFY(tokens.at(0) == "197");
-
-    tokens = mCntSqlSearch->GetTokens("101");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "1");
-    QVERIFY(tokens.at(1) == "1");
-    
-    tokens = mCntSqlSearch->GetTokens("1203");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "12");
-    QVERIFY(tokens.at(1) == "3");
-    
-    tokens = mCntSqlSearch->GetTokens("000012013");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "000012");
-    QVERIFY(tokens.at(1) == "13");
-    
-    tokens = mCntSqlSearch->GetTokens("00206");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "002");
-    QVERIFY(tokens.at(1) == "6");
-    
-    tokens = mCntSqlSearch->GetTokens("001230045067800900");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "00123");
-    QVERIFY(tokens.at(1) == "45067800900");
-    
-    tokens = mCntSqlSearch->GetTokens("1000002030405060708090011");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "1");
-    QVERIFY(tokens.at(1) == "2030405060708090011");
-    
-    tokens = mCntSqlSearch->GetTokens("4304");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "43");
-    QVERIFY(tokens.at(1) == "4");
-    
-    tokens = mCntSqlSearch->GetTokens("010203040506070809011001200130014001500");
-    QVERIFY(tokens.count() == 2);
-    QVERIFY(tokens.at(0) == "01");
-    QVERIFY(tokens.at(1) == "203040506070809011001200130014001500");
-
-    TEST_PASSED_LOG("testGetTokens");
-    }
-
-#if defined(WRITE_LOGS)
-void WriteLog(const QString a, const QString b)
-    {
-    TPtrC16 ptr(reinterpret_cast<const TUint16*>(a.utf16()));
-    WritePart(ptr);
-    
-    if (b.size() > 0)
-        {
-        TPtrC16 ptr2(reinterpret_cast<const TUint16*>(b.utf16()));
-        WritePart(ptr2);
-        }
-    }
-
-void WritePart(const TDesC& s)
-    {
-    // RDebug::Print() only writes first 256 chars
-    const TInt KMaxLength = 255;
-        
-    TInt pos(0);
-    TInt len = s.Length();  
-    while (pos < len)
-        {
-        TInt partLength = KMaxLength;
-        if (pos + partLength > len)
-            {
-            partLength = len - pos;
-            }
-        TPtrC16 part = s.Mid(pos, partLength);
-        RDebug::Print(part);
-        pos += KMaxLength;
-        }
-    }
-#endif // #if defined(WRITE_LOGS)
-
-
-#ifdef SQL_QT_TEST
-QTEST_MAIN(UT_CntSqlSearch)
-#endif
-
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsqlsearch.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef UT_CNTSQLSEARCH_H
-#define UT_CNTSQLSEARCH_H
-
-#include <QObject>
-
-class CntSqlSearch;
-
-class UT_CntSqlSearch : public QObject                 
-{
-     Q_OBJECT
-    
-private slots:
-
-/*
- * In addition, there are four private slots that are not treated as testfunctions. 
- * They will be executed by the testing framework and can be used to initialize and clean up 
- * either the entire test or the current test function.
- * 
- * initTestCase() will be called before the first testfunction is executed.
- * cleanupTestCase() will be called after the last testfunction was executed.
- * init() will be called before each testfunction is executed.
- * cleanup() will be called after every testfunction.
-*/
-    void initTestCase();
-    void cleanupTestCase();
-    void init();
-    void cleanup();
-
-private slots: //test methods
-
-    void testPredictiveSearch();
-    void testSelectTableView();
-	void testCreateQuery();
-	void testExactMatchSearch();
-	void testIntersectionSearch();
-	void testExactMatch();
-	void testCreateJoinTableSearch();
-    void testUpperLimit();
-    void testLowerLimit();
-    void testGetTokens();
-    
-private:
- 
-    CntSqlSearch* mCntSqlSearch;  
-};
-
-#endif // UT_CNTSQLSEARCH_H
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsymbianengine.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_cntsymbianengine.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -462,7 +462,7 @@
 
     // Retrieve contacts with invalid filter
     cnt_ids = m_engine->contactIds(invalidFilter, s, &err);
-    QVERIFY(err == QContactManager::NotSupportedError);
+    QVERIFY(cnt_ids.count() == 0);
 
     // Retrieve sorted contacts
     QContactSortOrder sortOrder;
@@ -724,16 +724,8 @@
     contacts.insert(3, 0);
 
     QVERIFY(!m_engine->removeContacts(contacts, &errorMap, &err));
-    QVERIFY(err == QContactManager::DoesNotExistError);
-    foreach(QContactManager::Error e, errorMap) {
-        QVERIFY(e == QContactManager::DoesNotExistError);
-    }
-
-    for(int i=0; i<contacts.count(); i++) {
-        QContact f = m_engine->contact(contacts[i], hint, &err);
-        QVERIFY(f.localId() == 0);
-        QVERIFY(err == QContactManager::DoesNotExistError);
-    }
+    QVERIFY(err == QContactManager::BadArgumentError); //not allowed to delete
+                                                    //a contact with id = 0
 }
 
 void TestSymbianEngine::addOwnCard()
@@ -1040,7 +1032,7 @@
     orgContact.saveDetail(&org);
     label = m_engine->synthesizedDisplayLabel(orgContact, &err);
     QVERIFY(err == QContactManager::NoError);
-    QVERIFY(label == QString("Nokia"));
+    QVERIFY(label.isEmpty());
 
     QContact jargon;
     jargon.setType("jargon");
--- a/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_symbian.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/plugin/tsrc/ut_symbian/ut_symbian.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -26,7 +26,6 @@
                ut_cntrelationship.h \
                ut_cntsymbiandatabase.h \
                ut_transformcontactdata.h \
-               ut_cntsqlsearch.h \
                mt_cntsqlsort.h
     
     SOURCES += $$SYMBIAN_SOURCES \
@@ -38,7 +37,6 @@
                ut_cntrelationship.cpp \
                ut_cntsymbiandatabase.cpp \
                ut_transformcontactdata.cpp \
-               ut_cntsqlsearch.cpp \
                mt_cntsqlsort.cpp
 
     CONFIG += mobility
--- a/plugins/contacts/symbian/symbian.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbian/symbian.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -1,11 +1,54 @@
 TEMPLATE = subdirs
+CONFIG += ordered
 
 include(../../../common.pri)
 
-contains(build_symbiancntmodel, yes) {
-    message(Building Symbian CNTMODEL library.)
-    SUBDIRS += contactsmodel 
+
+## quick platform check.
+IS_SYMBIAN_4 = yes
+IS_SYMBIAN_3 = no
+#exists($${EPOCROOT}epoc32/data/z/system/install/Series60v5.2.sis) {
+#    exists($${EPOCROOT}epoc32/release/winscw/udeb/VPbkEng.dll) \
+#    | exists($${EPOCROOT}epoc32/release/armv5/urel/VPbkEng.dll) {
+#        message(Building Symbian contacts plugin on S^3)
+#    } else {
+#        message(Building Symbian contacts plugin on S^4 or later platform)
+#        IS_SYMBIAN_4 = yes
+#    }
+#}
+
+contains(IS_SYMBIAN_4, yes) {
+    message(Building Symbian^4 CNTMODEL library and plugin)
+    SUBDIRS += contactsmodel plugin
+} else {
+    SUBDIRS += plugin
 }
-SUBDIRS += plugin
+
 
-CONFIG += ordered
+#contains(symbiancntmodel_enabled, yes) {
+#    contains(symbiancntmodelv2_enabled, yes) {
+#        ##### Symbian^4 with in-source cntmodel already deployed
+#        ##message(Building Symbian CNTMODEL library.)
+#        ##SUBDIRS += contactsmodel plugin
+#
+#        ##TODO FIXME: we disabled building the symbian plugin on Symbian^4 temporarily
+#        message(In-source CNTMODEL deployed: building Symbian CNTMODEL and contacts plugin DISABLED!)
+#    } else {
+#
+#        contains(IS_SYMBIAN_4, yes) {
+#            ## the configure tests don't agree with the platform check.
+#            message(Configure test confusion; building Symbian CNTMODEL and contacts plugin DISABLED!)
+#        } else {
+#            ## this is symbian 3.1, 3.2, 5.0 or ^3
+#            message(Building Symbian contacts plugin)
+#            SUBDIRS += plugin
+#        }
+#    }
+#} else {
+#    ##### Symbian^4 without in-source cntmodel already deployed
+#    ##message(Building Symbian CNTMODEL library.)
+#    ##SUBDIRS += contactsmodel plugin
+#
+#    ##TODO FIXME: we disabled building the symbian plugin on Symbian^4 temporarily
+#    message(In-source CNTMODEL not deployed: building Symbian CNTMODEL and contacts plugin DISABLED!)
+#}
--- a/plugins/contacts/symbiansim/inc/cntsimstoreeventlistener.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbiansim/inc/cntsimstoreeventlistener.h	Mon Oct 04 01:37:06 2010 +0300
@@ -45,12 +45,12 @@
 #include <e32base.h>
 
 class CntSymbianSimEngine;
-class RMobilePhoneBookStore;
+class RMobilePhoneStore;
 
 class CntSimStoreEventListener : public CActive
 {
 public:
-    CntSimStoreEventListener(CntSymbianSimEngine &engine, RMobilePhoneBookStore& store);
+    CntSimStoreEventListener(CntSymbianSimEngine &engine, RMobilePhoneStore& store);
     ~CntSimStoreEventListener();
     
     void start();
@@ -61,7 +61,7 @@
     
 private:
     CntSymbianSimEngine &m_engine;
-    RMobilePhoneBookStore &m_store;
+    RMobilePhoneStore &m_store;
     TUint32 m_event;
     TInt m_index;
 };
--- a/plugins/contacts/symbiansim/inc/cntsimstoreprivate.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbiansim/inc/cntsimstoreprivate.h	Mon Oct 04 01:37:06 2010 +0300
@@ -106,6 +106,7 @@
     RTelServer m_etelServer;
     RMobilePhone m_etelPhone;
     RMobilePhoneBookStore m_etelStore;
+    RMobileONStore m_etelOnStore;
     SimStoreInfo m_storeInfo;
     RBuf8 m_buffer;
     QContact m_convertedContact;
--- a/plugins/contacts/symbiansim/inc/cntsymbiansimengine.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbiansim/inc/cntsymbiansimengine.h	Mon Oct 04 01:37:06 2010 +0300
@@ -86,10 +86,22 @@
 Q_DEFINE_LATIN1_CONSTANT(KParameterValueSimStoreNameAdn, "ADN");
 Q_DEFINE_LATIN1_CONSTANT(KParameterValueSimStoreNameSdn, "SDN");
 Q_DEFINE_LATIN1_CONSTANT(KParameterValueSimStoreNameFdn, "FDN");
+Q_DEFINE_LATIN1_CONSTANT(KParameterValueSimStoreNameOn, "ON");
 
 class CntSimStore;
 class CntAbstractSimRequest;
 
+class CntSymbianSimPhoneNumberMatching
+{
+public:
+    enum TNumberType { ENotInitialized, EUnknown, EDigit, EPlus, EOneZero, ETwoZeros };
+    static TBool isBestMatchL(const QString& numberToMatch, const QString& matchingNumber);
+    static TBool validateBestMatchingRulesL(const TDesC& phoneNumber, const TDesC& matchNumber);
+    static TBool checkBestMatchingRules(const TDesC& numberA, TNumberType numberAType,
+                                             const TDesC& numberB, TNumberType numberBType);
+    static TInt formatAndCheckNumberType(TDes& number);
+};
+
 class CntSymbianSimEngineData : public QSharedData
 {
 public:
--- a/plugins/contacts/symbiansim/src/cntsimstoreeventlistener.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbiansim/src/cntsimstoreeventlistener.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -51,7 +51,7 @@
 
 QTM_USE_NAMESPACE
 
-CntSimStoreEventListener::CntSimStoreEventListener(CntSymbianSimEngine &engine, RMobilePhoneBookStore& store)
+CntSimStoreEventListener::CntSimStoreEventListener(CntSymbianSimEngine &engine, RMobilePhoneStore& store)
     :CActive(CActive::EPriorityUserInput),
      m_engine(engine),
      m_store(store)
--- a/plugins/contacts/symbiansim/src/cntsimstoreprivate.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbiansim/src/cntsimstoreprivate.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -85,7 +85,8 @@
     m_storeInfo.m_emailSupported            = false;
     
     // SDN store is allways read only
-    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameSdn)
+    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameSdn ||
+        m_storeInfo.m_storeName == KParameterValueSimStoreNameOn)
         m_storeInfo.m_readOnlyAccess = true;
 }
 
@@ -104,13 +105,23 @@
     User::LeaveIfError(m_etelPhone.Open(m_etelServer, info.iName));
     
     // Open Etel store
-    User::LeaveIfError(m_etelStore.Open(m_etelPhone, storeName));
+    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) {
+        User::LeaveIfError(m_etelOnStore.Open(m_etelPhone));
+    }
+    else {
+        User::LeaveIfError(m_etelStore.Open(m_etelPhone, storeName));        
+    }
 
     // Update store info
     updateStoreInfoL();
     
     // Start listening for events
-    m_listener = new (ELeave) CntSimStoreEventListener(m_engine, m_etelStore);
+    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) {
+        m_listener = new (ELeave) CntSimStoreEventListener(m_engine, m_etelOnStore);
+    }
+    else {
+        m_listener = new (ELeave) CntSimStoreEventListener(m_engine, m_etelStore);
+    }
     m_listener->start();
 }
 
@@ -119,6 +130,7 @@
     Cancel();
     delete m_listener;
     m_etelStore.Close();
+    m_etelOnStore.Close();
     m_etelPhone.Close();
     m_etelServer.Close();
 }
@@ -139,6 +151,8 @@
         storeName.Copy(KETelIccAdnPhoneBook);
     } else if (m_storeInfo.m_storeName == KParameterValueSimStoreNameSdn) {
         storeName.Copy(KETelIccSdnPhoneBook);
+    } else if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) {
+        storeName.Copy(KETelOwnNumberStore);
     }
 
     // Check that we got a valid store name
@@ -154,10 +168,48 @@
         return false;
     }
     
+    // ON store requires different read approach.
+    // fetch ON contacts synchronously since there are usually only couple of them  
+    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) {
+
+        TRequestStatus status;
+        QList<QContact> fetchedContacts; 
+        for (int i = index; i <= numSlots; i++) {
+            RMobileONStore::TMobileONEntryV1 onEntry;
+            onEntry.iIndex = i;         
+            RMobileONStore::TMobileONEntryV1Pckg onEntryPkg(onEntry);
+            m_etelOnStore.Read(status, onEntryPkg);
+            User::WaitForRequest(status);
+            if (status.Int() == KErrNone) {
+                QContact c;
+                c.setType(QContactType::TypeContact);
+                QContactName name;
+                name.setCustomLabel(QString::fromUtf16(onEntry.iText.Ptr(),
+                        onEntry.iText.Length()));
+                c.saveDetail(&name);
+                
+                QContactPhoneNumber number;
+                number.setNumber(QString::fromUtf16(onEntry.iNumber.iTelNumber.Ptr(),
+                        onEntry.iNumber.iTelNumber.Length()));
+                c.saveDetail(&number);
+                
+                QScopedPointer<QContactId> contactId(new QContactId());
+                contactId->setLocalId(i);
+                contactId->setManagerUri(m_managerUri);
+                c.setId(*contactId);
+                fetchedContacts.append(c);
+            }
+        }
+        emit m_simStore.readComplete(fetchedContacts, QContactManager::NoError);
+        *error = QContactManager::NoError;
+        return true;
+    }        
+    
     // start reading
     m_buffer.Zero();
     m_buffer.ReAlloc(KOneSimContactBufferSize*numSlots);
     m_etelStore.Read(iStatus, index, numSlots, m_buffer);
+    
     SetActive();
     m_state = ReadState;
     
@@ -172,6 +224,11 @@
         return false;
     }
     
+    if (m_storeInfo.m_readOnlyAccess) {
+        *error = QContactManager::NotSupportedError;
+        return false;    
+    }
+    
     // get index
     m_writeIndex = KErrNotFound;
     if (contact.id().managerUri() == m_managerUri &&
@@ -208,6 +265,11 @@
         return false;
     }
     
+    if (m_storeInfo.m_readOnlyAccess) {
+        *error = QContactManager::NotSupportedError;
+        return false;    
+    }
+    
     // NOTE:
     // If index points to an empty slot and running in hardware the 
     // delete operation will not return any error.
@@ -227,6 +289,13 @@
         return false;
     }
     
+    // reserved slots are checked for sim contacts removing, 
+    // this operation is not supported for read only stores
+    if (m_storeInfo.m_readOnlyAccess) {
+        *error = QContactManager::NotSupportedError;
+        return false;    
+    }
+    
     // start reading
     m_buffer.Zero();
     m_buffer.ReAlloc(KOneSimContactBufferSize*m_storeInfo.m_totalEntries);
@@ -664,6 +733,10 @@
     if (IsActive())
         User::Leave(KErrLocked);
     
+    if (m_storeInfo.m_readOnlyAccess) {
+        User::Leave(KErrNotSupported);
+    }
+    
     // get index
     int index = KErrNotFound;
     if (contact->id().managerUri() == m_managerUri &&
@@ -694,6 +767,10 @@
     if (IsActive())
         User::Leave(KErrLocked);
     
+    if (m_storeInfo.m_readOnlyAccess) {
+        User::Leave(KErrNotSupported);
+    }
+    
     // NOTE:
     // If index points to an empty slot and running in hardware the 
     // delete operation will not return any error.
@@ -707,23 +784,41 @@
 void CntSimStorePrivate::updateStoreInfoL()
 {
 #ifdef SYMBIANSIM_BACKEND_PHONEBOOKINFOV1
+    TRequestStatus status;
     RMobilePhoneBookStore::TMobilePhoneBookInfoV1 info;
     RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg infoPckg(info);
-#else
-    RMobilePhoneBookStore::TMobilePhoneBookInfoV5 info;
-    RMobilePhoneBookStore::TMobilePhoneBookInfoV5Pckg infoPckg(info);
-#endif
-
-    // Get info
-    TRequestStatus status;
     m_etelStore.GetInfo(status, infoPckg);
     User::WaitForRequest(status);
     User::LeaveIfError(status.Int());
-
-    // Update entry counts
     m_storeInfo.m_totalEntries = info.iTotalEntries;
     m_storeInfo.m_usedEntries  = info.iUsedEntries;
-    
+#else
+    // Get info
+    TRequestStatus status;
+    if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) {
+        RMobileONStore::TMobileONStoreInfoV1 onInfo;
+        RMobileONStore::TMobileONStoreInfoV1Pckg onInfoPckg(onInfo);
+        m_etelOnStore.GetInfo(status, onInfoPckg);
+        User::WaitForRequest(status);
+        User::LeaveIfError(status.Int());
+
+        // Update entry counts
+        m_storeInfo.m_totalEntries = onInfo.iTotalEntries;
+        m_storeInfo.m_usedEntries  = onInfo.iUsedEntries;
+    }
+    else {
+        RMobilePhoneBookStore::TMobilePhoneBookInfoV5 info;
+        RMobilePhoneBookStore::TMobilePhoneBookInfoV5Pckg infoPckg(info);
+        m_etelStore.GetInfo(status, infoPckg);
+        User::WaitForRequest(status);
+        User::LeaveIfError(status.Int());
+
+        // Update entry counts
+        m_storeInfo.m_totalEntries = info.iTotalEntries;
+        m_storeInfo.m_usedEntries  = info.iUsedEntries;
+    }
+#endif
+
 #ifdef SYMBIANSIM_BACKEND_TEST_EXTRADETAILS
     // Check if store supports the extra details
     //
@@ -734,7 +829,7 @@
     //
     // There is an API for checking these but it's Nokia internal so we must
     // do it this way - by checking if saving these details is possible.
-    
+
     // Have we checked these already?
     if (m_extraDetailsChecked == false)
     {
--- a/plugins/contacts/symbiansim/src/cntsymbiansimengine.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/contacts/symbiansim/src/cntsymbiansimengine.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -529,12 +529,26 @@
             f.detailFieldName() == QContactPhoneNumber::FieldNumber &&
             f.matchFlags() == QContactFilter::MatchPhoneNumber) 
         {
-            QString matchNumber = f.value().toString().right(d->m_phoneNumberMatchLen);
             QList<QContactPhoneNumber> pns = contact.details<QContactPhoneNumber>();
             foreach (QContactPhoneNumber pn, pns) {
-                QString number = pn.number().right(d->m_phoneNumberMatchLen);
-                if (number == matchNumber)
-                    return true;
+                // Best matching enabled
+                if(d->m_phoneNumberMatchLen == 0) {
+                    bool bestMatchFound(false);
+                    QString matchingNumber = f.value().toString();
+                    QString numberToMatch = pn.number();
+                    TRAP_IGNORE(
+                            bestMatchFound = CntSymbianSimPhoneNumberMatching::isBestMatchL(numberToMatch,matchingNumber);
+                    )
+                    if (bestMatchFound)
+                        return true;
+                }
+                else {
+                    // Default matching
+                    QString matchNumber = f.value().toString().right(d->m_phoneNumberMatchLen);
+                    QString number = pn.number().right(d->m_phoneNumberMatchLen);
+                    if (number == matchNumber)
+                        return true;
+                }
             }
             return false;
         }
@@ -543,6 +557,21 @@
 }
 
 /*!
+  Returns whether the supplied \a phonenumber is the best matching number.
+ */
+TBool CntSymbianSimPhoneNumberMatching::isBestMatchL(const QString& numberToMatch, const QString& matchingNumber)
+{
+    bool bestMatchFound(false);
+    TPtrC numberPtr(reinterpret_cast<const TUint16*>(numberToMatch.utf16()));
+    TPtrC matchNumberPtr(reinterpret_cast<const TUint16*>(matchingNumber.utf16()));
+    
+    if (CntSymbianSimPhoneNumberMatching::validateBestMatchingRulesL(numberPtr,matchNumberPtr)) {
+        bestMatchFound = true;
+    }
+    return bestMatchFound;
+}
+
+/*!
  * Executes an asynchronous request so that it will appear synchronous. This is
  * used internally in all synchronous functions. This way we only need to 
  * implement the matching asynchronous request.
@@ -593,6 +622,197 @@
     CleanupStack::PopAndDestroy(repository);
 }
 
+/*!
+  Validates the supplied \a phonenumber against best matching rules.
+ */
+TBool CntSymbianSimPhoneNumberMatching::validateBestMatchingRulesL(const TDesC& phoneNumber, const TDesC& matchNumber)
+    {
+    RBuf numberA;
+    numberA.CleanupClosePushL();
+    numberA.CreateL(matchNumber);
+    TNumberType numberAType = (TNumberType) CntSymbianSimPhoneNumberMatching::formatAndCheckNumberType(numberA);
+    RBuf numberB;
+    numberB.CleanupClosePushL();
+    numberB.CreateL(phoneNumber);
+    TNumberType numberBType = (TNumberType) CntSymbianSimPhoneNumberMatching::formatAndCheckNumberType(numberB);
+
+    TBool match = (!numberB.Compare(numberA) ||
+                    CntSymbianSimPhoneNumberMatching::checkBestMatchingRules(numberA, numberAType, numberB, numberBType) ||
+                    CntSymbianSimPhoneNumberMatching::checkBestMatchingRules(numberB, numberBType, numberA, numberAType));
+    
+    // cleanup
+    CleanupStack::PopAndDestroy(2);
+    return match;
+    }
+
+/*!
+  Removes non-digit chars except plus form the beginning.
+  Checks if number matches to one of defined types.
+ */
+TInt CntSymbianSimPhoneNumberMatching::formatAndCheckNumberType(TDes& number)
+    {
+    _LIT( KOneZeroPattern, "0*" );
+    _LIT( KTwoZerosPattern, "00*" );
+    _LIT( KPlusPattern, "+*" );
+    const TChar KPlus = TChar('+');
+    const TChar KZero = TChar('0');
+    const TChar KAsterisk = TChar('*');
+    const TChar KHash = TChar('#');
+    
+    for( TInt pos = 0; pos < number.Length(); ++pos ) {
+        TChar chr = number[pos];
+        if ( !chr.IsDigit() && !( pos == 0 && chr == KPlus  )
+                && !( chr == KAsterisk ) && !( chr == KHash ) ) {
+            number.Delete( pos, 1 );
+            --pos;
+        }
+    }
+    
+    TInt format;
+    
+    if (!number.Match(KTwoZerosPattern) && number.Length() > 2 && number[2] != KZero) {
+        format = ETwoZeros;
+    }
+    else if (!number.Match(KOneZeroPattern)&& number.Length() > 1 && number[1] != KZero) {
+        format = EOneZero;
+    }
+    else if (!number.Match(KPlusPattern) && number.Length() > 1 && number[1] != KZero) {
+        format = EPlus;
+    }
+    else if (number.Length() > 0 && number[0] != KZero && ( ( TChar ) number[0] ).IsDigit()) {
+        format = EDigit;
+    }
+    else {
+        format = EUnknown;
+    }
+
+    return format;
+    }
+
+TBool CntSymbianSimPhoneNumberMatching::checkBestMatchingRules(
+        const TDesC& numberA, TNumberType numberAType,
+        const TDesC& numberB, TNumberType numberBType  )
+    {
+    TBool result = EFalse;
+    
+    // Rules for matching not identical numbers
+    // Rules details are presented in Best_Number_Matching_Algorithm_Description.doc
+    
+    // rule International-International 1
+    if (!result && numberAType == EPlus && numberBType == ETwoZeros) {
+        TPtrC numberAPtr = numberA.Right(numberA.Length() - 1);
+        TPtrC numberBPtr = numberB.Right(numberB.Length() - 2);
+        result = !(numberAPtr.Compare(numberBPtr));
+        if (result) {
+            return result;
+        }
+    }
+
+    // rule International-International 2
+    if (numberAType == EPlus && numberBType == EDigit) {
+        TPtrC numberAPtr = numberA.Right( numberA.Length() - 1 );
+        if (numberAPtr.Length() < numberB.Length()) {
+            TPtrC numberBPtr = numberB.Right( numberAPtr.Length() );
+            result = !(numberAPtr.Compare(numberBPtr));
+            if (result) {
+                return result;
+            }
+        }
+    }
+
+    // rule International-International 3
+    if (numberAType == ETwoZeros && numberBType == EDigit) {
+        TPtrC numberAPtr = numberA.Right(numberA.Length() - 2);
+        if (numberAPtr.Length() < numberB.Length()) {
+            TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
+            result = !(numberAPtr.Compare(numberBPtr));
+            if (result) {
+                return result;
+            }
+        }
+    }
+
+    // rule International-Operator 1
+    if (numberAType == EOneZero && numberBType == EPlus
+            || numberAType == EDigit && numberBType == EPlus) {
+        TPtrC numberAPtr;
+        if (numberAType == EOneZero) {
+            numberAPtr.Set(numberA.Right(numberA.Length() - 1));
+        }
+        else {
+            numberAPtr.Set(numberA);
+        }
+        if (numberAPtr.Length() < numberB.Length() - 1) {
+            TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
+            result = !(numberAPtr.Compare(numberBPtr));
+            if (result) {
+                return result;
+            }
+        }
+    }
+
+    // rule International-Operator 2
+    if (numberAType == EOneZero && numberBType == ETwoZeros
+            || numberAType == EDigit && numberBType == ETwoZeros) {
+        TPtrC numberAPtr;
+        if (numberAType == EOneZero) {
+            numberAPtr.Set(numberA.Right(numberA.Length() - 1));
+        }
+        else {
+            numberAPtr.Set(numberA);
+        }
+        if (numberAPtr.Length() < numberB.Length() - 2) {
+            TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
+            result = !(numberAPtr.Compare(numberBPtr));
+            if (result) {
+                return result;
+            }
+        }
+    }
+
+    // rule International-Operator 3
+    if (numberAType == EOneZero && numberBType == EDigit
+            || numberAType == EDigit && numberBType == EDigit) {
+        TPtrC numberAPtr;
+        if (numberAType == EOneZero) {
+            numberAPtr.Set(numberA.Right( numberA.Length() - 1));
+        }
+        else {
+            numberAPtr.Set(numberA);
+        }
+        if (numberAPtr.Length() < numberB.Length()) {
+            TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
+            result = !(numberAPtr.Compare(numberBPtr));
+            if (result) {
+                return result;
+            }
+        }
+    }
+
+    // rule Operator-Operator 1
+    if (numberAType == EOneZero && numberBType == EDigit) {
+        TPtrC numberAPtr = numberA.Right(numberA.Length() - 1);
+        result = !(numberAPtr.Compare(numberB));
+        if (result) {
+            return result;
+        }
+    }
+    
+    // rule North America Numbering Plan 1
+    if (numberAType == EDigit && numberBType == EPlus) {
+        TPtrC numberBPtr = numberB.Right(numberB.Length() - 1);
+        result = !(numberA.Compare(numberBPtr));
+        if (result) {
+            return result;
+        }
+    }
+
+    // More exceptional acceptance rules can be added here
+    // Keep rules updated in the document Best_Number_Matching_Algorithm_Description.doc
+
+    return result;
+    }
+
 QContactManagerEngine* CntSymbianSimFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
 {
     CntSymbianSimEngine *engine = new CntSymbianSimEngine(parameters, error);
--- a/plugins/declarative/contacts/contacts.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/declarative/contacts/contacts.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -17,7 +17,7 @@
 
 include(../../../common.pri)
 
-QT += declarative
+QT += declarative script network
 
 
 CONFIG += mobility
@@ -47,3 +47,16 @@
 # SOURCES += imageprovider.cpp
 
 INSTALLS += target qmldir
+
+symbian {
+    # In Symbian, a library should enjoy _largest_ possible capability set.
+    TARGET.CAPABILITY = ALL -TCB
+    # Allow writable DLL data
+    TARGET.EPOCALLOWDLLDATA = 1
+    # Target UID, makes every Symbian app unique
+    TARGET.UID3 = 0x20021325
+    # Specifies what files shall be deployed: the plugin itself and the qmldir file.
+    importFiles.sources = $$DESTDIR/declarative_contacts$${QT_LIBINFIX}.dll qmldir 
+    importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+    DEPLOYMENT = importFiles
+ }
--- a/plugins/declarative/multimedia/multimedia.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/declarative/multimedia/multimedia.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -36,6 +36,12 @@
 INSTALLS += target qmldir
 
 symbian {
+    # In Symbian, a library should enjoy _largest_ possible capability set.
+    TARGET.CAPABILITY = ALL -TCB
     TARGET.UID3 = 0x20021313
     TARGET.EPOCALLOWDLLDATA=1
+    # Specifies what files shall be deployed: the plugin itself and the qmldir file.
+    importFiles.sources = $$DESTDIR/declarative_multimedia$${QT_LIBINFIX}.dll qmldir 
+    importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+    DEPLOYMENT = importFiles
 }
--- a/plugins/declarative/publishsubscribe/publishsubscribe.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/declarative/publishsubscribe/publishsubscribe.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -23,3 +23,15 @@
 
 INSTALLS += target qmldir
 
+symbian {
+    # In Symbian, a library should enjoy _largest_ possible capability set.
+    TARGET.CAPABILITY = ALL -TCB
+    # Allow writable DLL data
+    TARGET.EPOCALLOWDLLDATA = 1
+    # Target UID, makes every Symbian app unique
+    TARGET.UID3 = 0x20021322
+    # Specifies what files shall be deployed: the plugin itself and the qmldir file.
+    importFiles.sources = $$DESTDIR/declarative_publishsubscribe$${QT_LIBINFIX}.dll qmldir 
+    importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+    DEPLOYMENT = importFiles
+ }
\ No newline at end of file
--- a/plugins/declarative/sensors/sensors.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/declarative/sensors/sensors.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -23,6 +23,14 @@
 INSTALLS += target qmldir
 
 symbian {
-    TARGET.EPOCALLOWDLLDATA=1
-}
-
+    # In Symbian, a library should enjoy _largest_ possible capability set.
+    TARGET.CAPABILITY = ALL -TCB
+    # Allow writable DLL data
+    TARGET.EPOCALLOWDLLDATA = 1
+    # Target UID, makes every Symbian app unique
+    TARGET.UID3 = 0x20021324
+    # Specifies what files shall be deployed: the plugin itself and the qmldir file.
+    importFiles.sources = $$DESTDIR/declarative_sensors$${QT_LIBINFIX}.dll qmldir 
+    importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+    DEPLOYMENT = importFiles
+ }
--- a/plugins/declarative/serviceframework/qdeclarativeservice.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/declarative/serviceframework/qdeclarativeservice.h	Mon Oct 04 01:37:06 2010 +0300
@@ -54,11 +54,11 @@
 
 class QDeclarativeService : public QObject {
     Q_OBJECT
-    Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName);
-    Q_PROPERTY(QString serviceName READ serviceName);
-    Q_PROPERTY(QString versionNumber READ versionNumber);
-    Q_PROPERTY(bool valid READ isValid NOTIFY validChanged);
-    Q_PROPERTY(QObject* serviceObject READ serviceObject NOTIFY serviceObjectChanged);
+    Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName)
+    Q_PROPERTY(QString serviceName READ serviceName)
+    Q_PROPERTY(QString versionNumber READ versionNumber)
+    Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
+    Q_PROPERTY(QObject* serviceObject READ serviceObject NOTIFY serviceObjectChanged)
 
 public:
     QDeclarativeService();
@@ -90,9 +90,9 @@
 
 class QDeclarativeServiceList : public QObject {
     Q_OBJECT
-    Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName);
-    Q_PROPERTY(QString minVersion READ minVersion WRITE setMinVersion);
-    Q_PROPERTY(QDeclarativeListProperty<QDeclarativeService> services READ services NOTIFY servicesChanged);
+    Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName)
+    Q_PROPERTY(QString minVersion READ minVersion WRITE setMinVersion)
+    Q_PROPERTY(QDeclarativeListProperty<QDeclarativeService> services READ services NOTIFY servicesChanged)
 
 public:
     QDeclarativeServiceList();
--- a/plugins/declarative/serviceframework/serviceframework.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/declarative/serviceframework/serviceframework.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -28,5 +28,10 @@
 symbian {
     TARGET.EPOCALLOWDLLDATA=1
     TARGET.CAPABILITY = All -Tcb
+    TARGET.UID3 = 0x20021323
     load(armcc_warnings)
+    # Specifies what files shall be deployed: the plugin itself and the qmldir file.
+    importFiles.sources = $$DESTDIR/declarative_serviceframework$${QT_LIBINFIX}.dll qmldir 
+    importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
+    DEPLOYMENT = importFiles
 }
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamerrecordercontrol.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerrecordercontrol.h	Mon Oct 04 01:37:06 2010 +0300
@@ -53,7 +53,6 @@
 class QGstreamerRecorderControl : public QMediaRecorderControl
 {
     Q_OBJECT
-    Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
 
 public:
     QGstreamerRecorderControl(QGstreamerCaptureSession *session);
--- a/plugins/multimedia/gstreamer/qx11videosurface.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/multimedia/gstreamer/qx11videosurface.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -460,7 +460,7 @@
 #ifdef Q_WS_MAEMO_5
             //the overlay xvideo adapter fails to switch winId,
             //prefer the "SGX Textured Video" adapter instead
-        for (unsigned int i = count-1; i >=0 && !portFound; --i) {
+        for (int i = count-1; i >= 0 && !portFound; --i) {
 #else
         for (unsigned int i = 0; i < count && !portFound; ++i) {
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/mediaplayer.pri	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,16 @@
+INCLUDEPATH += $$PWD
+
+DEFINES += QMEDIA_QT7_PLAYER
+
+HEADERS += \
+    $$PWD/qt7playercontrol.h \
+    $$PWD/qt7playermetadata.h \
+    $$PWD/qt7playerservice.h \
+    $$PWD/qt7playersession.h
+
+OBJECTIVE_SOURCES += \
+    $$PWD/qt7playercontrol.mm \
+    $$PWD/qt7playermetadata.mm \
+    $$PWD/qt7playerservice.mm \
+    $$PWD/qt7playersession.mm
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playercontrol.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT7PLAYERCONTROL_H
+#define QT7PLAYERCONTROL_H
+
+#include <QtCore/qobject.h>
+
+#include <qmediaplayercontrol.h>
+#include <qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerSession;
+class QT7PlayerService;
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+
+class QT7PlayerControl : public QMediaPlayerControl
+{
+Q_OBJECT
+public:
+    QT7PlayerControl(QObject *parent = 0);
+    ~QT7PlayerControl();
+
+    void setSession(QT7PlayerSession *session);
+
+    QMediaPlayer::State state() const;
+    QMediaPlayer::MediaStatus mediaStatus() const;
+
+    QMediaContent media() const;
+    const QIODevice *mediaStream() const;
+    void setMedia(const QMediaContent &content, QIODevice *stream);
+
+    qint64 position() const;
+    qint64 duration() const;
+
+    int bufferStatus() const;
+
+    int volume() const;
+    bool isMuted() const;
+
+    bool isAudioAvailable() const;
+    bool isVideoAvailable() const;
+
+    bool isSeekable() const;
+    QMediaTimeRange availablePlaybackRanges() const;
+
+    qreal playbackRate() const;
+    void setPlaybackRate(qreal rate);
+
+public Q_SLOTS:
+    void setPosition(qint64 pos);
+
+    void play();
+    void pause();
+    void stop();
+
+    void setVolume(int volume);
+    void setMuted(bool muted);
+
+private:
+    QT7PlayerSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playercontrol.mm	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qt7playercontrol.h"
+#include "qt7playersession.h"
+
+#include <qmediaplaylistnavigator.h>
+
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+
+QT_USE_NAMESPACE
+
+QT7PlayerControl::QT7PlayerControl(QObject *parent)
+   : QMediaPlayerControl(parent)
+{    
+}
+
+QT7PlayerControl::~QT7PlayerControl()
+{
+}
+
+void QT7PlayerControl::setSession(QT7PlayerSession *session)
+{
+    m_session = session;
+
+    connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64)));
+    connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+    connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)),
+            this, SIGNAL(stateChanged(QMediaPlayer::State)));
+    connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+            this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+    connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
+    connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
+    connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool)));
+    connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool)));
+    connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+}
+
+qint64 QT7PlayerControl::position() const
+{
+    return m_session->position();
+}
+
+qint64 QT7PlayerControl::duration() const
+{
+    return m_session->duration();
+}
+
+QMediaPlayer::State QT7PlayerControl::state() const
+{
+    return m_session->state();
+}
+
+QMediaPlayer::MediaStatus QT7PlayerControl::mediaStatus() const
+{
+    return m_session->mediaStatus();
+}
+
+int QT7PlayerControl::bufferStatus() const
+{
+    return m_session->bufferStatus();
+}
+
+int QT7PlayerControl::volume() const
+{
+    return m_session->volume();
+}
+
+bool QT7PlayerControl::isMuted() const
+{
+    return m_session->isMuted();
+}
+
+bool QT7PlayerControl::isSeekable() const
+{
+    return m_session->isSeekable();
+}
+
+QMediaTimeRange QT7PlayerControl::availablePlaybackRanges() const
+{
+    QMediaTimeRange result;
+
+    if (isSeekable())
+        result.addInterval(0, duration());
+
+    return result;
+}
+
+qreal QT7PlayerControl::playbackRate() const
+{
+    return m_session->playbackRate();
+}
+
+void QT7PlayerControl::setPlaybackRate(qreal rate)
+{
+    m_session->setPlaybackRate(rate);
+}
+
+void QT7PlayerControl::setPosition(qint64 pos)
+{
+    m_session->setPosition(pos);
+}
+
+void QT7PlayerControl::play()
+{
+    m_session->play();
+}
+
+void QT7PlayerControl::pause()
+{
+    m_session->pause();
+}
+
+void QT7PlayerControl::stop()
+{
+    m_session->stop();
+}
+
+void QT7PlayerControl::setVolume(int volume)
+{
+    m_session->setVolume(volume);
+}
+
+void QT7PlayerControl::setMuted(bool muted)
+{
+    m_session->setMuted(muted);
+}
+
+QMediaContent QT7PlayerControl::media() const
+{
+    return m_session->media();
+}
+
+const QIODevice *QT7PlayerControl::mediaStream() const
+{
+    return m_session->mediaStream();
+}
+
+void QT7PlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+    m_session->setMedia(content, stream);
+
+    emit mediaChanged(content);
+}
+
+bool QT7PlayerControl::isAudioAvailable() const
+{
+    return m_session->isAudioAvailable();
+}
+
+bool QT7PlayerControl::isVideoAvailable() const
+{
+    return m_session->isVideoAvailable();
+}
+
+
+#include "moc_qt7playercontrol.cpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playermetadata.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT7PLAYERMETADATACONTROL_H
+#define QT7PLAYERMETADATACONTROL_H
+
+#include <qmetadatareadercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerSession;
+
+class QT7PlayerMetaDataControl : public QMetaDataReaderControl
+{
+    Q_OBJECT
+public:
+    QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent);
+    virtual ~QT7PlayerMetaDataControl();
+
+    bool isMetaDataAvailable() const;
+    bool isWritable() const;
+
+    QVariant metaData(QtMultimediaKit::MetaData key) const;
+    QList<QtMultimediaKit::MetaData> availableMetaData() const;
+
+    QVariant extendedMetaData(const QString &key) const ;
+    QStringList availableExtendedMetaData() const;
+
+private slots:
+    void updateTags();
+
+private:
+    QT7PlayerSession *m_session;
+    QMap<QtMultimediaKit::MetaData, QVariant> m_tags;
+};
+
+QT_END_NAMESPACE
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playermetadata.mm	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qt7backend.h"
+#include "qt7playermetadata.h"
+#include "qt7playersession.h"
+#include <QtCore/qvarlengtharray.h>
+
+#import <QTKit/QTMovie.h>
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+    #include <QuickTime/QuickTime.h>
+    #undef check // avoid name clash;
+#endif
+
+QT_USE_NAMESPACE
+
+QT7PlayerMetaDataControl::QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent)
+    :QMetaDataReaderControl(parent), m_session(session)
+{
+}
+
+QT7PlayerMetaDataControl::~QT7PlayerMetaDataControl()
+{
+}
+
+bool QT7PlayerMetaDataControl::isMetaDataAvailable() const
+{
+    return !m_tags.isEmpty();
+}
+
+bool QT7PlayerMetaDataControl::isWritable() const
+{
+    return false;
+}
+
+QVariant QT7PlayerMetaDataControl::metaData(QtMultimediaKit::MetaData key) const
+{
+    return m_tags.value(key);
+}
+
+QList<QtMultimediaKit::MetaData> QT7PlayerMetaDataControl::availableMetaData() const
+{
+    return m_tags.keys();
+}
+
+QVariant QT7PlayerMetaDataControl::extendedMetaData(const QString &key) const
+{
+    Q_UNUSED(key);
+    return QVariant();
+}
+
+QStringList QT7PlayerMetaDataControl::availableExtendedMetaData() const
+{
+    return QStringList();
+}
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+
+static QString stripCopyRightSymbol(const QString &key)
+{
+    return key.right(key.length()-1);
+}
+
+static QString convertQuickTimeKeyToUserKey(const QString &key)
+{
+    if (key == QLatin1String("com.apple.quicktime.displayname"))
+        return QLatin1String("nam");
+    else if (key == QLatin1String("com.apple.quicktime.album"))
+        return QLatin1String("alb");
+    else if (key == QLatin1String("com.apple.quicktime.artist"))
+        return QLatin1String("ART");
+    else
+        return QLatin1String("???");
+}
+
+static OSStatus readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
+                              QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
+{
+    QTPropertyValueType type;
+    ByteCount propSize;
+    UInt32 propFlags;
+    OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
+
+    if (err == noErr) {
+        *value = malloc(propSize);
+        if (*value != 0) {
+            err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
+
+            if (err == noErr && (type == 'code' || type == 'itsk' || type == 'itlk')) {
+                // convert from native endian to big endian
+                OSTypePtr pType = (OSTypePtr)*value;
+                *pType = EndianU32_NtoB(*pType);
+            }
+        }
+        else
+            return -1;
+    }
+
+    return err;
+}
+
+static UInt32 getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
+{
+    QTPropertyValuePtr value = 0;
+    ByteCount ignore = 0;
+    OSStatus err = readMetaValue(
+            metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
+
+    if (err == noErr) {
+        UInt32 type = *((UInt32 *) value);
+        if (value)
+            free(value);
+        return type;
+    }
+
+    return 0;
+}
+
+static QString cFStringToQString(CFStringRef str)
+{
+    if(!str)
+        return QString();
+    CFIndex length = CFStringGetLength(str);
+    const UniChar *chars = CFStringGetCharactersPtr(str);
+    if (chars)
+        return QString(reinterpret_cast<const QChar *>(chars), length);
+
+    QVarLengthArray<UniChar> buffer(length);
+    CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
+    return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
+}
+
+
+static QString getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
+{
+    QTPropertyValuePtr value = 0;
+    ByteCount size = 0;
+    OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
+    QString string;
+
+    if (err == noErr) {
+        UInt32 dataType = getMetaType(metaDataRef, item);
+        switch (dataType){
+        case kQTMetaDataTypeUTF8:
+        case kQTMetaDataTypeMacEncodedText:
+            string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
+            break;
+        case kQTMetaDataTypeUTF16BE:
+            string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
+            break;
+        default:
+            break;
+        }
+
+        if (value)
+            free(value);
+    }
+
+    return string;
+}
+
+
+static void readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
+{
+    QTMetaDataItem item = kQTMetaDataItemUninitialized;
+    OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
+    while (err == noErr){
+        QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
+        if (format == kQTMetaDataStorageFormatQuickTime)
+            key = convertQuickTimeKeyToUserKey(key);
+        else
+            key = stripCopyRightSymbol(key);
+
+        if (!result.contains(key)){
+            QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
+            result.insert(key, val);
+        }
+        err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
+    }
+}
+#endif
+
+
+void QT7PlayerMetaDataControl::updateTags()
+{
+    bool wasEmpty = m_tags.isEmpty();
+    m_tags.clear();
+
+    QTMovie *movie = (QTMovie*)m_session->movie();
+
+    if (movie) {
+        QMultiMap<QString, QString> metaMap;
+
+#ifdef QUICKTIME_C_API_AVAILABLE
+        QTMetaDataRef metaDataRef;
+        OSStatus err = QTCopyMovieMetaData([movie quickTimeMovie], &metaDataRef);
+        if (err == noErr) {
+            readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
+            readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
+            readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
+        }
+#else
+        AutoReleasePool pool;
+        NSString *name = [movie attributeForKey:@"QTMovieDisplayNameAttribute"];
+        metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
+#endif // QUICKTIME_C_API_AVAILABLE
+
+        m_tags.insert(QtMultimediaKit::AlbumArtist, metaMap.value(QLatin1String("ART")));
+        m_tags.insert(QtMultimediaKit::AlbumTitle, metaMap.value(QLatin1String("alb")));
+        m_tags.insert(QtMultimediaKit::Title, metaMap.value(QLatin1String("nam")));
+        m_tags.insert(QtMultimediaKit::Date, metaMap.value(QLatin1String("day")));
+        m_tags.insert(QtMultimediaKit::Genre, metaMap.value(QLatin1String("gnre")));
+        m_tags.insert(QtMultimediaKit::TrackNumber, metaMap.value(QLatin1String("trk")));
+        m_tags.insert(QtMultimediaKit::Description, metaMap.value(QLatin1String("des")));
+    }
+
+    if (!wasEmpty || !m_tags.isEmpty())
+        emit metaDataChanged();
+}
+
+#include "moc_qt7playermetadata.cpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playerservice.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT7PLAYERSERVICE_H
+#define QT7PLAYERSERVICE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qset.h>
+#include <qmediaservice.h>
+
+
+QT_BEGIN_NAMESPACE
+class QMediaMetaData;
+class QMediaPlayerControl;
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+class QT7PlayerControl;
+class QT7PlayerMetaDataControl;
+class QT7VideoWindowControl;
+class QT7VideoWidgetControl;
+class QT7VideoRendererControl;
+class QT7VideoOutput;
+class QT7PlayerSession;
+
+class QT7PlayerService : public QMediaService
+{
+Q_OBJECT
+public:
+    QT7PlayerService(QObject *parent = 0);
+    ~QT7PlayerService();
+
+    QMediaControl* requestControl(const char *name);
+    void releaseControl(QMediaControl *control);
+
+private:
+    QT7PlayerSession *m_session;
+    QT7PlayerControl *m_control;
+    QMediaControl * m_videoOutput;
+    QT7PlayerMetaDataControl *m_playerMetaDataControl;
+};
+
+QT_END_NAMESPACE
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playerservice.mm	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qdebug.h>
+#include <QtGui/qwidget.h>
+
+#include "qt7backend.h"
+#include "qt7playerservice.h"
+#include "qt7playercontrol.h"
+#include "qt7playersession.h"
+#include "qt7videooutput.h"
+#include "qt7movieviewoutput.h"
+#include "qt7movieviewrenderer.h"
+#include "qt7movierenderer.h"
+#include "qt7movievideowidget.h"
+#include "qt7playermetadata.h"
+
+#include <qmediaplaylistnavigator.h>
+#include <qmediaplaylist.h>
+
+QT_USE_NAMESPACE
+
+QT7PlayerService::QT7PlayerService(QObject *parent):
+    QMediaService(parent),
+    m_videoOutput(0)
+{
+    m_session = new QT7PlayerSession(this);
+
+    m_control = new QT7PlayerControl(this);
+    m_control->setSession(m_session);
+
+    m_playerMetaDataControl = new QT7PlayerMetaDataControl(m_session, this);
+    connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags()));
+}
+
+QT7PlayerService::~QT7PlayerService()
+{
+}
+
+QMediaControl *QT7PlayerService::requestControl(const char *name)
+{
+    if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
+        return m_control;
+
+    if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
+        return m_playerMetaDataControl;
+
+    if (!m_videoOutput) {
+        if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
+#if defined(QT_MAC_USE_COCOA)
+            m_videoOutput = new QT7MovieViewOutput(this);
+#endif
+        }
+
+        if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+#ifdef QUICKTIME_C_API_AVAILABLE
+            m_videoOutput = new QT7MovieRenderer(this);
+#else
+            m_videoOutput = new QT7MovieViewRenderer(this);
+#endif
+        }
+
+        if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
+#ifdef QUICKTIME_C_API_AVAILABLE
+            m_videoOutput = new QT7MovieVideoWidget(this);
+#endif
+        }
+
+        if (m_videoOutput) {
+            QT7VideoOutput *videoOutput = qobject_cast<QT7VideoOutput*>(m_videoOutput);
+            m_session->setVideoOutput(videoOutput);
+            return m_videoOutput;
+        }
+    }
+
+    return 0;
+}
+
+void QT7PlayerService::releaseControl(QMediaControl *control)
+{
+    if (m_videoOutput == control) {
+        m_videoOutput = 0;
+        m_session->setVideoOutput(0);
+        delete control;
+    }
+}
+
+#include "moc_qt7playerservice.cpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playersession.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT7PLAYERSESSION_H
+#define QT7PLAYERSESSION_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qset.h>
+#include <QtCore/qresource.h>
+
+#include <qmediaplayercontrol.h>
+#include <qmediaplayer.h>
+
+#include <QtGui/qmacdefines_mac.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QT7PlayerControl;
+class QMediaPlaylist;
+class QMediaPlaylistNavigator;
+class QT7VideoOutput;
+class QT7PlayerSession;
+class QT7PlayerService;
+
+
+class QT7PlayerSession : public QObject
+{
+    Q_OBJECT
+public:
+    QT7PlayerSession(QObject *parent = 0);
+    ~QT7PlayerSession();
+
+    void *movie() const;
+
+    void setControl(QT7PlayerControl *control);
+
+    void setVideoOutput(QT7VideoOutput *output);
+
+    QMediaPlayer::State state() const;
+    QMediaPlayer::MediaStatus mediaStatus() const;
+
+    QMediaContent media() const;
+    const QIODevice *mediaStream() const;
+    void setMedia(const QMediaContent &content, QIODevice *stream);
+
+    qint64 position() const;
+    qint64 duration() const;
+
+    int bufferStatus() const;
+
+    int volume() const;
+    bool isMuted() const;
+
+    bool isAudioAvailable() const;
+    bool isVideoAvailable() const;
+
+    bool isSeekable() const;
+
+    qreal playbackRate() const;
+
+public slots:
+    void setPlaybackRate(qreal rate);
+
+    void setPosition(qint64 pos);
+
+    void play();
+    void pause();
+    void stop();
+
+    void setVolume(int volume);
+    void setMuted(bool muted);
+
+    void processEOS();
+    void processLoadStateChange();
+    void processVolumeChange();
+    void processNaturalSizeChange();
+
+signals:
+    void positionChanged(qint64 position);
+    void durationChanged(qint64 duration);
+    void stateChanged(QMediaPlayer::State newState);
+    void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+    void volumeChanged(int volume);
+    void mutedChanged(bool muted);
+    void audioAvailableChanged(bool audioAvailable);
+    void videoAvailableChanged(bool videoAvailable);
+    void error(int error, const QString &errorString);
+
+private:
+    class ResourceHandler {
+    public:
+        ResourceHandler():resource(0) {}
+        ~ResourceHandler() { clear(); }
+        void setResourceFile(const QString &file) {
+            if (resource) {
+                if (resource->fileName() == file)
+                    return;
+                delete resource;
+                rawData.clear();
+            }
+            resource = new QResource(file);
+        }
+        bool isValid() const { return resource && resource->isValid() && resource->data() != 0; }
+        const uchar *data() {
+            if (!isValid())
+                return 0;
+            if (resource->isCompressed()) {
+                if (rawData.size() == 0)
+                    rawData = qUncompress(resource->data(), resource->size());
+                return (const uchar *)rawData.constData();
+            }
+            return resource->data();
+        }
+        qint64 size() {
+            if (data() == 0)
+                return 0;
+            return resource->isCompressed() ? rawData.size() : resource->size();
+        }
+        void clear() {
+            delete resource;
+            rawData.clear();
+        }
+        QResource *resource;
+        QByteArray rawData;
+    };
+
+    void openMovie(bool tryAsync);
+
+    void *m_QTMovie;
+    void *m_movieObserver;
+
+    QMediaPlayer::State m_state;
+    QMediaPlayer::MediaStatus m_mediaStatus;
+    QIODevice *m_mediaStream;
+    QMediaContent m_resources;
+    ResourceHandler m_resourceHandler;
+
+    QT7VideoOutput * m_videoOutput;
+
+    mutable qint64 m_currentTime;
+
+    bool m_muted;
+    bool m_tryingAsync;
+    int m_volume;
+    qreal m_rate;
+
+    qint64 m_duration;
+    bool m_videoAvailable;
+    bool m_audioAvailable;
+};
+
+QT_END_NAMESPACE
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/multimedia/qt7/mediaplayer/qt7playersession.mm	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,655 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <QTKit/QTDataReference.h>
+#import <QTKit/QTMovie.h>
+
+#include "qt7backend.h"
+
+#include "qt7playersession.h"
+#include "qt7playercontrol.h"
+#include "qt7videooutput.h"
+
+#include <QtNetwork/qnetworkcookie.h>
+#include <qmediaplaylistnavigator.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Foundation/Foundation.h>
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qurl.h>
+
+#include <QtCore/qdebug.h>
+
+QT_USE_NAMESPACE
+
+@interface QTMovieObserver : NSObject
+{
+@private
+    QT7PlayerSession *m_session;
+    QTMovie *m_movie;
+}
+
+- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session;
+- (void) setMovie:(QTMovie *)movie;
+- (void) processEOS:(NSNotification *)notification;
+- (void) processLoadStateChange:(NSNotification *)notification;
+- (void) processVolumeChange:(NSNotification *)notification;
+- (void) processNaturalSizeChange :(NSNotification *)notification;
+@end
+
+@implementation QTMovieObserver
+
+- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session
+{
+    if (!(self = [super init]))
+        return nil;
+
+    self->m_session = session;
+    return self;
+}
+
+- (void) setMovie:(QTMovie *)movie
+{
+    if (m_movie == movie)
+        return;
+
+    if (m_movie) {
+        [[NSNotificationCenter defaultCenter] removeObserver:self];
+        [m_movie release];
+    }
+
+    m_movie = movie;
+
+    if (movie) {
+        [[NSNotificationCenter defaultCenter] addObserver:self
+                                                 selector:@selector(processEOS:)
+                                                     name:QTMovieDidEndNotification
+                                                   object:m_movie];
+
+        [[NSNotificationCenter defaultCenter] addObserver:self
+                                                 selector:@selector(processLoadStateChange:)
+                                                     name:QTMovieLoadStateDidChangeNotification
+                                                   object:m_movie];
+
+        [[NSNotificationCenter defaultCenter] addObserver:self
+                                                 selector:@selector(processVolumeChange:)
+                                                     name:QTMovieVolumeDidChangeNotification
+                                                   object:m_movie];
+
+        if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
+            [[NSNotificationCenter defaultCenter] addObserver:self
+                                                     selector:@selector(processNaturalSizeChange:)
+                                                         name:@"QTMovieNaturalSizeDidChangeNotification"
+                                                       object:m_movie];
+
+        }
+        else {
+            [[NSNotificationCenter defaultCenter] addObserver:self
+                                                     selector:@selector(processNaturalSizeChange:)
+                                                         name:QTMovieEditedNotification
+                                                       object:m_movie];
+        }
+
+        [movie retain];
+    }
+}
+
+- (void) processEOS:(NSNotification *)notification
+{
+    Q_UNUSED(notification);
+    QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection);
+}
+
+- (void) processLoadStateChange:(NSNotification *)notification
+{
+    Q_UNUSED(notification);
+    QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
+}
+
+- (void) processVolumeChange:(NSNotification *)notification
+{
+    Q_UNUSED(notification);
+    QMetaObject::invokeMethod(m_session, "processVolumeChange", Qt::AutoConnection);
+}
+
+- (void) processNaturalSizeChange :(NSNotification *)notification
+{
+    Q_UNUSED(notification);
+    QMetaObject::invokeMethod(m_session, "processNaturalSizeChange", Qt::AutoConnection);
+}
+
+@end
+
+static inline NSString *qString2CFStringRef(const QString &string)
+{
+    return [NSString stringWithCharacters:reinterpret_cast<const UniChar *>(string.unicode()) length:string.length()];
+}
+
+QT7PlayerSession::QT7PlayerSession(QObject *parent)
+   : QObject(parent)
+   , m_QTMovie(0)
+   , m_state(QMediaPlayer::StoppedState)
+   , m_mediaStatus(QMediaPlayer::NoMedia)
+   , m_mediaStream(0)
+   , m_videoOutput(0)
+   , m_muted(false)
+   , m_tryingAsync(false)
+   , m_volume(100)
+   , m_rate(1.0)
+   , m_duration(0)
+   , m_videoAvailable(false)
+   , m_audioAvailable(false)
+{
+    m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this];
+}
+
+QT7PlayerSession::~QT7PlayerSession()
+{
+    [(QTMovieObserver*)m_movieObserver setMovie:nil];
+    [(QTMovieObserver*)m_movieObserver release];
+    [(QTMovie*)m_QTMovie release];
+}
+
+void *QT7PlayerSession::movie() const
+{
+    return m_QTMovie;
+}
+
+void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output)
+{
+    if (m_videoOutput == output)
+        return;
+
+    if (m_videoOutput)
+        m_videoOutput->setMovie(0);
+
+    m_videoOutput = output;
+
+    if (m_videoOutput && m_state != QMediaPlayer::StoppedState)
+        m_videoOutput->setMovie(m_QTMovie);
+}
+
+qint64 QT7PlayerSession::position() const
+{
+    if (!m_QTMovie || m_state == QMediaPlayer::PausedState)
+        return m_currentTime;
+
+    QTTime qtTime = [(QTMovie*)m_QTMovie currentTime];
+    quint64 t = static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
+    m_currentTime = t;
+
+    return m_currentTime;
+}
+
+qint64 QT7PlayerSession::duration() const
+{
+    if (!m_QTMovie)
+        return 0;
+
+    QTTime qtTime = [(QTMovie*)m_QTMovie duration];
+
+    return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
+}
+
+QMediaPlayer::State QT7PlayerSession::state() const
+{
+    return m_state;
+}
+
+QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const
+{
+    return m_mediaStatus;
+}
+
+int QT7PlayerSession::bufferStatus() const
+{
+    return 100;
+}
+
+int QT7PlayerSession::volume() const
+{
+    return m_volume;
+}
+
+bool QT7PlayerSession::isMuted() const
+{
+    return m_muted;
+}
+
+bool QT7PlayerSession::isSeekable() const
+{
+    return true;
+}
+
+qreal QT7PlayerSession::playbackRate() const
+{
+    return m_rate;
+}
+
+void QT7PlayerSession::setPlaybackRate(qreal rate)
+{
+    if (qFuzzyCompare(m_rate, rate))
+        return;
+
+    m_rate = rate;
+
+    if (m_QTMovie != 0 && m_state == QMediaPlayer::PlayingState) {
+        AutoReleasePool pool;
+        float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
+        [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
+    }
+}
+
+void QT7PlayerSession::setPosition(qint64 pos)
+{
+    if ( !isSeekable() || pos == position())
+        return;
+
+    pos = qMin(pos, duration());
+
+    QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime];
+    newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale;
+    [(QTMovie*)m_QTMovie setCurrentTime:newQTTime];
+}
+
+void QT7PlayerSession::play()
+{
+    if (m_state == QMediaPlayer::PlayingState)
+        return;
+
+    m_state = QMediaPlayer::PlayingState;
+
+    if (m_videoOutput)
+        m_videoOutput->setMovie(m_QTMovie);
+
+    AutoReleasePool pool;
+    float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
+    [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
+
+    emit stateChanged(m_state);
+}
+
+void QT7PlayerSession::pause()
+{
+    if (m_state == QMediaPlayer::PausedState)
+        return;
+
+    m_state = QMediaPlayer::PausedState;
+
+    if (m_videoOutput)
+        m_videoOutput->setMovie(m_QTMovie);
+
+    [(QTMovie*)m_QTMovie setRate:0];
+
+    emit stateChanged(m_state);
+}
+
+void QT7PlayerSession::stop()
+{
+    if (m_state == QMediaPlayer::StoppedState)
+        return;
+
+    m_state = QMediaPlayer::StoppedState;
+
+    [(QTMovie*)m_QTMovie setRate:0];
+    setPosition(0);
+
+    if (m_videoOutput)
+        m_videoOutput->setMovie(0);
+
+    emit stateChanged(m_state);
+}
+
+void QT7PlayerSession::setVolume(int volume)
+{
+    if (m_volume == volume)
+        return;
+
+    m_volume = volume;
+
+    if (m_QTMovie != 0)
+        [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
+    else
+        emit volumeChanged(m_volume);
+}
+
+void QT7PlayerSession::setMuted(bool muted)
+{
+    if (m_muted == muted)
+        return;
+
+    m_muted = muted;
+
+    if (m_QTMovie != 0)
+        [(QTMovie*)m_QTMovie setMuted:m_muted];
+
+    emit mutedChanged(muted);
+}
+
+QMediaContent QT7PlayerSession::media() const
+{
+    return m_resources;
+}
+
+const QIODevice *QT7PlayerSession::mediaStream() const
+{
+    return m_mediaStream;
+}
+
+void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+    AutoReleasePool pool;
+
+#ifdef QT_DEBUG_QT7
+    qDebug() << Q_FUNC_INFO << content.canonicalUrl();
+#endif
+
+    if (m_QTMovie) {
+        [(QTMovieObserver*)m_movieObserver setMovie:nil];
+
+        if (m_videoOutput)
+            m_videoOutput->setMovie(0);
+
+        [(QTMovie*)m_QTMovie release];
+        m_QTMovie = 0;
+        m_resourceHandler.clear();
+    }
+
+    m_resources = content;
+    m_mediaStream = stream;
+    m_mediaStatus = QMediaPlayer::NoMedia;
+
+    if (content.isNull())
+        return;
+
+    QNetworkRequest request = content.canonicalResource().request();
+
+    QVariant cookies = request.header(QNetworkRequest::CookieHeader);
+    if (cookies.isValid()) {
+        NSHTTPCookieStorage *store = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+        QList<QNetworkCookie> cookieList = cookies.value<QList<QNetworkCookie> >();
+
+        foreach (const QNetworkCookie &requestCookie, cookieList) {
+            NSMutableDictionary *p = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                               qString2CFStringRef(requestCookie.name()), NSHTTPCookieName,
+                               qString2CFStringRef(requestCookie.value()), NSHTTPCookieValue,
+                               qString2CFStringRef(requestCookie.domain()), NSHTTPCookieDomain,
+                               qString2CFStringRef(requestCookie.path()), NSHTTPCookiePath,
+                               nil
+                               ];
+            if (requestCookie.isSessionCookie())
+                [p setObject:[NSString stringWithUTF8String:"TRUE"] forKey:NSHTTPCookieDiscard];
+            else
+                [p setObject:[NSDate dateWithTimeIntervalSince1970:requestCookie.expirationDate().toTime_t()] forKey:NSHTTPCookieExpires];
+
+            [store setCookie:[NSHTTPCookie cookieWithProperties:p]];
+        }
+    }
+
+    // Attempt multiple times to open the movie.
+    // First try - attempt open in async mode
+    openMovie(true);
+}
+
+void QT7PlayerSession::openMovie(bool tryAsync)
+{
+    QUrl requestUrl = m_resources.canonicalResource().request().url();
+    if (requestUrl.scheme().isEmpty())
+        requestUrl.setScheme(QLatin1String("file"));
+
+#ifdef QT_DEBUG_QT7
+    qDebug() << Q_FUNC_INFO << requestUrl;
+#endif
+
+    NSError *err = 0;
+    NSString *urlString = [NSString stringWithUTF8String:requestUrl.toEncoded().constData()];
+
+    NSMutableDictionary *attr = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute,
+                [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute,
+                [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute,
+                [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute,
+                nil];
+
+
+    if (requestUrl.scheme() == QLatin1String("qrc")) {
+        // Load from Qt resource
+        m_resourceHandler.setResourceFile(QLatin1Char(':') + requestUrl.path());
+        if (!m_resourceHandler.isValid()) {
+            emit error(QMediaPlayer::FormatError, tr("Attempting to play invalid Qt resource"));
+            return;
+        }
+
+        CFDataRef resourceData =
+                CFDataCreateWithBytesNoCopy(0, m_resourceHandler.data(), m_resourceHandler.size(), kCFAllocatorNull);
+
+        QTDataReference *dataReference =
+                [QTDataReference dataReferenceWithReferenceToData:(NSData*)resourceData
+                                                             name:qString2CFStringRef(requestUrl.path())
+                                                         MIMEType:nil];
+
+        [attr setObject:dataReference forKey:QTMovieDataReferenceAttribute];
+
+        CFRelease(resourceData);
+    } else {
+        [attr setObject:[NSURL URLWithString:urlString] forKey:QTMovieURLAttribute];
+    }
+
+    if (tryAsync && QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
+        [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenAsyncRequiredAttribute"];
+// XXX: This is disabled for now. causes some problems with video playback for some formats
+//        [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
+        m_tryingAsync = true;
+    }
+    else
+        m_tryingAsync = false;
+
+    m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
+    if (err != nil) {
+        // First attempt to test for inability to perform async
+//        if ([err code] == QTErrorMovieOpeningCannotBeAsynchronous) { XXX: error code unknown!
+        if (m_tryingAsync) {
+            m_tryingAsync = false;
+            err = nil;
+            [attr removeObjectForKey:@"QTMovieOpenAsyncRequiredAttribute"];
+            m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
+        }
+    }
+
+    if (err != nil) {
+        m_QTMovie = 0;
+        QString description = QString::fromUtf8([[err localizedDescription] UTF8String]);
+        emit error(QMediaPlayer::FormatError, description);
+
+#ifdef QT_DEBUG_QT7
+        qDebug() << Q_FUNC_INFO << description;
+#endif
+    }
+    else {
+        [(QTMovie*)m_QTMovie retain];
+
+        [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie];
+
+        if (m_state != QMediaPlayer::StoppedState && m_videoOutput)
+            m_videoOutput->setMovie(m_QTMovie);
+
+        processLoadStateChange();
+
+        [(QTMovie*)m_QTMovie setMuted:m_muted];
+        [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
+    }
+}
+
+bool QT7PlayerSession::isAudioAvailable() const
+{
+    if (!m_QTMovie)
+        return false;
+
+    AutoReleasePool pool;
+    return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES;
+}
+
+bool QT7PlayerSession::isVideoAvailable() const
+{
+    if (!m_QTMovie)
+        return false;
+
+    AutoReleasePool pool;
+    return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES;
+}
+
+void QT7PlayerSession::processEOS()
+{
+#ifdef QT_DEBUG_QT7
+    qDebug() << Q_FUNC_INFO;
+#endif
+    m_mediaStatus = QMediaPlayer::EndOfMedia;
+    if (m_videoOutput)
+        m_videoOutput->setMovie(0);
+    emit stateChanged(m_state = QMediaPlayer::StoppedState);
+    emit mediaStatusChanged(m_mediaStatus);
+}
+
+void QT7PlayerSession::processLoadStateChange()
+{
+    if (!m_QTMovie)
+        return;
+
+    AutoReleasePool pool;
+
+    long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] longValue];
+
+#ifdef QT_DEBUG_QT7
+    qDebug() << Q_FUNC_INFO << state;
+#endif
+
+#ifndef QUICKTIME_C_API_AVAILABLE
+    enum {
+      kMovieLoadStateError          = -1L,
+      kMovieLoadStateLoading        = 1000,
+      kMovieLoadStateLoaded         = 2000,
+      kMovieLoadStatePlayable       = 10000,
+      kMovieLoadStatePlaythroughOK  = 20000,
+      kMovieLoadStateComplete       = 100000
+    };
+#endif
+
+    if (state == kMovieLoadStateError) {
+        if (m_tryingAsync) {
+            NSError *error = [(QTMovie*)m_QTMovie attributeForKey:@"QTMovieLoadStateErrorAttribute"];
+            if ([error code] == componentNotThreadSafeErr) {
+                // Last Async check, try again with no such flag
+                openMovie(false);
+            }
+        }
+        else {
+            if (m_videoOutput)
+                m_videoOutput->setMovie(0);
+
+            emit error(QMediaPlayer::FormatError, tr("Failed to load media"));
+            emit mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
+            emit stateChanged(m_state = QMediaPlayer::StoppedState);
+        }
+
+        return;
+    }
+
+    QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia;
+    bool isPlaying = (m_state != QMediaPlayer::StoppedState);
+
+    if (state >= kMovieLoadStatePlaythroughOK) {
+        newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
+    } else if (state >= kMovieLoadStatePlayable)
+        newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia;
+    else if (state >= kMovieLoadStateLoading)
+        newStatus = isPlaying ? QMediaPlayer::StalledMedia : QMediaPlayer::LoadingMedia;
+
+    if (state >= kMovieLoadStatePlayable &&
+        m_state == QMediaPlayer::PlayingState &&
+        [(QTMovie*)m_QTMovie rate] == 0) {
+
+        float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
+
+        [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
+    }
+
+    if (state >= kMovieLoadStateLoaded) {
+        qint64 currentDuration = duration();
+        if (m_duration != currentDuration)
+            emit durationChanged(m_duration = currentDuration);
+
+        if (m_audioAvailable != isAudioAvailable())
+            emit audioAvailableChanged(m_audioAvailable = !m_audioAvailable);
+
+        if (m_videoAvailable != isVideoAvailable())
+            emit videoAvailableChanged(m_videoAvailable = !m_videoAvailable);
+    }
+
+    if (newStatus != m_mediaStatus)
+        emit mediaStatusChanged(m_mediaStatus = newStatus);
+}
+
+void QT7PlayerSession::processVolumeChange()
+{
+    if (!m_QTMovie)
+        return;
+
+    int newVolume = qRound(100.0f * [((QTMovie*)m_QTMovie) volume]);
+
+    if (newVolume != m_volume) {
+        emit volumeChanged(m_volume = newVolume);
+    }
+}
+
+void QT7PlayerSession::processNaturalSizeChange()
+{
+    AutoReleasePool pool;
+    NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
+#ifdef QT_DEBUG_QT7
+    qDebug() << Q_FUNC_INFO << QSize(size.width, size.height);
+#endif
+
+    if (m_videoOutput)
+        m_videoOutput->updateNaturalSize(QSize(size.width, size.height));
+}
+
+#include "moc_qt7playersession.cpp"
--- a/plugins/multimedia/qt7/qt7.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/multimedia/qt7/qt7.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -33,31 +33,25 @@
 
 HEADERS += \
     qt7backend.h \
-    qt7playercontrol.h \
     qt7videooutput.h \
     qt7movieviewoutput.h \
     qt7movievideowidget.h \
     qt7movieviewrenderer.h \
-    qt7playersession.h \
-    qt7playerservice.h \
     qt7serviceplugin.h \
     qt7movierenderer.h \
     qt7ciimagevideobuffer.h \
-    qt7playermetadata.h \
     qcvdisplaylink.h
 
 
 OBJECTIVE_SOURCES += \
     qt7backend.mm \
-    qt7playersession.mm \
     qt7serviceplugin.mm \
     qt7movieviewoutput.mm \
     qt7movievideowidget.mm \
     qt7movieviewrenderer.mm \
-    qt7playermetadata.mm \
     qt7movierenderer.mm \
-    qt7playercontrol.mm \
     qt7videooutput.mm \
     qt7ciimagevideobuffer.mm \
-    qt7playerservice.mm \
     qcvdisplaylink.mm
+
+include(mediaplayer/mediaplayer.pri)
--- a/plugins/multimedia/qt7/qt7playercontrol.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERCONTROL_H
-#define QT7PLAYERCONTROL_H
-
-#include <QtCore/qobject.h>
-
-#include <qmediaplayercontrol.h>
-#include <qmediaplayer.h>
-
-#include <QtGui/qmacdefines_mac.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-class QT7PlayerService;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-
-class QT7PlayerControl : public QMediaPlayerControl
-{
-Q_OBJECT
-public:
-    QT7PlayerControl(QObject *parent = 0);
-    ~QT7PlayerControl();
-
-    void setSession(QT7PlayerSession *session);
-
-    QMediaPlayer::State state() const;
-    QMediaPlayer::MediaStatus mediaStatus() const;
-
-    QMediaContent media() const;
-    const QIODevice *mediaStream() const;
-    void setMedia(const QMediaContent &content, QIODevice *stream);
-
-    qint64 position() const;
-    qint64 duration() const;
-
-    int bufferStatus() const;
-
-    int volume() const;
-    bool isMuted() const;
-
-    bool isAudioAvailable() const;
-    bool isVideoAvailable() const;
-
-    bool isSeekable() const;
-    QMediaTimeRange availablePlaybackRanges() const;
-
-    qreal playbackRate() const;
-    void setPlaybackRate(qreal rate);
-
-public Q_SLOTS:
-    void setPosition(qint64 pos);
-
-    void play();
-    void pause();
-    void stop();
-
-    void setVolume(int volume);
-    void setMuted(bool muted);
-
-private:
-    QT7PlayerSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
--- a/plugins/multimedia/qt7/qt7playercontrol.mm	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-
-#include <qmediaplaylistnavigator.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-QT7PlayerControl::QT7PlayerControl(QObject *parent)
-   : QMediaPlayerControl(parent)
-{    
-}
-
-QT7PlayerControl::~QT7PlayerControl()
-{
-}
-
-void QT7PlayerControl::setSession(QT7PlayerSession *session)
-{
-    m_session = session;
-
-    connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64)));
-    connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
-    connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)),
-            this, SIGNAL(stateChanged(QMediaPlayer::State)));
-    connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
-            this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
-    connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
-    connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
-    connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool)));
-    connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool)));
-    connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
-}
-
-qint64 QT7PlayerControl::position() const
-{
-    return m_session->position();
-}
-
-qint64 QT7PlayerControl::duration() const
-{
-    return m_session->duration();
-}
-
-QMediaPlayer::State QT7PlayerControl::state() const
-{
-    return m_session->state();
-}
-
-QMediaPlayer::MediaStatus QT7PlayerControl::mediaStatus() const
-{
-    return m_session->mediaStatus();
-}
-
-int QT7PlayerControl::bufferStatus() const
-{
-    return m_session->bufferStatus();
-}
-
-int QT7PlayerControl::volume() const
-{
-    return m_session->volume();
-}
-
-bool QT7PlayerControl::isMuted() const
-{
-    return m_session->isMuted();
-}
-
-bool QT7PlayerControl::isSeekable() const
-{
-    return m_session->isSeekable();
-}
-
-QMediaTimeRange QT7PlayerControl::availablePlaybackRanges() const
-{
-    QMediaTimeRange result;
-
-    if (isSeekable())
-        result.addInterval(0, duration());
-
-    return result;
-}
-
-qreal QT7PlayerControl::playbackRate() const
-{
-    return m_session->playbackRate();
-}
-
-void QT7PlayerControl::setPlaybackRate(qreal rate)
-{
-    m_session->setPlaybackRate(rate);
-}
-
-void QT7PlayerControl::setPosition(qint64 pos)
-{
-    m_session->setPosition(pos);
-}
-
-void QT7PlayerControl::play()
-{
-    m_session->play();
-}
-
-void QT7PlayerControl::pause()
-{
-    m_session->pause();
-}
-
-void QT7PlayerControl::stop()
-{
-    m_session->stop();
-}
-
-void QT7PlayerControl::setVolume(int volume)
-{
-    m_session->setVolume(volume);
-}
-
-void QT7PlayerControl::setMuted(bool muted)
-{
-    m_session->setMuted(muted);
-}
-
-QMediaContent QT7PlayerControl::media() const
-{
-    return m_session->media();
-}
-
-const QIODevice *QT7PlayerControl::mediaStream() const
-{
-    return m_session->mediaStream();
-}
-
-void QT7PlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
-{
-    m_session->setMedia(content, stream);
-
-    emit mediaChanged(content);
-}
-
-bool QT7PlayerControl::isAudioAvailable() const
-{
-    return m_session->isAudioAvailable();
-}
-
-bool QT7PlayerControl::isVideoAvailable() const
-{
-    return m_session->isVideoAvailable();
-}
-
-
-#include "moc_qt7playercontrol.cpp"
--- a/plugins/multimedia/qt7/qt7playermetadata.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERMETADATACONTROL_H
-#define QT7PLAYERMETADATACONTROL_H
-
-#include <qmetadatareadercontrol.h>
-
-QT_BEGIN_NAMESPACE
-
-class QT7PlayerSession;
-
-class QT7PlayerMetaDataControl : public QMetaDataReaderControl
-{
-    Q_OBJECT
-public:
-    QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent);
-    virtual ~QT7PlayerMetaDataControl();
-
-    bool isMetaDataAvailable() const;
-    bool isWritable() const;
-
-    QVariant metaData(QtMultimediaKit::MetaData key) const;
-    QList<QtMultimediaKit::MetaData> availableMetaData() const;
-
-    QVariant extendedMetaData(const QString &key) const ;
-    QStringList availableExtendedMetaData() const;
-
-private slots:
-    void updateTags();
-
-private:
-    QT7PlayerSession *m_session;
-    QMap<QtMultimediaKit::MetaData, QVariant> m_tags;
-};
-
-QT_END_NAMESPACE
-
-#endif
--- a/plugins/multimedia/qt7/qt7playermetadata.mm	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,260 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qt7backend.h"
-#include "qt7playermetadata.h"
-#include "qt7playersession.h"
-#include <QtCore/qvarlengtharray.h>
-
-#import <QTKit/QTMovie.h>
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-    #include <QuickTime/QuickTime.h>
-    #undef check // avoid name clash;
-#endif
-
-QT_USE_NAMESPACE
-
-QT7PlayerMetaDataControl::QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent)
-    :QMetaDataReaderControl(parent), m_session(session)
-{
-}
-
-QT7PlayerMetaDataControl::~QT7PlayerMetaDataControl()
-{
-}
-
-bool QT7PlayerMetaDataControl::isMetaDataAvailable() const
-{
-    return !m_tags.isEmpty();
-}
-
-bool QT7PlayerMetaDataControl::isWritable() const
-{
-    return false;
-}
-
-QVariant QT7PlayerMetaDataControl::metaData(QtMultimediaKit::MetaData key) const
-{
-    return m_tags.value(key);
-}
-
-QList<QtMultimediaKit::MetaData> QT7PlayerMetaDataControl::availableMetaData() const
-{
-    return m_tags.keys();
-}
-
-QVariant QT7PlayerMetaDataControl::extendedMetaData(const QString &key) const
-{
-    Q_UNUSED(key);
-    return QVariant();
-}
-
-QStringList QT7PlayerMetaDataControl::availableExtendedMetaData() const
-{
-    return QStringList();
-}
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-
-static QString stripCopyRightSymbol(const QString &key)
-{
-    return key.right(key.length()-1);
-}
-
-static QString convertQuickTimeKeyToUserKey(const QString &key)
-{
-    if (key == QLatin1String("com.apple.quicktime.displayname"))
-        return QLatin1String("nam");
-    else if (key == QLatin1String("com.apple.quicktime.album"))
-        return QLatin1String("alb");
-    else if (key == QLatin1String("com.apple.quicktime.artist"))
-        return QLatin1String("ART");
-    else
-        return QLatin1String("???");
-}
-
-static OSStatus readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
-                              QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
-{
-    QTPropertyValueType type;
-    ByteCount propSize;
-    UInt32 propFlags;
-    OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
-
-    if (err == noErr) {
-        *value = malloc(propSize);
-        if (*value != 0) {
-            err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
-
-            if (err == noErr && (type == 'code' || type == 'itsk' || type == 'itlk')) {
-                // convert from native endian to big endian
-                OSTypePtr pType = (OSTypePtr)*value;
-                *pType = EndianU32_NtoB(*pType);
-            }
-        }
-        else
-            return -1;
-    }
-
-    return err;
-}
-
-static UInt32 getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
-{
-    QTPropertyValuePtr value = 0;
-    ByteCount ignore = 0;
-    OSStatus err = readMetaValue(
-            metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
-
-    if (err == noErr) {
-        UInt32 type = *((UInt32 *) value);
-        if (value)
-            free(value);
-        return type;
-    }
-
-    return 0;
-}
-
-static QString cFStringToQString(CFStringRef str)
-{
-    if(!str)
-        return QString();
-    CFIndex length = CFStringGetLength(str);
-    const UniChar *chars = CFStringGetCharactersPtr(str);
-    if (chars)
-        return QString(reinterpret_cast<const QChar *>(chars), length);
-
-    QVarLengthArray<UniChar> buffer(length);
-    CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
-    return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
-}
-
-
-static QString getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
-{
-    QTPropertyValuePtr value = 0;
-    ByteCount size = 0;
-    OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
-    QString string;
-
-    if (err == noErr) {
-        UInt32 dataType = getMetaType(metaDataRef, item);
-        switch (dataType){
-        case kQTMetaDataTypeUTF8:
-        case kQTMetaDataTypeMacEncodedText:
-            string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
-            break;
-        case kQTMetaDataTypeUTF16BE:
-            string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
-            break;
-        default:
-            break;
-        }
-
-        if (value)
-            free(value);
-    }
-
-    return string;
-}
-
-
-static void readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
-{
-    QTMetaDataItem item = kQTMetaDataItemUninitialized;
-    OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
-    while (err == noErr){
-        QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
-        if (format == kQTMetaDataStorageFormatQuickTime)
-            key = convertQuickTimeKeyToUserKey(key);
-        else
-            key = stripCopyRightSymbol(key);
-
-        if (!result.contains(key)){
-            QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
-            result.insert(key, val);
-        }
-        err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
-    }
-}
-#endif
-
-
-void QT7PlayerMetaDataControl::updateTags()
-{
-    bool wasEmpty = m_tags.isEmpty();
-    m_tags.clear();
-
-    QTMovie *movie = (QTMovie*)m_session->movie();
-
-    if (movie) {
-        QMultiMap<QString, QString> metaMap;
-
-#ifdef QUICKTIME_C_API_AVAILABLE
-        QTMetaDataRef metaDataRef;
-        OSStatus err = QTCopyMovieMetaData([movie quickTimeMovie], &metaDataRef);
-        if (err == noErr) {
-            readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
-            readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
-            readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
-        }
-#else
-        AutoReleasePool pool;
-        NSString *name = [movie attributeForKey:@"QTMovieDisplayNameAttribute"];
-        metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
-#endif // QUICKTIME_C_API_AVAILABLE
-
-        m_tags.insert(QtMultimediaKit::AlbumArtist, metaMap.value(QLatin1String("ART")));
-        m_tags.insert(QtMultimediaKit::AlbumTitle, metaMap.value(QLatin1String("alb")));
-        m_tags.insert(QtMultimediaKit::Title, metaMap.value(QLatin1String("nam")));
-        m_tags.insert(QtMultimediaKit::Date, metaMap.value(QLatin1String("day")));
-        m_tags.insert(QtMultimediaKit::Genre, metaMap.value(QLatin1String("gnre")));
-        m_tags.insert(QtMultimediaKit::TrackNumber, metaMap.value(QLatin1String("trk")));
-        m_tags.insert(QtMultimediaKit::Description, metaMap.value(QLatin1String("des")));
-    }
-
-    if (!wasEmpty || !m_tags.isEmpty())
-        emit metaDataChanged();
-}
-
-#include "moc_qt7playermetadata.cpp"
--- a/plugins/multimedia/qt7/qt7playerservice.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERSERVICE_H
-#define QT7PLAYERSERVICE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qset.h>
-#include <qmediaservice.h>
-
-
-QT_BEGIN_NAMESPACE
-class QMediaMetaData;
-class QMediaPlayerControl;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7PlayerControl;
-class QT7PlayerMetaDataControl;
-class QT7VideoWindowControl;
-class QT7VideoWidgetControl;
-class QT7VideoRendererControl;
-class QT7VideoOutput;
-class QT7PlayerSession;
-
-class QT7PlayerService : public QMediaService
-{
-Q_OBJECT
-public:
-    QT7PlayerService(QObject *parent = 0);
-    ~QT7PlayerService();
-
-    QMediaControl* requestControl(const char *name);
-    void releaseControl(QMediaControl *control);
-
-private:
-    QT7PlayerSession *m_session;
-    QT7PlayerControl *m_control;
-    QMediaControl * m_videoOutput;
-    QT7PlayerMetaDataControl *m_playerMetaDataControl;
-};
-
-QT_END_NAMESPACE
-
-#endif
--- a/plugins/multimedia/qt7/qt7playerservice.mm	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qvariant.h>
-#include <QtCore/qdebug.h>
-#include <QtGui/qwidget.h>
-
-#include "qt7backend.h"
-#include "qt7playerservice.h"
-#include "qt7playercontrol.h"
-#include "qt7playersession.h"
-#include "qt7videooutput.h"
-#include "qt7movieviewoutput.h"
-#include "qt7movieviewrenderer.h"
-#include "qt7movierenderer.h"
-#include "qt7movievideowidget.h"
-#include "qt7playermetadata.h"
-
-#include <qmediaplaylistnavigator.h>
-#include <qmediaplaylist.h>
-
-QT_USE_NAMESPACE
-
-QT7PlayerService::QT7PlayerService(QObject *parent):
-    QMediaService(parent),
-    m_videoOutput(0)
-{
-    m_session = new QT7PlayerSession(this);
-
-    m_control = new QT7PlayerControl(this);
-    m_control->setSession(m_session);
-
-    m_playerMetaDataControl = new QT7PlayerMetaDataControl(m_session, this);
-    connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags()));
-}
-
-QT7PlayerService::~QT7PlayerService()
-{
-}
-
-QMediaControl *QT7PlayerService::requestControl(const char *name)
-{
-    if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
-        return m_control;
-
-    if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
-        return m_playerMetaDataControl;
-
-    if (!m_videoOutput) {
-        if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
-#if defined(QT_MAC_USE_COCOA)
-            m_videoOutput = new QT7MovieViewOutput(this);
-#endif
-        }
-
-        if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
-#ifdef QUICKTIME_C_API_AVAILABLE
-            m_videoOutput = new QT7MovieRenderer(this);
-#else
-            m_videoOutput = new QT7MovieViewRenderer(this);
-#endif
-        }
-
-        if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
-#ifdef QUICKTIME_C_API_AVAILABLE
-            m_videoOutput = new QT7MovieVideoWidget(this);
-#endif
-        }
-
-        if (m_videoOutput) {
-            QT7VideoOutput *videoOutput = qobject_cast<QT7VideoOutput*>(m_videoOutput);
-            m_session->setVideoOutput(videoOutput);
-            return m_videoOutput;
-        }
-    }
-
-    return 0;
-}
-
-void QT7PlayerService::releaseControl(QMediaControl *control)
-{
-    if (m_videoOutput == control) {
-        m_videoOutput = 0;
-        m_session->setVideoOutput(0);
-        delete control;
-    }
-}
-
-#include "moc_qt7playerservice.cpp"
--- a/plugins/multimedia/qt7/qt7playersession.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT7PLAYERSESSION_H
-#define QT7PLAYERSESSION_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qset.h>
-
-#include <qmediaplayercontrol.h>
-#include <qmediaplayer.h>
-
-#include <QtGui/qmacdefines_mac.h>
-
-QT_BEGIN_NAMESPACE
-class QT7PlayerControl;
-class QMediaPlaylist;
-class QMediaPlaylistNavigator;
-class QT7VideoOutput;
-class QT7PlayerSession;
-class QT7PlayerService;
-
-
-class QT7PlayerSession : public QObject
-{
-Q_OBJECT
-public:
-    QT7PlayerSession(QObject *parent = 0);
-    ~QT7PlayerSession();
-
-    void *movie() const;
-
-    void setControl(QT7PlayerControl *control);
-
-    void setVideoOutput(QT7VideoOutput *output);
-
-    QMediaPlayer::State state() const;
-    QMediaPlayer::MediaStatus mediaStatus() const;
-
-    QMediaContent media() const;
-    const QIODevice *mediaStream() const;
-    void setMedia(const QMediaContent &content, QIODevice *stream);
-
-    qint64 position() const;
-    qint64 duration() const;
-
-    int bufferStatus() const;
-
-    int volume() const;
-    bool isMuted() const;
-
-    bool isAudioAvailable() const;
-    bool isVideoAvailable() const;
-
-    bool isSeekable() const;
-
-    qreal playbackRate() const;
-
-public slots:
-    void setPlaybackRate(qreal rate);
-
-    void setPosition(qint64 pos);
-
-    void play();
-    void pause();
-    void stop();
-
-    void setVolume(int volume);
-    void setMuted(bool muted);
-
-    void processEOS();
-    void processLoadStateChange();
-    void processVolumeChange();
-    void processNaturalSizeChange();
-
-signals:
-    void positionChanged(qint64 position);
-    void durationChanged(qint64 duration);
-    void stateChanged(QMediaPlayer::State newState);
-    void mediaStatusChanged(QMediaPlayer::MediaStatus status);
-    void volumeChanged(int volume);
-    void mutedChanged(bool muted);
-    void audioAvailableChanged(bool audioAvailable);
-    void videoAvailableChanged(bool videoAvailable);
-    void error(int error, const QString &errorString);
-
-private:
-    void openMovie(bool tryAsync);
-
-    void *m_QTMovie;
-    void *m_movieObserver;
-
-    QMediaPlayer::State m_state;
-    QMediaPlayer::MediaStatus m_mediaStatus;
-    QIODevice *m_mediaStream;
-    QMediaContent m_resources;
-
-    QT7VideoOutput * m_videoOutput;
-
-    mutable qint64 m_currentTime;
-
-    bool m_muted;
-    bool m_tryingAsync;
-    int m_volume;
-    qreal m_rate;
-
-    qint64 m_duration;
-    bool m_videoAvailable;
-    bool m_audioAvailable;
-};
-
-QT_END_NAMESPACE
-
-#endif
--- a/plugins/multimedia/qt7/qt7playersession.mm	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,631 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <QTKit/QTDataReference.h>
-#import <QTKit/QTMovie.h>
-
-#include "qt7backend.h"
-
-#include "qt7playersession.h"
-#include "qt7playercontrol.h"
-#include "qt7videooutput.h"
-
-#include <QtNetwork/qnetworkcookie.h>
-#include <qmediaplaylistnavigator.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qurl.h>
-
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-@interface QTMovieObserver : NSObject
-{
-@private
-    QT7PlayerSession *m_session;
-    QTMovie *m_movie;
-}
-
-- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session;
-- (void) setMovie:(QTMovie *)movie;
-- (void) processEOS:(NSNotification *)notification;
-- (void) processLoadStateChange:(NSNotification *)notification;
-- (void) processVolumeChange:(NSNotification *)notification;
-- (void) processNaturalSizeChange :(NSNotification *)notification;
-@end
-
-@implementation QTMovieObserver
-
-- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session
-{
-    if (!(self = [super init]))
-        return nil;
-
-    self->m_session = session;
-    return self;
-}
-
-- (void) setMovie:(QTMovie *)movie
-{
-    if (m_movie == movie)
-        return;
-
-    if (m_movie) {
-        [[NSNotificationCenter defaultCenter] removeObserver:self];
-        [m_movie release];
-    }
-
-    m_movie = movie;
-
-    if (movie) {
-        [[NSNotificationCenter defaultCenter] addObserver:self
-                                                 selector:@selector(processEOS:)
-                                                     name:QTMovieDidEndNotification
-                                                   object:m_movie];
-
-        [[NSNotificationCenter defaultCenter] addObserver:self
-                                                 selector:@selector(processLoadStateChange:)
-                                                     name:QTMovieLoadStateDidChangeNotification
-                                                   object:m_movie];
-
-        [[NSNotificationCenter defaultCenter] addObserver:self
-                                                 selector:@selector(processVolumeChange:)
-                                                     name:QTMovieVolumeDidChangeNotification
-                                                   object:m_movie];
-
-        if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
-            [[NSNotificationCenter defaultCenter] addObserver:self
-                                                     selector:@selector(processNaturalSizeChange:)
-                                                         name:@"QTMovieNaturalSizeDidChangeNotification"
-                                                       object:m_movie];
-
-        }
-        else {
-            [[NSNotificationCenter defaultCenter] addObserver:self
-                                                     selector:@selector(processNaturalSizeChange:)
-                                                         name:QTMovieEditedNotification
-                                                       object:m_movie];
-        }
-
-        [movie retain];
-    }
-}
-
-- (void) processEOS:(NSNotification *)notification
-{
-    Q_UNUSED(notification);
-    QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection);
-}
-
-- (void) processLoadStateChange:(NSNotification *)notification
-{
-    Q_UNUSED(notification);
-    QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection);
-}
-
-- (void) processVolumeChange:(NSNotification *)notification
-{
-    Q_UNUSED(notification);
-    QMetaObject::invokeMethod(m_session, "processVolumeChange", Qt::AutoConnection);
-}
-
-- (void) processNaturalSizeChange :(NSNotification *)notification
-{
-    Q_UNUSED(notification);
-    QMetaObject::invokeMethod(m_session, "processNaturalSizeChange", Qt::AutoConnection);
-}
-
-@end
-
-static inline NSString *qString2CFStringRef(const QString &string)
-{
-    return [NSString stringWithCharacters:reinterpret_cast<const UniChar *>(string.unicode()) length:string.length()];
-}
-
-QT7PlayerSession::QT7PlayerSession(QObject *parent)
-   : QObject(parent)
-   , m_QTMovie(0)
-   , m_state(QMediaPlayer::StoppedState)
-   , m_mediaStatus(QMediaPlayer::NoMedia)
-   , m_mediaStream(0)
-   , m_videoOutput(0)
-   , m_muted(false)
-   , m_tryingAsync(false)
-   , m_volume(100)
-   , m_rate(1.0)
-   , m_duration(0)
-   , m_videoAvailable(false)
-   , m_audioAvailable(false)
-{
-    m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this];
-}
-
-QT7PlayerSession::~QT7PlayerSession()
-{
-    [(QTMovieObserver*)m_movieObserver setMovie:nil];
-    [(QTMovieObserver*)m_movieObserver release];
-    [(QTMovie*)m_QTMovie release];
-}
-
-void *QT7PlayerSession::movie() const
-{
-    return m_QTMovie;
-}
-
-void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output)
-{
-    if (m_videoOutput == output)
-        return;
-
-    if (m_videoOutput)
-        m_videoOutput->setMovie(0);
-
-    m_videoOutput = output;
-
-    if (m_videoOutput && m_state != QMediaPlayer::StoppedState)
-        m_videoOutput->setMovie(m_QTMovie);
-}
-
-qint64 QT7PlayerSession::position() const
-{
-    if (!m_QTMovie || m_state == QMediaPlayer::PausedState)
-        return m_currentTime;
-
-    QTTime qtTime = [(QTMovie*)m_QTMovie currentTime];
-    quint64 t = static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
-    m_currentTime = t;
-
-    return m_currentTime;
-}
-
-qint64 QT7PlayerSession::duration() const
-{
-    if (!m_QTMovie)
-        return 0;
-
-    QTTime qtTime = [(QTMovie*)m_QTMovie duration];
-
-    return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f);
-}
-
-QMediaPlayer::State QT7PlayerSession::state() const
-{
-    return m_state;
-}
-
-QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const
-{
-    return m_mediaStatus;
-}
-
-int QT7PlayerSession::bufferStatus() const
-{
-    return 100;
-}
-
-int QT7PlayerSession::volume() const
-{
-    return m_volume;
-}
-
-bool QT7PlayerSession::isMuted() const
-{
-    return m_muted;
-}
-
-bool QT7PlayerSession::isSeekable() const
-{
-    return true;
-}
-
-qreal QT7PlayerSession::playbackRate() const
-{
-    return m_rate;
-}
-
-void QT7PlayerSession::setPlaybackRate(qreal rate)
-{
-    if (qFuzzyCompare(m_rate, rate))
-        return;
-
-    m_rate = rate;
-
-    if (m_QTMovie != 0 && m_state == QMediaPlayer::PlayingState) {
-        AutoReleasePool pool;
-        float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
-        [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
-    }
-}
-
-void QT7PlayerSession::setPosition(qint64 pos)
-{
-    if ( !isSeekable() || pos == position())
-        return;
-
-    pos = qMin(pos, duration());
-
-    QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime];
-    newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale;
-    [(QTMovie*)m_QTMovie setCurrentTime:newQTTime];
-}
-
-void QT7PlayerSession::play()
-{
-    if (m_state == QMediaPlayer::PlayingState)
-        return;
-
-    m_state = QMediaPlayer::PlayingState;
-
-    if (m_videoOutput)
-        m_videoOutput->setMovie(m_QTMovie);
-
-    AutoReleasePool pool;
-    float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
-    [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
-
-    emit stateChanged(m_state);
-}
-
-void QT7PlayerSession::pause()
-{
-    if (m_state == QMediaPlayer::PausedState)
-        return;
-
-    m_state = QMediaPlayer::PausedState;
-
-    if (m_videoOutput)
-        m_videoOutput->setMovie(m_QTMovie);
-
-    [(QTMovie*)m_QTMovie setRate:0];
-
-    emit stateChanged(m_state);
-}
-
-void QT7PlayerSession::stop()
-{
-    if (m_state == QMediaPlayer::StoppedState)
-        return;
-
-    m_state = QMediaPlayer::StoppedState;
-
-    [(QTMovie*)m_QTMovie setRate:0];
-    setPosition(0);
-
-    if (m_videoOutput)
-        m_videoOutput->setMovie(0);
-
-    emit stateChanged(m_state);
-}
-
-void QT7PlayerSession::setVolume(int volume)
-{
-    if (m_volume == volume)
-        return;
-
-    m_volume = volume;
-
-    if (m_QTMovie != 0)
-        [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
-    else
-        emit volumeChanged(m_volume);
-}
-
-void QT7PlayerSession::setMuted(bool muted)
-{
-    if (m_muted == muted)
-        return;
-
-    m_muted = muted;
-
-    if (m_QTMovie != 0)
-        [(QTMovie*)m_QTMovie setMuted:m_muted];
-
-    emit mutedChanged(muted);
-}
-
-QMediaContent QT7PlayerSession::media() const
-{
-    return m_resources;
-}
-
-const QIODevice *QT7PlayerSession::mediaStream() const
-{
-    return m_mediaStream;
-}
-
-void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream)
-{
-    AutoReleasePool pool;
-
-#ifdef QT_DEBUG_QT7
-    qDebug() << Q_FUNC_INFO << content.canonicalUrl();
-#endif
-
-    if (m_QTMovie) {
-        [(QTMovieObserver*)m_movieObserver setMovie:nil];
-
-        if (m_videoOutput)
-            m_videoOutput->setMovie(0);
-
-        [(QTMovie*)m_QTMovie release];
-        m_QTMovie = 0;
-    }
-
-    m_resources = content;
-    m_mediaStream = stream;
-    m_mediaStatus = QMediaPlayer::NoMedia;
-
-    if (content.isNull())
-        return;
-
-    QNetworkRequest request = content.canonicalResource().request();
-
-    QVariant cookies = request.header(QNetworkRequest::CookieHeader);
-    if (cookies.isValid()) {
-        NSHTTPCookieStorage *store = [NSHTTPCookieStorage sharedHTTPCookieStorage];
-        QList<QNetworkCookie> cookieList = cookies.value<QList<QNetworkCookie> >();
-
-        foreach (const QNetworkCookie &requestCookie, cookieList) {
-            NSMutableDictionary *p = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-                               qString2CFStringRef(requestCookie.name()), NSHTTPCookieName,
-                               qString2CFStringRef(requestCookie.value()), NSHTTPCookieValue,
-                               qString2CFStringRef(requestCookie.domain()), NSHTTPCookieDomain,
-                               qString2CFStringRef(requestCookie.path()), NSHTTPCookiePath,
-                               nil
-                               ];
-            if (requestCookie.isSessionCookie())
-                [p setObject:[NSString stringWithUTF8String:"TRUE"] forKey:NSHTTPCookieDiscard];
-            else
-                [p setObject:[NSDate dateWithTimeIntervalSince1970:requestCookie.expirationDate().toTime_t()] forKey:NSHTTPCookieExpires];
-
-            [store setCookie:[NSHTTPCookie cookieWithProperties:p]];
-        }
-    }
-
-    // Attempt multiple times to open the movie.
-    // First try - attempt open in async mode
-    openMovie(true);
-}
-
-void QT7PlayerSession::openMovie(bool tryAsync)
-{
-    QUrl requestUrl = m_resources.canonicalResource().request().url();
-    if (requestUrl.scheme().isEmpty())
-        requestUrl.setScheme(QLatin1String("file"));
-
-#ifdef QT_DEBUG_QT7
-    qDebug() << Q_FUNC_INFO << requestUrl;
-#endif
-
-    NSError *err = 0;
-    NSString *urlString = [NSString stringWithUTF8String:requestUrl.toEncoded().constData()];
-
-    NSMutableDictionary *attr = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-                [NSURL URLWithString:urlString], QTMovieURLAttribute,
-                [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute,
-                [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute,
-                [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute,
-                [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute,
-                nil];
-
-    if (tryAsync && QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
-        [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenAsyncRequiredAttribute"];
-// XXX: This is disabled for now. causes some problems with video playback for some formats
-//        [attr setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
-        m_tryingAsync = true;
-    }
-    else
-        m_tryingAsync = false;
-
-    m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
-    if (err != nil) {
-        // First attempt to test for inability to perform async
-//        if ([err code] == QTErrorMovieOpeningCannotBeAsynchronous) { XXX: error code unknown!
-        if (m_tryingAsync) {
-            m_tryingAsync = false;
-            err = nil;
-            [attr removeObjectForKey:@"QTMovieOpenAsyncRequiredAttribute"];
-            m_QTMovie = [QTMovie movieWithAttributes:attr error:&err];
-        }
-    }
-
-    if (err != nil) {
-        m_QTMovie = 0;
-        QString description = QString::fromUtf8([[err localizedDescription] UTF8String]);
-        emit error(QMediaPlayer::FormatError, description);
-
-#ifdef QT_DEBUG_QT7
-        qDebug() << Q_FUNC_INFO << description;
-#endif
-    }
-    else {
-        [(QTMovie*)m_QTMovie retain];
-
-        [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie];
-
-        if (m_state != QMediaPlayer::StoppedState && m_videoOutput)
-            m_videoOutput->setMovie(m_QTMovie);
-
-        processLoadStateChange();
-
-        [(QTMovie*)m_QTMovie setMuted:m_muted];
-        [(QTMovie*)m_QTMovie setVolume:m_volume / 100.0f];
-    }
-}
-
-bool QT7PlayerSession::isAudioAvailable() const
-{
-    if (!m_QTMovie)
-        return false;
-
-    AutoReleasePool pool;
-    return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES;
-}
-
-bool QT7PlayerSession::isVideoAvailable() const
-{
-    if (!m_QTMovie)
-        return false;
-
-    AutoReleasePool pool;
-    return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES;
-}
-
-void QT7PlayerSession::processEOS()
-{
-#ifdef QT_DEBUG_QT7
-    qDebug() << Q_FUNC_INFO;
-#endif
-    m_mediaStatus = QMediaPlayer::EndOfMedia;
-    if (m_videoOutput)
-        m_videoOutput->setMovie(0);
-    emit stateChanged(m_state = QMediaPlayer::StoppedState);
-    emit mediaStatusChanged(m_mediaStatus);
-}
-
-void QT7PlayerSession::processLoadStateChange()
-{
-    if (!m_QTMovie)
-        return;
-
-    AutoReleasePool pool;
-
-    long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] longValue];
-
-#ifdef QT_DEBUG_QT7
-    qDebug() << Q_FUNC_INFO << state;
-#endif
-
-#ifndef QUICKTIME_C_API_AVAILABLE
-    enum {
-      kMovieLoadStateError          = -1L,
-      kMovieLoadStateLoading        = 1000,
-      kMovieLoadStateLoaded         = 2000,
-      kMovieLoadStatePlayable       = 10000,
-      kMovieLoadStatePlaythroughOK  = 20000,
-      kMovieLoadStateComplete       = 100000
-    };
-#endif
-
-    if (state == kMovieLoadStateError) {
-        if (m_tryingAsync) {
-            NSError *error = [(QTMovie*)m_QTMovie attributeForKey:@"QTMovieLoadStateErrorAttribute"];
-            if ([error code] == componentNotThreadSafeErr) {
-                // Last Async check, try again with no such flag
-                openMovie(false);
-            }
-        }
-        else {
-            if (m_videoOutput)
-                m_videoOutput->setMovie(0);
-
-            emit error(QMediaPlayer::FormatError, tr("Failed to load media"));
-            emit mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
-            emit stateChanged(m_state = QMediaPlayer::StoppedState);
-        }
-
-        return;
-    }
-
-    QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia;
-    bool isPlaying = (m_state != QMediaPlayer::StoppedState);
-
-    if (state >= kMovieLoadStatePlaythroughOK) {
-        newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
-    } else if (state >= kMovieLoadStatePlayable)
-        newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia;
-    else if (state >= kMovieLoadStateLoading)
-        newStatus = isPlaying ? QMediaPlayer::StalledMedia : QMediaPlayer::LoadingMedia;
-
-    if (state >= kMovieLoadStatePlayable &&
-        m_state == QMediaPlayer::PlayingState &&
-        [(QTMovie*)m_QTMovie rate] == 0) {
-
-        float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue];
-
-        [(QTMovie*)m_QTMovie setRate:preferredRate * m_rate];
-    }
-
-    if (state >= kMovieLoadStateLoaded) {
-        qint64 currentDuration = duration();
-        if (m_duration != currentDuration)
-            emit durationChanged(m_duration = currentDuration);
-
-        if (m_audioAvailable != isAudioAvailable())
-            emit audioAvailableChanged(m_audioAvailable = !m_audioAvailable);
-
-        if (m_videoAvailable != isVideoAvailable())
-            emit videoAvailableChanged(m_videoAvailable = !m_videoAvailable);
-    }
-
-    if (newStatus != m_mediaStatus)
-        emit mediaStatusChanged(m_mediaStatus = newStatus);
-}
-
-void QT7PlayerSession::processVolumeChange()
-{
-    if (!m_QTMovie)
-        return;
-
-    int newVolume = qRound(100.0f * [((QTMovie*)m_QTMovie) volume]);
-
-    if (newVolume != m_volume) {
-        emit volumeChanged(m_volume = newVolume);
-    }
-}
-
-void QT7PlayerSession::processNaturalSizeChange()
-{
-    AutoReleasePool pool;
-    NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue];
-#ifdef QT_DEBUG_QT7
-    qDebug() << Q_FUNC_INFO << QSize(size.width, size.height);
-#endif
-
-    if (m_videoOutput)
-        m_videoOutput->updateNaturalSize(QSize(size.width, size.height));
-}
-
-#include "moc_qt7playersession.cpp"
--- a/plugins/multimedia/qt7/qt7serviceplugin.mm	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/multimedia/qt7/qt7serviceplugin.mm	Mon Oct 04 01:37:06 2010 +0300
@@ -51,7 +51,11 @@
 
 QStringList QT7ServicePlugin::keys() const
 {
-    return QStringList() << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER);
+    return QStringList()
+#ifdef QMEDIA_QT7_PLAYER
+        << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)
+#endif
+        ;
 }
 
 QMediaService* QT7ServicePlugin::create(QString const& key)
@@ -59,9 +63,10 @@
 #ifdef QT_DEBUG_QT7
     qDebug() << "QT7ServicePlugin::create" << key;
 #endif
+#ifdef QMEDIA_QT7_PLAYER
     if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
         return new QT7PlayerService;
-
+#endif
     qWarning() << "unsupported key:" << key;
 
     return 0;
--- a/plugins/multimedia/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/multimedia/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h	Mon Oct 04 01:37:06 2010 +0300
@@ -71,6 +71,9 @@
     bool isMuted() const;
     void applySettings();
 
+Q_SIGNALS:
+    void durationChanged(qint64 position);
+
 public Q_SLOTS:
     void record();
     void pause();
--- a/plugins/plugins.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/plugins.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -5,5 +5,6 @@
 contains(mobility_modules,contacts): SUBDIRS += contacts
 contains(mobility_modules,multimedia): SUBDIRS += multimedia
 contains(mobility_modules,sensors): SUBDIRS += sensors
+contains(mobility_modules,versit): SUBDIRS += versit
 
 #contains(QT_CONFIG,declarative): SUBDIRS += declarative
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/sensors/maemo6/Sensors.conf	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,9 @@
+[Default]
+QAccelerometer=maemo6.accelerometer
+QAmbientLightSensor=maemo6.als
+QCompass=maemo6.compass
+QMagnetometer=maemo6.magnetometer
+QOrientationSensor=maemo6.orientationsensor
+QProximitySensor=maemo6.proximity
+QRotationSensor=maemo6.rotationsensor
+QTapSensor=maemo6.tapsensor
--- a/plugins/sensors/maemo6/maemo6.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -15,3 +15,7 @@
 MOBILITY += sensors
 CONFIG += link_pkgconfig
 PKGCONFIG += sensord
+
+CONFIGFILES.files = Sensors.conf
+CONFIGFILES.path = /etc/xdg/Nokia/
+INSTALLS += CONFIGFILES
--- a/plugins/sensors/maemo6/maemo6accelerometer.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6accelerometer.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -49,7 +49,7 @@
 {
     const QString sensorName = "accelerometersensor";
     initSensor<AccelerometerSensorChannelInterface>(sensorName, m_initDone);
-
+    setRanges(GRAVITY_EARTH_THOUSANDTH);
 
     if (m_sensorInterface){
         if (!(QObject::connect(m_sensorInterface, SIGNAL(dataAvailable(const XYZ&)),
--- a/plugins/sensors/maemo6/maemo6als.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6als.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -60,9 +60,8 @@
         qWarning() << "Unable to initialize "<<sensorName;
     setReading<QAmbientLightReading>(&m_reading);
     // metadata
-    addDataRate(10, 10); // 10 Hz
     addOutputRange(0, 5, 1);
-    setDescription(QLatin1String("Ambient light intensity given as 5 pre-defined levels"));
+    setDescription(QLatin1String("ambient light intensity given as 5 pre-defined levels"));
 }
 
 void maemo6als::slotDataAvailable(const Unsigned& data)
--- a/plugins/sensors/maemo6/maemo6magnetometer.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6magnetometer.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -43,6 +43,8 @@
 
 char const * const maemo6magnetometer::id("maemo6.magnetometer");
 bool maemo6magnetometer::m_initDone = false;
+const float maemo6magnetometer::NANO = 0.000000001;
+
 
 maemo6magnetometer::maemo6magnetometer(QSensor *sensor)
     : maemo6sensorbase(sensor)
@@ -50,6 +52,7 @@
     const QString sensorName = "magnetometersensor";
     initSensor<MagnetometerSensorChannelInterface>(sensorName, m_initDone);
 
+    setRanges(NANO);
 
     if (m_sensorInterface){
         if (!(QObject::connect(m_sensorInterface, SIGNAL(dataAvailable(const MagneticField&)),
@@ -72,17 +75,13 @@
 void maemo6magnetometer::slotDataAvailable(const MagneticField& data)
 {
 
-    if (m_isGeoMagnetometer){
-        m_reading.setX( 0.0000003 * data.x() );
-        m_reading.setY( 0.0000003 * data.y() );
-        m_reading.setZ( 0.0000003 * data.z() );
-        m_reading.setCalibrationLevel( ((float) data.level()) / 3.0 );
-    } else {
-        m_reading.setX( 0.0000003 * data.rx() );
-        m_reading.setY( 0.0000003 * data.ry() );
-        m_reading.setZ( 0.0000003 * data.rz() );
-        m_reading.setCalibrationLevel(1);
-    }
+    //nanoTeslas given, divide with 10^9 to get Teslas
+    m_reading.setX( NANO * m_isGeoMagnetometer?data.x():data.rx());
+    m_reading.setY( NANO * m_isGeoMagnetometer?data.y():data.ry());
+    m_reading.setZ( NANO * m_isGeoMagnetometer?data.z():data.rz());
+    m_reading.setCalibrationLevel( m_isGeoMagnetometer?((float) data.level()) / 3.0 :1);
+
+
     m_reading.setTimestamp(data.timestamp());
     newReadingAvailable();
 }
--- a/plugins/sensors/maemo6/maemo6magnetometer.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6magnetometer.h	Mon Oct 04 01:37:06 2010 +0300
@@ -62,6 +62,7 @@
     virtual void start();
 
 private:
+    static const float NANO;
     QMagnetometerReading m_reading;
     static bool m_initDone;
     bool m_isGeoMagnetometer;
--- a/plugins/sensors/maemo6/maemo6sensorbase.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6sensorbase.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -91,3 +91,16 @@
     if (m_sensorInterface)
         m_sensorInterface->stop();
 }
+
+
+void maemo6sensorbase::setRanges(qreal correctionFactor){
+    int l = m_sensorInterface->getAvailableDataRanges().size();
+
+    for (int i=0; i<l; i++){
+        qreal rangeMin = ((DataRange)(m_sensorInterface->getAvailableDataRanges().at(i))).min * correctionFactor;
+        qreal rangeMax =((DataRange)(m_sensorInterface->getAvailableDataRanges().at(i))).max * correctionFactor;
+        qreal resolution = ((DataRange)(m_sensorInterface->getAvailableDataRanges().at(i))).resolution * correctionFactor;
+        addOutputRange(rangeMin, rangeMax, resolution);
+    }
+
+}
--- a/plugins/sensors/maemo6/maemo6sensorbase.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/maemo6/maemo6sensorbase.h	Mon Oct 04 01:37:06 2010 +0300
@@ -63,6 +63,8 @@
     static const float GRAVITY_EARTH;
     static const float GRAVITY_EARTH_THOUSANDTH;    //for speed
 
+    void setRanges(qreal correctionFactor);
+
     template<typename T>
     void initSensor(QString sensorName, bool &initDone)
     {
@@ -78,8 +80,6 @@
 
         initDone = true;
 
-        if (sensorName=="alssensor") return; // SensorFW returns lux values, plugin enumerated values
-
 
         //metadata
         int l = m_sensorInterface->getAvailableIntervals().size();
@@ -94,15 +94,14 @@
             addDataRate(rateMin, rateMax);
         }
 
-        l = m_sensorInterface->getAvailableDataRanges().size();
+        if (sensorName=="alssensor") return;                // SensorFW returns lux values, plugin enumerated values
+
+        setDescription(m_sensorInterface->property("description").toString());
 
-        for (int i=0; i<l; i++){
-            qreal rangeMin = ((DataRange)(m_sensorInterface->getAvailableDataRanges().at(i))).min;
-            qreal rangeMax =((DataRange)(m_sensorInterface->getAvailableDataRanges().at(i))).max;
-            qreal resolution = ((DataRange)(m_sensorInterface->getAvailableDataRanges().at(i))).min;
-            addOutputRange(rangeMin, rangeMax, resolution);
-        }
-        setDescription(m_sensorInterface->property("description").toString());
+        if (sensorName=="accelerometersensor") return;      // SensorFW returns milliGs, plugin m/s^2
+        if (sensorName=="magnetometersensor") return;       // SensorFW returns nanoTeslas, plugin Teslas
+
+        setRanges(1);
     };
 
 private:
--- a/plugins/sensors/s60_sensor_api/s60_sensor_api.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/plugins/sensors/s60_sensor_api/s60_sensor_api.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -9,7 +9,7 @@
 include(s60_sensor_api.pri)
 include(version.pri)
 
-TARGET = $$qtLibraryTarget(qtsensors_s60sensorapi)
+TARGET = $$qtLibraryTarget(qtsensors_sym)
 TARGET.EPOCALLOWDLLDATA = 1
 TARGET.UID3 = 0x2002BFC1
 TARGET.CAPABILITY = ALL -TCB
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/versit/backuphandler/backuphandler.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,22 @@
+TEMPLATE = lib
+CONFIG += plugin
+TARGET = $$qtLibraryTarget(qtversit_backuphandler)
+PLUGIN_TYPE=versit
+
+include(../../../common.pri)
+
+HEADERS += backupvcardhandler.h
+SOURCES += backupvcardhandler.cpp
+
+INCLUDEPATH += \
+               $$SOURCE_DIR/src/contacts \
+               $$SOURCE_DIR/src/contacts/details \
+               $$SOURCE_DIR/src/contacts/filters \
+               $$SOURCE_DIR/src/contacts/requests \
+               $$SOURCE_DIR/src/versit
+CONFIG += mobility
+MOBILITY = versit contacts
+
+symbian {
+    TARGET.EPOCALLOWDLLDATA = 1
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/versit/backuphandler/backupvcardhandler.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,387 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+#include <QString>
+#include <QTextStream>
+#include <QUrl>
+#include "backupvcardhandler.h"
+#include "qcontact.h"
+#include "qcontactdetail.h"
+#include "qversitdocument.h"
+#include "qversitproperty.h"
+
+QTM_USE_NAMESPACE
+
+/*
+ * This is a map from Versit group names to the details that were generated from properties with the
+ * said groups.  Multiple details can be associated with a single group.
+ */
+class DetailGroupMap
+{
+public:
+    QList<QContactDetail> detailsInGroup(const QString& groupName) const;
+    void insert(const QString& groupName, const QContactDetail& detail);
+    void update(const QContactDetail& detail);
+    void clear();
+
+private:
+    QHash<int, QString> mDetailGroupName; // detailid -> group name
+    QHash<int, QContactDetail> mDetailById; // detailid -> detail
+};
+
+/* See QVersitContactImporter::createBackupHandler() */
+class BackupVCardHandler : public QVersitContactHandler
+{
+public:
+    BackupVCardHandler();
+    void propertyProcessed(const QVersitDocument& document,
+                           const QVersitProperty& property,
+                           const QContact& contact,
+                           bool* alreadyProcessed,
+                           QList<QContactDetail>* updatedDetails);
+    void documentProcessed(const QVersitDocument& document,
+                           QContact* contact);
+    void detailProcessed(const QContact& contact,
+                         const QContactDetail& detail,
+                         const QVersitDocument& document,
+                         QSet<QString>* processedFields,
+                         QList<QVersitProperty>* toBeRemoved,
+                         QList<QVersitProperty>* toBeAdded);
+    void contactProcessed(const QContact& contact,
+                          QVersitDocument* document);
+
+private:
+    static QVariant deserializeValue(const QVersitProperty& property);
+    static void serializeValue(QVersitProperty* property, const QVariant& value);
+    DetailGroupMap mDetailGroupMap; // remembers which details came from which groups
+    int mDetailNumber;
+};
+
+Q_DEFINE_LATIN1_CONSTANT(PropertyName, "X-NOKIA-QCONTACTFIELD");
+Q_DEFINE_LATIN1_CONSTANT(DetailDefinitionParameter, "DETAIL");
+Q_DEFINE_LATIN1_CONSTANT(FieldParameter, "FIELD");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameter, "DATATYPE");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterVariant, "VARIANT");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterDate, "DATE");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterDateTime, "DATETIME");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterTime, "TIME");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterBool, "BOOL");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterInt, "INT");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterUInt, "UINT");
+Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterUrl, "URL");
+Q_DEFINE_LATIN1_CONSTANT(GroupPrefix, "G");
+
+QSet<QString> BackupVCardHandlerFactory::profiles() const
+{
+    QSet<QString> retval;
+    retval.insert(QVersitContactHandlerFactory::ProfileBackup);
+    return retval;
+}
+
+QString BackupVCardHandlerFactory::name() const
+{
+    return QLatin1String("com.nokia.qt.mobility.versit.backuphandler");
+}
+
+int BackupVCardHandlerFactory::index() const
+{
+    // Prefer to run this plugin last.
+    return -1;
+}
+
+QVersitContactHandler* BackupVCardHandlerFactory::createHandler() const
+{
+    return new BackupVCardHandler();
+}
+
+Q_EXPORT_PLUGIN2(qtversit_backuphandler, BackupVCardHandlerFactory);
+
+/*
+ * Returns a list of details generated from a Versit group.
+ */
+QList<QContactDetail> DetailGroupMap::detailsInGroup(const QString& groupName) const
+{
+    QList<int> detailIds = mDetailGroupName.keys(groupName);
+    QList<QContactDetail> details;
+    foreach (int detailId, detailIds) {
+        details << mDetailById[detailId];
+    }
+    return details;
+}
+
+/*
+ * Inserts the association between \a detail and \a groupName to the map.
+ * The detail must have a key (ie. have already been saved in a contact) and the group name must not
+ * be the empty string.
+ */
+void DetailGroupMap::insert(const QString& groupName, const QContactDetail& detail)
+{
+    Q_ASSERT(!groupName.isEmpty());
+    mDetailGroupName[detail.key()] = groupName;
+    mDetailById[detail.key()] = detail;
+}
+
+/*
+ * Replaces the detail currently in the map with \a detail.
+ * The detail must have a key (ie. have already been saved in a contact).
+ */
+void DetailGroupMap::update(const QContactDetail& detail)
+{
+    Q_ASSERT(detail.key());
+    mDetailById[detail.key()] = detail;
+}
+
+/*!
+ * Removes details and groups from the map.
+ */
+void DetailGroupMap::clear()
+{
+    mDetailGroupName.clear();
+    mDetailById.clear();
+}
+
+
+BackupVCardHandler::BackupVCardHandler()
+    : mDetailNumber(0)
+{
+}
+
+void BackupVCardHandler::propertyProcessed(
+        const QVersitDocument& document,
+        const QVersitProperty& property,
+        const QContact& contact,
+        bool* alreadyProcessed,
+        QList<QContactDetail>* updatedDetails)
+{
+    Q_UNUSED(document)
+    Q_UNUSED(contact)
+    QString group;
+    if (!property.groups().isEmpty())
+        group = property.groups().first();
+    if (!*alreadyProcessed) {
+        if (property.name() != PropertyName)
+            return;
+        if (property.groups().size() != 1)
+            return;
+        QMultiHash<QString,QString> parameters = property.parameters();
+        QString definitionName = parameters.value(DetailDefinitionParameter);
+        QString fieldName = parameters.value(FieldParameter);
+
+        // Find a detail previously seen with the same definitionName, which was generated from
+        // a property from the same group
+        QContactDetail detail(definitionName);
+        foreach (const QContactDetail& previousDetail, mDetailGroupMap.detailsInGroup(group)) {
+            if (previousDetail.definitionName() == definitionName) {
+                detail = previousDetail;
+            }
+        }
+        // If not found, it's a new empty detail with the definitionName set.
+
+        detail.setValue(fieldName, deserializeValue(property));
+
+        // Replace the equivalent detail in updatedDetails with the new one
+        QMutableListIterator<QContactDetail> it(*updatedDetails);
+        while (it.hasNext()) {
+            if (it.next().key() == detail.key()) {
+                it.remove();
+                break;
+            }
+        }
+        updatedDetails->append(detail);
+        *alreadyProcessed = true;
+    }
+    if (!group.isEmpty()) {
+        // Keep track of which details were generated from which Versit groups
+        foreach (const QContactDetail& detail, *updatedDetails) {
+            mDetailGroupMap.insert(group, detail);
+        }
+    }
+}
+
+QVariant BackupVCardHandler::deserializeValue(const QVersitProperty& property)
+{
+    // Import the field
+    if (property.parameters().contains(DatatypeParameter, DatatypeParameterVariant)) {
+        // The value was stored as a QVariant serialized in a QByteArray
+        QDataStream stream(property.variantValue().toByteArray());
+        QVariant value;
+        stream >> value;
+        return value;
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterDate)) {
+        // The value was a QDate serialized as a string
+        return QDate::fromString(property.value(), Qt::ISODate);
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterTime)) {
+        // The value was a QTime serialized as a string
+        return QTime::fromString(property.value(), Qt::ISODate);
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterDateTime)) {
+        // The value was a QDateTime serialized as a string
+        return QDateTime::fromString(property.value(), Qt::ISODate);
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterBool)) {
+        // The value was a bool serialized as a string
+        return property.value().toInt() != 0;
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterInt)) {
+        // The value was an int serialized as a string
+        return property.value().toInt();
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterUInt)) {
+        // The value was a uint serialized as a string
+        return property.value().toUInt();
+    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterUrl)) {
+        // The value was a QUrl serialized as a string
+        return QUrl(property.value());
+    } else {
+        // The value was stored as a QString or QByteArray
+        return property.variantValue();
+    }
+}
+
+void BackupVCardHandler::documentProcessed(
+        const QVersitDocument& document,
+        QContact* contact)
+{
+    Q_UNUSED(document)
+    Q_UNUSED(contact)
+    mDetailGroupMap.clear();
+}
+
+void BackupVCardHandler::detailProcessed(
+        const QContact& contact,
+        const QContactDetail& detail,
+        const QVersitDocument& document,
+        QSet<QString>* processedFields,
+        QList<QVersitProperty>* toBeRemoved,
+        QList<QVersitProperty>* toBeAdded)
+{
+    Q_UNUSED(contact)
+    Q_UNUSED(document)
+    Q_UNUSED(toBeRemoved)
+    if (detail.accessConstraints().testFlag(QContactDetail::ReadOnly))
+        return;
+    QVariantMap fields = detail.variantValues();
+    // fields from the same detail have the same group so the importer can collate them
+    QString detailGroup = GroupPrefix + QString::number(mDetailNumber++);
+    int toBeAddedCount = toBeAdded->count();
+    bool propertiesSynthesized = false;
+    for (QVariantMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); it++) {
+        if (!processedFields->contains(it.key()) && !it.value().toString().isEmpty()) {
+            // Generate a property for the unknown field
+            QVersitProperty property;
+            property.setGroups(QStringList(detailGroup));
+            property.setName(PropertyName);
+            property.insertParameter(DetailDefinitionParameter, detail.definitionName());
+            property.insertParameter(FieldParameter, it.key());
+
+            serializeValue(&property, it.value());
+
+            toBeAdded->append(property);
+            propertiesSynthesized = true;
+            processedFields->insert(it.key());
+        }
+    }
+    if (propertiesSynthesized) {
+        // We need to group the already-generated properties with the newly synthesized ones
+        for (int i = 0; i < toBeAddedCount; i++) {
+            QVersitProperty& property = (*toBeAdded)[i];
+            property.setGroups(property.groups() << detailGroup);
+        }
+    }
+}
+
+void BackupVCardHandler::serializeValue(QVersitProperty* property, const QVariant& value)
+{
+    // serialize the value
+    if (value.type() == QVariant::String
+        || value.type() == QVariant::ByteArray) {
+        // store QStrings and QByteArrays as-is
+        property->setValue(value);
+    } else if (value.type() == QVariant::Date) {
+        // Store a QDate as a string
+        QString valueString(value.toDate().toString(Qt::ISODate));
+        property->insertParameter(DatatypeParameter, DatatypeParameterDate);
+        property->setValue(valueString);
+    } else if (value.type() == QVariant::Time) {
+        // Store a QTime as a string
+        QString valueString(value.toTime().toString(Qt::ISODate));
+        property->insertParameter(DatatypeParameter, DatatypeParameterTime);
+        property->setValue(valueString);
+    } else if (value.type() == QVariant::DateTime) {
+        // Store a QDateTime as a string
+        QString valueString(value.toDateTime().toString(Qt::ISODate));
+        property->insertParameter(DatatypeParameter, DatatypeParameterDateTime);
+        property->setValue(valueString);
+    } else if (value.type() == QVariant::Bool) {
+        // Store an int as a string
+        QString valueString(QString::number(value.toBool() ? 1 : 0));
+        property->insertParameter(DatatypeParameter, DatatypeParameterBool);
+        property->setValue(valueString);
+    } else if (value.type() == QVariant::Int) {
+        // Store an int as a string
+        QString valueString(QString::number(value.toInt()));
+        property->insertParameter(DatatypeParameter, DatatypeParameterInt);
+        property->setValue(valueString);
+    } else if (value.type() == QVariant::UInt) {
+        // Store a uint as a string
+        QString valueString(QString::number(value.toUInt()));
+        property->insertParameter(DatatypeParameter, DatatypeParameterUInt);
+        property->setValue(valueString);
+    } else if (value.type() == QVariant::Url) {
+        // Store a QUrl as a string
+        QString valueString(value.toUrl().toString());
+        property->insertParameter(DatatypeParameter, DatatypeParameterUrl);
+        property->setValue(valueString);
+    } else {
+        // Store other types by serializing the QVariant in a QByteArray
+        QByteArray valueBytes;
+        QDataStream stream(&valueBytes, QIODevice::WriteOnly);
+        stream << value;
+        property->insertParameter(DatatypeParameter, DatatypeParameterVariant);
+        property->setValue(valueBytes);
+    }
+}
+
+void BackupVCardHandler::contactProcessed(
+        const QContact& contact,
+        QVersitDocument* document)
+{
+    Q_UNUSED(contact)
+    Q_UNUSED(document)
+    mDetailNumber = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/versit/backuphandler/backupvcardhandler.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TESTVCARDHANDLER_H
+#define TESTVCARDHANDLER_H
+
+#include <QObject>
+#include <QtPlugin>
+#include "qversitcontacthandler.h"
+
+QTM_USE_NAMESPACE
+
+class BackupVCardHandlerFactory : public QObject, public QVersitContactHandlerFactory
+{
+    Q_OBJECT
+    Q_INTERFACES(QtMobility::QVersitContactHandlerFactory)
+
+public:
+    QSet<QString> profiles() const;
+    QString name() const;
+    int index() const;
+    QVersitContactHandler* createHandler() const;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/versit/versit.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,7 @@
+TEMPLATE = subdirs
+
+CONFIG += ordered
+
+include(../../common.pri)
+
+SUBDIRS += backuphandler
--- a/qtmobility.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/qtmobility.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -45,10 +45,10 @@
 
     PRF_CONFIG=$${QT_MOBILITY_BUILD_TREE}/features/mobilityconfig.prf
     system(echo MOBILITY_CONFIG=$${mobility_modules} > $$PRF_CONFIG)
-    system(echo MOBILITY_VERSION = 1.0.2 >> $$PRF_CONFIG)
+    system(echo MOBILITY_VERSION = 1.0.3 >> $$PRF_CONFIG)
     system(echo MOBILITY_MAJOR_VERSION = 1 >> $$PRF_CONFIG)
     system(echo MOBILITY_MINOR_VERSION = 0 >> $$PRF_CONFIG)
-    system(echo MOBILITY_PATCH_VERSION = 2 >> $$PRF_CONFIG)
+    system(echo MOBILITY_PATCH_VERSION = 3 >> $$PRF_CONFIG)
 
     #symbian does not generate make install rule. we have to copy prf manually 
     symbian {
--- a/src/bearer/qnetworkmanagerservice_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/bearer/qnetworkmanagerservice_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -713,146 +713,80 @@
 
 NMDeviceType QNetworkManagerSettingsConnection::getType()
 {
-    QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("connection"));
-    while (i != d->settingsMap.end() && i.key() == QLatin1String("connection")) {
-        QMap<QString,QVariant> innerMap = i.value();
-        QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("type"));
-        while (ii != innerMap.end() && ii.key() == QLatin1String("type")) {
-            QString devType = ii.value().toString();
-            if (devType == QLatin1String("802-3-ethernet")) {
-                return 	DEVICE_TYPE_802_3_ETHERNET;
-            }
-            if (devType == QLatin1String("802-11-wireless")) {
-                return 	DEVICE_TYPE_802_11_WIRELESS;
-            }
-            ii++;
-        }
-        i++;
-    }
-    return 	DEVICE_TYPE_UNKNOWN;
+    const QString devType =
+        d->settingsMap.value(QLatin1String("connection")).value(QLatin1String("type")).toString();
+
+    if (devType == QLatin1String("802-3-ethernet"))
+        return DEVICE_TYPE_802_3_ETHERNET;
+    else if (devType == QLatin1String("802-11-wireless"))
+        return DEVICE_TYPE_802_11_WIRELESS;
+    else
+        return DEVICE_TYPE_UNKNOWN;
 }
 
 bool QNetworkManagerSettingsConnection::isAutoConnect()
 {
-    QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("connection"));
-    while (i != d->settingsMap.end() && i.key() == QLatin1String("connection")) {
-        QMap<QString,QVariant> innerMap = i.value();
-        QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("autoconnect"));
-        while (ii != innerMap.end() && ii.key() == QLatin1String("autoconnect")) {
-            return ii.value().toBool();
-            ii++;
-        }
-        i++;
-    }
-    return true; //default networkmanager is autoconnect
+    const QVariant autoConnect =
+        d->settingsMap.value(QLatin1String("connection")).value(QLatin1String("autoconnect"));
+
+    // NetworkManager default is to auto connect
+    if (!autoConnect.isValid())
+        return true;
+
+    return autoConnect.toBool();
 }
 
 quint64 QNetworkManagerSettingsConnection::getTimestamp()
 {
-    QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("connection"));
-    while (i != d->settingsMap.end() && i.key() == QLatin1String("connection")) {
-        QMap<QString,QVariant> innerMap = i.value();
-        QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("timestamp"));
-        while (ii != innerMap.end() && ii.key() == QLatin1String("timestamp")) {
-            return ii.value().toUInt();
-            ii++;
-        }
-        i++;
-    }
-    return 	0;
+    qDebug() << d->settingsMap.value(QLatin1String("connection"));
+
+    return d->settingsMap.value(QLatin1String("connection"))
+                         .value(QLatin1String("timestamp")).toUInt();
 }
 
 QString QNetworkManagerSettingsConnection::getId()
 {
-    QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("connection"));
-    while (i != d->settingsMap.end() && i.key() == QLatin1String("connection")) {
-        QMap<QString,QVariant> innerMap = i.value();
-        QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("id"));
-        while (ii != innerMap.end() && ii.key() == QLatin1String("id")) {
-            return ii.value().toString();
-            ii++;
-        }
-        i++;
-    }
-    return 	QString();
+    return d->settingsMap.value(QLatin1String("connection")).value(QLatin1String("id")).toString();
 }
 
 QString QNetworkManagerSettingsConnection::getUuid()
 {
-    QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("connection"));
-    while (i != d->settingsMap.end() && i.key() == QLatin1String("connection")) {
-        QMap<QString,QVariant> innerMap = i.value();
-        QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("uuid"));
-        while (ii != innerMap.end() && ii.key() == QLatin1String("uuid")) {
-            return ii.value().toString();
-            ii++;
-        }
-        i++;
-    }
+    const QString id = d->settingsMap.value(QLatin1String("connection"))
+                                     .value(QLatin1String("uuid")).toString();
+
     // is no uuid, return the connection path
-    return 	d->connectionInterface->path();
+    return id.isEmpty() ? d->connectionInterface->path() : id;
 }
 
 QString QNetworkManagerSettingsConnection::getSsid()
 {
-    QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("802-11-wireless"));
-    while (i != d->settingsMap.end() && i.key() == QLatin1String("802-11-wireless")) {
-        QMap<QString,QVariant> innerMap = i.value();
-        QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("ssid"));
-        while (ii != innerMap.end() && ii.key() == QLatin1String("ssid")) {
-            return ii.value().toString();
-            ii++;
-        }
-        i++;
-    }
-    return 	QString();
+    return d->settingsMap.value(QLatin1String("802-11-wireless"))
+                         .value(QLatin1String("ssid")).toString();
 }
 
 QString QNetworkManagerSettingsConnection::getMacAddress()
 {
-    if(getType() == DEVICE_TYPE_802_3_ETHERNET) {
-        QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("802-3-ethernet"));
-        while (i != d->settingsMap.end() && i.key() == QLatin1String("802-3-ethernet")) {
-            QMap<QString,QVariant> innerMap = i.value();
-            QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("mac-address"));
-            while (ii != innerMap.end() && ii.key() == QLatin1String("mac-address")) {
-                return ii.value().toString();
-                ii++;
-            }
-            i++;
-        }
-    }
+    NMDeviceType type = getType();
 
-    else if(getType() == DEVICE_TYPE_802_11_WIRELESS) {
-        QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("802-11-wireless"));
-        while (i != d->settingsMap.end() && i.key() == QLatin1String("802-11-wireless")) {
-            QMap<QString,QVariant> innerMap = i.value();
-            QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("mac-address"));
-            while (ii != innerMap.end() && ii.key() == QLatin1String("mac-address")) {
-                return ii.value().toString();
-                ii++;
-            }
-            i++;
-        }
+    if (type == DEVICE_TYPE_802_3_ETHERNET) {
+        return d->settingsMap.value(QLatin1String("802-3-ethernet"))
+                             .value(QLatin1String("mac-address")).toString();
+    } else if (type == DEVICE_TYPE_802_11_WIRELESS) {
+        return d->settingsMap.value(QLatin1String("802-11-wireless"))
+                             .value(QLatin1String("mac-address")).toString();
+    } else {
+        return QString();
     }
-    return 	QString();
 }
 
-QStringList  QNetworkManagerSettingsConnection::getSeenBssids()
+QStringList QNetworkManagerSettingsConnection::getSeenBssids()
 {
- if(getType() == DEVICE_TYPE_802_11_WIRELESS) {
-        QNmSettingsMap::const_iterator i = d->settingsMap.find(QLatin1String("802-11-wireless"));
-        while (i != d->settingsMap.end() && i.key() == QLatin1String("802-11-wireless")) {
-            QMap<QString,QVariant> innerMap = i.value();
-            QMap<QString,QVariant>::const_iterator ii = innerMap.find(QLatin1String("seen-bssids"));
-            while (ii != innerMap.end() && ii.key() == QLatin1String("seen-bssids")) {
-                return ii.value().toStringList();
-                ii++;
-            }
-            i++;
-        }
+    if (getType() == DEVICE_TYPE_802_11_WIRELESS) {
+        return d->settingsMap.value(QLatin1String("802-11-wireless"))
+                             .value(QLatin1String("seen-bssids")).toStringList();
+    } else {
+        return QStringList();
     }
- return QStringList();
 }
 
 class QNetworkManagerConnectionActivePrivate
--- a/src/contacts/qcontact.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/contacts/qcontact.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -374,15 +374,10 @@
 /*! Returns a list of details with the given \a definitionName
     The definitionName string can be determined by the DefinitionName attribute
     of defined objects (e.g. QContactPhoneNumber::DefinitionName) or by
-    requesting a list of all the definitions synchronously with
-    \l {QContactManager::detailDefinitions()}{detailDefinitions()} or
-    asynchronously with a
-    \l {QContactDetailDefinitionFetchRequest}{detail definition fetch request},
-    and then inspecting the
-    \l{QContactDetailDefinition::name()}{name()} of each
-    definition.  If \a definitionName is empty, all details of any definition
-    will be returned.
- */
+    requesting a list of all the definition names using
+    \l {QContactManager::detailDefinitions()}{detailDefinitions()} or the
+    asynchronous \l
+    {QContactDetailDefinitionFetchRequest::definitionNames()}{definitionNames()}.*/
 QList<QContactDetail> QContact::details(const QString& definitionName) const
 {
     // build the sub-list of matching details.
@@ -407,15 +402,10 @@
     Returns a list of details of the given \a definitionName, with fields named \a fieldName and with value \a value.
     The definitionName string can be determined by the DefinitionName attribute
     of defined objects (e.g. QContactPhoneNumber::DefinitionName) or by
-    requesting a list of all the definitions synchronously with
-    \l {QContactManager::detailDefinitions()}{detailDefinitions()} or
-    asynchronously with a
-    \l {QContactDetailDefinitionFetchRequest}{detail definition fetch request},
-    and then inspecting the
-    \l{QContactDetailDefinition::name()}{name()} of each
-    definition.  If \a definitionName is empty, all details of any definition
-    will be returned.
- */
+    requesting a list of all the definition names using
+    \l {QContactManager::detailDefinitions()}{detailDefinitions()} or the
+    asynchronous \l
+    {QContactDetailDefinitionFetchRequest::definitionNames()}{definitionNames()}.*/
 QList<QContactDetail> QContact::details(const QString& definitionName, const QString& fieldName, const QString& value) const
 {
     // build the sub-list of matching details.
--- a/src/contacts/qcontactabstractrequest.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/contacts/qcontactabstractrequest.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -308,10 +308,6 @@
     If \a msecs is zero, this function will block indefinitely.
     Returns true if the request was cancelled or completed successfully within the given period, otherwise false.
     Some backends are unable to support this operation safely, and will return false immediately.
-
-    Note that any signals generated while waiting for the request to complete may be queued and delivered
-    some time after this function has returned, when the calling thread's event loop is dispatched.  If your code
-    depends on your slots being invoked, you may need to process events after calling this function.
  */
 bool QContactAbstractRequest::waitForFinished(int msecs)
 {
--- a/src/global/qmobilityglobal.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/global/qmobilityglobal.h	Mon Oct 04 01:37:06 2010 +0300
@@ -42,13 +42,13 @@
 #define QMOBILITYGLOBAL_H
 
 
-#define QTM_VERSION_STR   "1.0.2"
+#define QTM_VERSION_STR   "1.0.3"
 /*
    QTM_VERSION is (major << 16) + (minor << 8) + patch.
 */
-#define QTM_VERSION 0x010002
+#define QTM_VERSION 0x010003
 /*
-   can be used like #if (QTM_VERSION >= QTM_VERSION_CHECK(1, 0, 2))
+   can be used like #if (QTM_VERSION >= QTM_VERSION_CHECK(1, 0, 3))
 */
 #define QTM_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
 
--- a/src/global/qmobilitypluginsearch.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/global/qmobilitypluginsearch.h	Mon Oct 04 01:37:06 2010 +0300
@@ -38,8 +38,12 @@
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
+#ifndef QMOBILITYPLUGINSEARCH_H
+#define QMOBILITYPLUGINSEARCH_H
+
 #include <QApplication>
 #include <QStringList>
+#include <QDir>
 
 #if defined(Q_OS_SYMBIAN)
 # include <f32file.h>
@@ -47,62 +51,92 @@
 
 QTM_BEGIN_NAMESPACE
 
-class DirChecker
-{
-public:
-    DirChecker();
-    ~DirChecker();
-    bool checkDir(const QDir& dir);
+//class DirChecker
+//{
+//public:
+//    DirChecker();
+//    ~DirChecker();
+//    bool checkDir(const QDir& dir);
+
+//private:
+//#if defined(Q_OS_SYMBIAN)
+//    RFs rfs;
+//#endif
+//};
+
+//#if defined(Q_OS_SYMBIAN)
+//DirChecker::DirChecker()
+//{
+//    qt_symbian_throwIfError(rfs.Connect());
+//}
 
-private:
-#if defined(Q_OS_SYMBIAN)
-    RFs rfs;
-#endif
-};
+//bool DirChecker::checkDir(const QDir& dir)
+//{
+//    bool pathFound = false;
+//    // In Symbian, going cdUp() in a c:/private/<uid3>/ will result in *platsec* error at fileserver (requires AllFiles capability)
+//    // Also, trying to cd() to a nonexistent directory causes *platsec* error. This does not cause functional harm, but should
+//    // nevertheless be changed to use native Symbian methods to avoid unnecessary platsec warnings (as per qpluginloader.cpp).
+//    // Use native Symbian code to check for directory existence, because checking
+//    // for files from under non-existent protected dir like E:/private/<uid> using
+//    // QDir::exists causes platform security violations on most apps.
+//    QString nativePath = QDir::toNativeSeparators(dir.absolutePath());
+//    TPtrC ptr = TPtrC16(static_cast<const TUint16*>(nativePath.utf16()), nativePath.length());
+//    TUint attributes;
+//    TInt err = rfs.Att(ptr, attributes);
+//    if (err == KErrNone) {
+//        // yes, the directory exists.
+//        pathFound = true;
+//    }
+//    return pathFound;
+//}
+
+//DirChecker::~DirChecker()
+//{
+//    rfs.Close();
+//}
+//#else
+//DirChecker::DirChecker()
+//{
+//}
+
+//DirChecker::~DirChecker()
+//{
+//}
+
+//bool DirChecker::checkDir(const QDir &dir)
+//{
+//    return dir.exists();
+//}
+//#endif
 
 #if defined(Q_OS_SYMBIAN)
-DirChecker::DirChecker()
-{
-    qt_symbian_throwIfError(rfs.Connect());
-}
-
-bool DirChecker::checkDir(const QDir& dir)
-{
-    bool pathFound = false;
-    // In Symbian, going cdUp() in a c:/private/<uid3>/ will result in *platsec* error at fileserver (requires AllFiles capability)
-    // Also, trying to cd() to a nonexistent directory causes *platsec* error. This does not cause functional harm, but should
-    // nevertheless be changed to use native Symbian methods to avoid unnecessary platsec warnings (as per qpluginloader.cpp).
-    // Use native Symbian code to check for directory existence, because checking
-    // for files from under non-existent protected dir like E:/private/<uid> using
-    // QDir::exists causes platform security violations on most apps.
-    QString nativePath = QDir::toNativeSeparators(dir.absolutePath());
-    TPtrC ptr = TPtrC16(static_cast<const TUint16*>(nativePath.utf16()), nativePath.length());
-    TUint attributes;
-    TInt err = rfs.Att(ptr, attributes);
-    if (err == KErrNone) {
-        // yes, the directory exists.
-        pathFound = true;
+    inline bool checkMobilityPluginsDir(const QDir &dir)
+    {
+        RFs rfs;
+        qt_symbian_throwIfError(rfs.Connect());
+        bool pathFound = false;
+        // In Symbian, going cdUp() in a c:/private/<uid3>/ will result in *platsec* error at fileserver (requires AllFiles capability)
+        // Also, trying to cd() to a nonexistent directory causes *platsec* error. This does not cause functional harm, but should
+        // nevertheless be changed to use native Symbian methods to avoid unnecessary platsec warnings (as per qpluginloader.cpp).
+        // Use native Symbian code to check for directory existence, because checking
+        // for files from under non-existent protected dir like E:/private/<uid> using
+        // QDir::exists causes platform security violations on most apps.
+        QString nativePath = QDir::toNativeSeparators(dir.absolutePath());
+        TPtrC ptr = TPtrC16(static_cast<const TUint16*>(nativePath.utf16()), nativePath.length());
+        TUint attributes;
+        TInt err = rfs.Att(ptr, attributes);
+        if (err == KErrNone) {
+            // yes, the directory exists.
+            pathFound = true;
+        }
+        rfs.Close();
+        return pathFound;
     }
-    return pathFound;
-}
-
-DirChecker::~DirChecker()
-{
-    rfs.Close();
-}
 #else
-DirChecker::DirChecker()
-{
-}
-
-DirChecker::~DirChecker()
-{
-}
-
-bool DirChecker::checkDir(const QDir &dir)
-{
-    return dir.exists();
-}
+    inline bool checkMobilityPluginsDir(const QDir &dir)
+    {
+        return dir.exists();
+    }
 #endif
 
 inline QStringList mobilityPlugins(const QString plugintype)
@@ -120,7 +154,7 @@
         qDebug() << "Plugin paths:" << paths;
 #endif
 
-    DirChecker dirChecker;
+    //DirChecker dirChecker;
 
     //temp variable to avoid multiple identic path
     QSet<QString> processed;
@@ -134,7 +168,7 @@
             continue;
         processed.insert(paths.at(i));
         QDir pluginsDir(paths.at(i));
-        if (!dirChecker.checkDir(pluginsDir))
+        if (!checkMobilityPluginsDir(pluginsDir))
             continue;
 
 #if defined(Q_OS_WIN)
@@ -154,7 +188,7 @@
             || pluginsDir.path().endsWith(QLatin1String("/plugins/")))
             subdir = plugintype;
 
-        if (dirChecker.checkDir(QDir(pluginsDir.path() + QLatin1Char('/') + subdir))) {
+        if (checkMobilityPluginsDir(QDir(pluginsDir.path() + QLatin1Char('/') + subdir))) {
             pluginsDir.cd(subdir);
             QStringList files = pluginsDir.entryList(QDir::Files);
 
@@ -172,3 +206,5 @@
 }
 
 QTM_END_NAMESPACE
+
+#endif
--- a/src/location/location.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/location/location.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -68,10 +68,13 @@
                 qgeosatelliteinfosource_maemo.cpp \
                 dbuscomm_maemo.cpp \
                 dbusserver_maemo.cpp
-    HEADERS += qgeopositioninfosource_maemo_p.h \
+    PRIVATE_HEADERS += qgeopositioninfosource_maemo_p.h \
                 qgeosatelliteinfosource_maemo_p.h \
                 dbuscomm_maemo_p.h \
                 dbusserver_maemo_p.h
+    CONFIG += create_pc create_prl
+    pkgconfig.path = $$QT_MOBILITY_LIB/pkgconfig
+    pkgconfig.files = QtLocation.pc
 }
 
 maemo5 {
--- a/src/messaging/messaging.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/messaging.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -146,6 +146,10 @@
 	contains(messaging_ncnlist_enabled, no) {
 	DEFINES += NCNLISTREMOVED
 	}
+	contains(messaging_qthighway_enabled, yes) {
+    CONFIG += QTHIGHWAY
+    DEFINES += QTHIGHWAYUSED
+    }
         HEADERS -= qmessagestore_p.h \
             qmessagecontentcontainer_p.h \
             qmessage_p.h
@@ -182,6 +186,10 @@
         contains(CONFIG, FREESTYLEMAIL) {
 	    SOURCES += qfsengine_symbian.cpp
 	}
+    contains(CONFIG, QTHIGHWAY) {
+        LIBS += -lxqservice \
+                -lxqserviceutil \
+    }
     LIBS += -lsendas2 \
             -lmsgs \
             -letext \
@@ -198,7 +206,7 @@
             -lcone \
             -lapgrfx \
             -lapmime \
-            -lecom
+            -lecom 
         TARGET.CAPABILITY = ALL \
             -TCB
         TARGET.UID3 = 0x2002AC82
--- a/src/messaging/qfsengine_symbian.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/qfsengine_symbian.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -246,8 +246,12 @@
 
 QMessageAccountId CFSEngine::defaultAccount(QMessage::Type type) const
 {
-    // TODO
-    Q_UNUSED(type);
+    TRAPD(err, updateEmailAccountsL());
+    Q_UNUSED(err); 
+    QMessageAccountIdList accountIds = accountsByType(type);
+    if (accountIds.count() > 0)
+        return accountIds.at(0);
+        
     return QMessageAccountId();
 }
 
--- a/src/messaging/qmessage.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/qmessage.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -461,6 +461,11 @@
     Append the contents of the files specified by \a fileNames to the end of the list of 
     attachments for the message. The internet media (MIME) type of the attachments will be 
     determined by examining the files or file names.
+    
+    Symbian OS based devices have a limit for MMS message size. The message size limit 
+    varies between different devices, but is frequently 600 000 bytes. If the attachment
+    size is greater than the limit then message sending will fail when 
+    QMessageService::send() is called.
 
     \sa attachmentIds(), clearAttachments()
 */
--- a/src/messaging/qmessageaccount_symbian.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/qmessageaccount_symbian.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -42,6 +42,9 @@
 #include "qmessageaccount_p.h"
 #include "qmessagemanager.h"
 #include "qmtmengine_symbian_p.h"
+#ifdef FREESTYLEMAILUSED
+#include "qfsengine_symbian_p.h"
+#endif
 
 QTM_BEGIN_NAMESPACE
 
@@ -105,8 +108,15 @@
 
 QMessageAccountId QMessageAccount::defaultAccount(QMessage::Type type)
 {
-	return CMTMEngine::instance()->defaultAccount(type);
-	// or return CFSEngine::instance()->defaultAccount(type);
+#ifdef FREESTYLEMAILUSED
+    if (type == QMessage::Email) {
+        QMessageAccountId id = CFSEngine::instance()->defaultAccount(type);
+        if (id.isValid())
+            return id;
+        else return CMTMEngine::instance()->defaultAccount(type);
+    }
+#endif // FREESTYLEMAILUSED    
+    return CMTMEngine::instance()->defaultAccount(type);
 }
 
 QTM_END_NAMESPACE
--- a/src/messaging/qmessageid_maemo.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/qmessageid_maemo.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -76,6 +76,7 @@
 {
     if (!other.d_ptr) {
         delete d_ptr;
+        d_ptr = 0;
         return *this;
     }
 
--- a/src/messaging/qmtmengine_symbian.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/qmtmengine_symbian.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -77,8 +77,6 @@
 #include <smuthdr.h>
 #include <mtuireg.h> // CMtmUiRegistry
 #include <mtmuibas.h> // CBaseMtmUi
-#include <SendUiConsts.h>
-#include <sendui.h>    // SendUi API
 #include <CMessageData.h> //CMessageData
 #include <apgcli.h>
 #include <rsendas.h>
@@ -93,6 +91,17 @@
 #include <QTextCodec>
 #include <messagingutil_p.h>
 
+#ifdef QTHIGHWAYUSED
+#include <xqaiwdecl.h>
+#include <xqaiwdeclplat.h>
+#include <xqaiwrequest.h>
+#include <xqservicerequest.h>
+
+#include <email_services_api.h>
+#else
+#include <SendUiConsts.h>
+#include <sendui.h>    // SendUi API
+#endif
 
 QTM_BEGIN_NAMESPACE
 
@@ -781,6 +790,25 @@
     return retVal;
 }
 
+#ifdef QTHIGHWAYUSED
+bool CMTMEngine::composeSMSL(const QMessage &message)
+{
+    bool embedded = false;
+    XQAiwRequest* request = iAiwMgr.create("com.nokia.symbian.IMessageSend",
+            "send(QVariantMap, QString)",
+            embedded);
+    QMap<QString, QVariant> map;
+    foreach (QMessageAddress recipient,message.to()) {
+        map.insert(recipient.addressee(), QString(""));
+    }
+    QList<QVariant> data;
+    data.append(map);
+    data.append(message.textContent());
+    request->setArguments(data);
+    request->send();
+    return true;
+}
+#else
 bool CMTMEngine::composeSMSL(const QMessage &message)
 {
     CSendUi *sendUi = CSendUi::NewL();
@@ -811,9 +839,39 @@
     
     sendUi->CreateAndSendMessageL(KSenduiMtmSmsUid, messageData, KNullUid, ETrue);
     CleanupStack::PopAndDestroy(3); //bd, messageData and sendUi
+    
     return true;
 }
 
+#endif 
+#ifdef QTHIGHWAYUSED
+
+bool CMTMEngine::composeMMSL(const QMessage &message)
+{
+    bool embedded = false;
+    
+    XQAiwRequest* request = iAiwMgr.create("com.nokia.symbian.IMessageSend",
+            "send(QVariantMap, QString)",
+            embedded);
+    
+    QMap<QString, QVariant> map;
+    
+    foreach (QMessageAddress recipient,message.to()) {
+        map.insert(recipient.addressee(), QString(""));
+    }
+    
+    QList<QVariant> data;
+    data.append(map);
+    data.append(message.textContent());
+    request->setArguments(data);
+
+    request->send();
+
+    return true;
+}
+
+#else
+
 bool CMTMEngine::composeMMSL(const QMessage &message)
 {
     CSendUi *sendUi = CSendUi::NewL();
@@ -884,6 +942,51 @@
     return true;
 }
 
+#endif 
+#ifdef QTHIGHWAYUSED
+
+bool CMTMEngine::composeEmailL(const QMessage &message)
+{
+    bool embedded = false;
+    
+    XQAiwRequest* request = iAiwMgr.create(XQI_EMAIL_MESSAGE_SEND,
+            "send(QVariant)",//XQOP_EMAIL_MESSAGE_SEND,
+            embedded);
+    
+    QMap<QString,QVariant> map;
+
+    // Add receivers
+    QStringList toRecipients;
+    QStringList ccRecipients;
+    QStringList bccRecipients;
+
+    foreach(QMessageAddress address, message.to())
+        toRecipients.append(address.addressee());
+
+    foreach(QMessageAddress address, message.cc())
+        ccRecipients.append(address.addressee());
+
+    foreach(QMessageAddress address, message.bcc())
+        bccRecipients.append(address.addressee());
+
+    map.insert(emailSendToKey, toRecipients);
+    map.insert(emailSendCcKey, ccRecipients);
+    map.insert(emailSendBccKey, bccRecipients);
+    map.insert(emailSendSubjectKey, message.subject());
+    
+    map.insert(emailSendBodyTextKey, message.textContent());
+    
+    QList<QVariant> data;
+    data.append(map);
+    request->setArguments(data);
+        
+    bool res = request->send();
+   
+    return res;
+}
+
+#else
+
 bool CMTMEngine::composeEmailL(const QMessage &message)
 {
     CSendUi *sendUi = CSendUi::NewL();
@@ -971,6 +1074,8 @@
     return true;
 }
 
+#endif
+
 bool CMTMEngine::retrieve(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id)
 {
     TRAPD(err, retrieveL(privateService, messageId, id));
@@ -3763,6 +3868,30 @@
     ipMmsMtm->LoadMessageL();
     message.setFrom(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(ipMmsMtm->Sender().Ptr(), ipMmsMtm->Sender().Length())));
     QMessagePrivate::setSenderName(message, QString::fromUtf16(ipMmsMtm->Sender().Ptr(), ipMmsMtm->Sender().Length()));
+
+    // Read message recipients
+    const CMsvRecipientList&  recipients = ipMmsMtm->AddresseeList();
+    QMessageAddressList toList;
+    QMessageAddressList ccList;
+    QMessageAddressList bccList;
+    for (int i=0; i < recipients.Count(); i++) {
+        switch (recipients.Type(i)) {
+        case EMsvRecipientCc:
+            ccList.append(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(recipients[i].Ptr(), recipients[i].Length())));
+            break;
+        case EMsvRecipientBcc:
+            bccList.append(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(recipients[i].Ptr(), recipients[i].Length())));
+            break;
+        case EMsvRecipientTo:
+        default:
+            toList.append(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(recipients[i].Ptr(), recipients[i].Length())));
+            break;
+        }
+    }
+    message.setTo(toList);
+    message.setCc(ccList);
+    message.setBcc(bccList);
+
     
     // Read message subject
     if (receivedEntry.Entry().iDescription.Length() > 0)  {
--- a/src/messaging/qmtmengine_symbian_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/messaging/qmtmengine_symbian_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -55,7 +55,9 @@
 #include "qmessagefilter_p.h"
 #include "qmessagefolderfilter.h"
 #include "qmessageservice.h"
-
+#ifdef QTHIGHWAYUSED
+#include <xqappmgr.h>
+#endif
 
 class CRichText;
 class CCharFormatLayer;
@@ -314,6 +316,10 @@
     mutable QMessageFolderSortOrder iCurrentFolderOrdering;
     mutable QMessageSortOrder iCurrentMessageOrdering;
     
+#ifdef QTHIGHWAYUSED    
+    XQApplicationManager iAiwMgr;
+#endif
+    
     friend class QMessageService;
     friend class CMessagesFindOperation;
     friend class CAsynchronousMTMOperation;
--- a/src/multimedia/qgraphicsvideoitem_maemo5.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/multimedia/qgraphicsvideoitem_maemo5.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -62,6 +62,8 @@
 
 QT_BEGIN_NAMESPACE
 
+//#define DEBUG_GFX_VIDEO_ITEM
+
 //update overlay geometry slightly later,
 //to ensure color key is alredy replaced with static frame
 #define GEOMETRY_UPDATE_DELAY 20
@@ -514,7 +516,10 @@
 void QGraphicsVideoItem::paint(
         QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
 {
+#ifdef DEBUG_GFX_VIDEO_ITEM
     qDebug() << "QGraphicsVideoItem::paint";
+#endif
+
     Q_UNUSED(option);
     Q_D(QGraphicsVideoItem);
 
@@ -551,7 +556,7 @@
         if (widget) {
             //workaround for xvideo issue with U/V planes swapped
             QPoint topLeft = widget->mapToGlobal(overlayRect.topLeft());
-            if ((topLeft.x() & 1) == 0)
+            if ((topLeft.x() & 1) == 0 && topLeft.x() != 0)
                 overlayRect.moveLeft(overlayRect.left()-1);
         }
 
@@ -581,7 +586,9 @@
             geometryChanged = true;
             d->softwareRenderingTimer.start(SOFTWARE_RENDERING_DURATION, this);
 
-            //qDebug() << "set video display rect:" << deviceRect;
+#ifdef DEBUG_GFX_VIDEO_ITEM
+            qDebug() << "set video display rect:" << overlayRect;
+#endif
 
         }
 
--- a/src/multimedia/qmediaplaylistnavigator.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/multimedia/qmediaplaylistnavigator.h	Mon Oct 04 01:37:06 2010 +0300
@@ -54,7 +54,7 @@
     Q_OBJECT
     Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged)
     Q_PROPERTY(int currentIndex READ currentIndex WRITE jump NOTIFY currentIndexChanged)
-    Q_PROPERTY(QMediaContent currentItem READ currentItem NOTIFY currentItemChanged)
+    Q_PROPERTY(QMediaContent currentItem READ currentItem)
 
 public:
     QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent = 0);
--- a/src/multimedia/qmediapluginloader.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/multimedia/qmediapluginloader.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -46,17 +46,70 @@
 #include <QtCore/qdebug.h>
 
 #include "qmediaserviceproviderplugin.h"
-#include "qmobilitypluginsearch.h"
+
+#if defined(Q_OS_SYMBIAN)
+# include <f32file.h>
+#endif
+
+#if defined(Q_OS_MAC)
+# include <CoreFoundation/CoreFoundation.h>
+#endif
 
 QT_BEGIN_NAMESPACE
 
 typedef QMap<QString,QObjectList> ObjectListMap;
 Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins);
 
+
+#if defined(Q_OS_SYMBIAN)
+// XXX: Copied over from Mobility, hopefully to be removed at some point
+class DirChecker
+{
+public:
+    DirChecker();
+    ~DirChecker();
+    bool checkDir(const QDir& dir);
+
+private:
+    RFs rfs;
+};
+
+DirChecker::DirChecker()
+{
+    qt_symbian_throwIfError(rfs.Connect());
+}
+
+bool DirChecker::checkDir(const QDir& dir)
+{
+    bool pathFound = false;
+    // In Symbian, going cdUp() in a c:/private/<uid3>/ will result in *platsec* error at fileserver (requires AllFiles capability)
+    // Also, trying to cd() to a nonexistent directory causes *platsec* error. This does not cause functional harm, but should
+    // nevertheless be changed to use native Symbian methods to avoid unnecessary platsec warnings (as per qpluginloader.cpp).
+    // Use native Symbian code to check for directory existence, because checking
+    // for files from under non-existent protected dir like E:/private/<uid> using
+    // QDir::exists causes platform security violations on most apps.
+    QString nativePath = QDir::toNativeSeparators(dir.absolutePath());
+    TPtrC ptr = TPtrC16(static_cast<const TUint16*>(nativePath.utf16()), nativePath.length());
+    TUint attributes;
+    TInt err = rfs.Att(ptr, attributes);
+    if (err == KErrNone) {
+        // yes, the directory exists.
+        pathFound = true;
+    }
+    return pathFound;
+}
+
+DirChecker::~DirChecker()
+{
+    rfs.Close();
+}
+#endif
+
+
 QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity):
     m_iid(iid)
 {
-    m_location = location + "/";
+    m_location = QString::fromLatin1("/%1").arg(location);
     load();
 }
 
@@ -78,7 +131,83 @@
 //to be used for testing purposes only
 void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects)
 {
-    staticMediaPlugins()->insert(location+"/", objects);
+    staticMediaPlugins()->insert(QString::fromLatin1("/%1").arg(location), objects);
+}
+
+QStringList QMediaPluginLoader::availablePlugins() const
+{
+    QStringList paths;
+    QStringList plugins;
+
+#if defined(Q_OS_SYMBIAN)
+    DirChecker dirChecker;
+#endif
+
+#if defined(Q_OS_MAC)
+    QString imageSuffix(qgetenv("DYLD_IMAGE_SUFFIX"));
+
+    // Bundle plugin directory
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    if (mainBundle != 0) {
+        CFURLRef baseUrl = CFBundleCopyBundleURL(mainBundle);
+        CFURLRef pluginUrlPart = CFBundleCopyBuiltInPlugInsURL(mainBundle);
+        CFStringRef pluginPathPart = CFURLCopyFileSystemPath(pluginUrlPart, kCFURLPOSIXPathStyle);
+        CFURLRef pluginUrl = CFURLCreateCopyAppendingPathComponent(0, baseUrl, pluginPathPart, true);
+        CFStringRef pluginPath = CFURLCopyFileSystemPath(pluginUrl, kCFURLPOSIXPathStyle);
+
+        CFIndex length = CFStringGetLength(pluginPath);
+        UniChar buffer[length];
+        CFStringGetCharacters(pluginPath, CFRangeMake(0, length), buffer);
+
+        paths << QString(reinterpret_cast<const QChar *>(buffer), length);
+
+        CFRelease(pluginPath);
+        CFRelease(pluginUrl);
+        CFRelease(pluginPathPart);
+        CFRelease(pluginUrlPart);
+        CFRelease(baseUrl);
+    }
+#endif
+
+#ifdef QTM_PLUGIN_PATH
+    // Mobility's plugin directory
+    paths << QLatin1String(QTM_PLUGIN_PATH);
+#endif
+
+    // Qt paths
+    paths << QCoreApplication::libraryPaths();
+
+    foreach (const QString &path, paths) {
+        QDir typeDir(path + m_location);
+#if defined(Q_OS_SYMBIAN)
+        if (dirChecker.checkDir(typeDir))
+#endif
+        {
+            foreach (const QString &file, typeDir.entryList(QDir::Files)) {
+#if defined(Q_OS_MAC)
+                if (!imageSuffix.isEmpty()) {   // Only add appropriate images
+                    if (file.lastIndexOf(imageSuffix, -6) == -1)
+                        continue;
+                } else {  // Ignore any images with common suffixes
+                    if (file.endsWith(QLatin1String("_debug.dylib")) ||
+                        file.endsWith(QLatin1String("_profile.dylib")))
+                        continue;
+                }
+#elif defined(Q_OS_UNIX)
+                // Ignore separate debug files
+                if (file.endsWith(QLatin1String(".debug")))
+                    continue;
+#elif defined(Q_OS_WIN)
+                // Ignore non-dlls
+                if (!file.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive))
+                    continue;
+#endif
+                plugins << typeDir.absoluteFilePath(file);
+            }
+        }
+    }
+
+    return  plugins;
 }
 
 void QMediaPluginLoader::load()
@@ -97,25 +226,27 @@
             }
         }
     } else {
-        QStringList plugins = QTM_PREPEND_NAMESPACE(mobilityPlugins)(m_location);
-        for (int i=0; i < plugins.count(); i++) {
-            QPluginLoader   loader(plugins.at(i));
+        foreach (const QString &plugin, availablePlugins()) {
+            QPluginLoader   loader(plugin);
+
             QObject *o = loader.instance();
             if (o != 0 && o->qt_metacast(m_iid) != 0) {
                 QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o);
                 if (p != 0) {
-                    foreach (QString const &key, p->keys())
+                    foreach (const QString &key, p->keys())
                         m_instances.insertMulti(key, o);
                 }
 
                 continue;
             } else {
-                qWarning() << "QMediaPluginLoader: Failed to load plugin: " << plugins.at(i) << loader.errorString();
+                qWarning() << "QMediaPluginLoader: Failed to load plugin: " << plugin << loader.errorString();
             }
+
             delete o;
             loader.unload();
         }
     }
 }
+
 QT_END_NAMESPACE
 
--- a/src/multimedia/qmediapluginloader_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/multimedia/qmediapluginloader_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -54,13 +54,11 @@
 //
 
 #include <qmobilityglobal.h>
-#include <QObject>
+#include <QtCore/qobject.h>
 #include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
 #include <QtCore/qmap.h>
 
-QT_BEGIN_NAMESPACE
-class QObject;
-QT_END_NAMESPACE
 
 QT_BEGIN_NAMESPACE
 
@@ -81,6 +79,7 @@
 
 private:
     void load();
+    QStringList availablePlugins() const;
 
     QByteArray  m_iid;
     QString     m_location;
--- a/src/multimedia/qvideowidget.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/multimedia/qvideowidget.h	Mon Oct 04 01:37:06 2010 +0300
@@ -58,7 +58,7 @@
     Q_INTERFACES(QMediaBindableInterface)
     Q_PROPERTY(QMediaObject* mediaObject READ mediaObject WRITE setMediaObject)
     Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
-    Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode NOTIFY aspectRatioModeChanged)
+    Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode)
     Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
     Q_PROPERTY(int contrast READ contrast WRITE setContrast NOTIFY contrastChanged)
     Q_PROPERTY(int hue READ hue WRITE setHue NOTIFY hueChanged)
--- a/src/multimedia/qxvideosurface_maemo5.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/multimedia/qxvideosurface_maemo5.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -46,6 +46,8 @@
 
 #include "qxvideosurface_maemo5_p.h"
 
+//#define DEBUG_XV_SURFACE
+
 struct XvFormatRgb
 {
     QVideoFrame::PixelFormat pixelFormat;
@@ -162,6 +164,10 @@
     if (id == m_winId)
         return;
 
+#ifdef DEBUG_XV_SURFACE
+    qDebug() << "QXVideoSurface::setWinId" << id;
+#endif
+
     if (m_image)
         XFree(m_image);
 
@@ -173,6 +179,7 @@
     if (m_portId != 0)
         XvUngrabPort(QX11Info::display(), m_portId, 0);
 
+    QList<QVideoFrame::PixelFormat> prevFormats = m_supportedPixelFormats;
     m_supportedPixelFormats.clear();
     m_formatIds.clear();
 
@@ -195,7 +202,12 @@
         QAbstractVideoSurface::stop();
     }
 
-    emit supportedFormatsChanged();
+    if (m_supportedPixelFormats != prevFormats) {
+#ifdef DEBUG_XV_SURFACE
+        qDebug() << "QXVideoSurface: supportedFormatsChanged";
+#endif
+        emit supportedFormatsChanged();
+    }
 }
 
 QRect QXVideoSurface::displayRect() const
@@ -258,7 +270,9 @@
 
 bool QXVideoSurface::start(const QVideoSurfaceFormat &format)
 {
-    //qDebug() << "QXVideoSurface::start" << format;
+#ifdef DEBUG_XV_SURFACE
+    qDebug() << "QXVideoSurface::start" << format;
+#endif
 
     m_lastFrame = QVideoFrame();
 
@@ -296,7 +310,7 @@
         m_shminfo.readOnly = False;
 
         if (!XShmAttach(QX11Info::display(), &m_shminfo)) {
-            //qDebug() << "XShmAttach failed";
+            qWarning() << "XShmAttach failed" << format;
             return false;
         }
 
@@ -431,7 +445,10 @@
             }
         }
         XvFreeAdaptorInfo(adaptors);
-    }
+    }    
+
+    if (!portFound)
+        qWarning() << "QXVideoSurface::findPort: failed to find XVideo port";
 
     return portFound;
 }
@@ -472,4 +489,9 @@
         }
         XFree(imageFormats);
     }
+
+#ifdef DEBUG_XV_SURFACE
+    qDebug() << "Supported pixel formats:" << m_supportedPixelFormats;
+#endif
+
 }
--- a/src/publishsubscribe/psmapperserver_symbian/pathmapper_symbian.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/publishsubscribe/psmapperserver_symbian/pathmapper_symbian.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -144,8 +144,6 @@
 {
     QString basePath = path;
     QStringList children;
-    if (basePath.right(1) == QString(QLatin1Char('/')))
-        basePath.chop(1);
     QHashIterator<QString, PathData> i(m_paths);
     XQSettingsManager settingsManager;
     while (i.hasNext()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/s60installs/backup_registration.xml	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" standalone="yes"?>
+<backup_registration>
+    <system_backup/>
+    <passive_backup>
+    <include_directory name = "\" />
+    </passive_backup>
+    <restore requires_reboot = "no"/>
+</backup_registration>
--- a/src/s60installs/bwins/QtVersitu.def	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/s60installs/bwins/QtVersitu.def	Mon Oct 04 01:37:06 2010 +0300
@@ -120,14 +120,29 @@
 	??_EQVersitResourceHandler@QtMobility@@UAE@I@Z @ 119 NONAME ; QtMobility::QVersitResourceHandler::~QVersitResourceHandler(unsigned int)
 	?state@QVersitReader@QtMobility@@QBE?AW4State@12@XZ @ 120 NONAME ; enum QtMobility::QVersitReader::State QtMobility::QVersitReader::state(void) const
 	??_EQVersitContactExporterDetailHandler@QtMobility@@UAE@I@Z @ 121 NONAME ; QtMobility::QVersitContactExporterDetailHandler::~QVersitContactExporterDetailHandler(unsigned int)
-	?version@QVersitContactExporterDetailHandlerV2@QtMobility@@UBEHXZ @ 122 NONAME ; int QtMobility::QVersitContactExporterDetailHandlerV2::version(void) const
+	?version@QVersitContactExporterDetailHandlerV2@QtMobility@@UBEHXZ @ 122 NONAME ABSENT ; int QtMobility::QVersitContactExporterDetailHandlerV2::version(void) const
 	??_EQVersitContactExporterDetailHandlerV2@QtMobility@@UAE@I@Z @ 123 NONAME ; QtMobility::QVersitContactExporterDetailHandlerV2::~QVersitContactExporterDetailHandlerV2(unsigned int)
 	?setPropertyHandler@QVersitContactImporter@QtMobility@@QAEXPAVQVersitContactImporterPropertyHandlerV2@2@@Z @ 124 NONAME ; void QtMobility::QVersitContactImporter::setPropertyHandler(class QtMobility::QVersitContactImporterPropertyHandlerV2 *)
 	??1QVersitContactImporterPropertyHandlerV2@QtMobility@@UAE@XZ @ 125 NONAME ; QtMobility::QVersitContactImporterPropertyHandlerV2::~QVersitContactImporterPropertyHandlerV2(void)
 	??_EQVersitContactImporterPropertyHandlerV2@QtMobility@@UAE@I@Z @ 126 NONAME ; QtMobility::QVersitContactImporterPropertyHandlerV2::~QVersitContactImporterPropertyHandlerV2(unsigned int)
-	?version@QVersitContactImporterPropertyHandlerV2@QtMobility@@UBEHXZ @ 127 NONAME ; int QtMobility::QVersitContactImporterPropertyHandlerV2::version(void) const
-	?createBackupHandler@QVersitContactExporterDetailHandlerV2@QtMobility@@SAPAV12@XZ @ 128 NONAME ; class QtMobility::QVersitContactExporterDetailHandlerV2 * QtMobility::QVersitContactExporterDetailHandlerV2::createBackupHandler(void)
+	?version@QVersitContactImporterPropertyHandlerV2@QtMobility@@UBEHXZ @ 127 NONAME ABSENT ; int QtMobility::QVersitContactImporterPropertyHandlerV2::version(void) const
+	?createBackupHandler@QVersitContactExporterDetailHandlerV2@QtMobility@@SAPAV12@XZ @ 128 NONAME ABSENT ; class QtMobility::QVersitContactExporterDetailHandlerV2 * QtMobility::QVersitContactExporterDetailHandlerV2::createBackupHandler(void)
 	??1QVersitContactExporterDetailHandlerV2@QtMobility@@UAE@XZ @ 129 NONAME ; QtMobility::QVersitContactExporterDetailHandlerV2::~QVersitContactExporterDetailHandlerV2(void)
-	?createBackupHandler@QVersitContactImporterPropertyHandlerV2@QtMobility@@SAPAV12@XZ @ 130 NONAME ; class QtMobility::QVersitContactImporterPropertyHandlerV2 * QtMobility::QVersitContactImporterPropertyHandlerV2::createBackupHandler(void)
+	?createBackupHandler@QVersitContactImporterPropertyHandlerV2@QtMobility@@SAPAV12@XZ @ 130 NONAME ABSENT ; class QtMobility::QVersitContactImporterPropertyHandlerV2 * QtMobility::QVersitContactImporterPropertyHandlerV2::createBackupHandler(void)
 	?setDetailHandler@QVersitContactExporter@QtMobility@@QAEXPAVQVersitContactExporterDetailHandlerV2@2@@Z @ 131 NONAME ; void QtMobility::QVersitContactExporter::setDetailHandler(class QtMobility::QVersitContactExporterDetailHandlerV2 *)
+	?ProfileSync@QVersitContactHandlerFactory@QtMobility@@2U?$QLatin1Constant@$04@2@B @ 132 NONAME ; struct QtMobility::QLatin1Constant<5> const QtMobility::QVersitContactHandlerFactory::ProfileSync
+	?ProfileBackup@QVersitContactHandlerFactory@QtMobility@@2U?$QLatin1Constant@$06@2@B @ 133 NONAME ; struct QtMobility::QLatin1Constant<7> const QtMobility::QVersitContactHandlerFactory::ProfileBackup
+	?subDocuments@QVersitDocument@QtMobility@@QBE?AV?$QList@VQVersitDocument@QtMobility@@@@XZ @ 134 NONAME ; class QList<class QtMobility::QVersitDocument> QtMobility::QVersitDocument::subDocuments(void) const
+	?profiles@QVersitContactHandlerFactory@QtMobility@@UBE?AV?$QSet@VQString@@@@XZ @ 135 NONAME ; class QSet<class QString> QtMobility::QVersitContactHandlerFactory::profiles(void) const
+	??0QVersitContactImporter@QtMobility@@QAE@ABVQString@@@Z @ 136 NONAME ; QtMobility::QVersitContactImporter::QVersitContactImporter(class QString const &)
+	??1QVersitContactHandler@QtMobility@@UAE@XZ @ 137 NONAME ; QtMobility::QVersitContactHandler::~QVersitContactHandler(void)
+	??0QVersitContactExporter@QtMobility@@QAE@ABVQString@@@Z @ 138 NONAME ; QtMobility::QVersitContactExporter::QVersitContactExporter(class QString const &)
+	?addSubDocument@QVersitDocument@QtMobility@@QAEXABV12@@Z @ 139 NONAME ; void QtMobility::QVersitDocument::addSubDocument(class QtMobility::QVersitDocument const &)
+	?index@QVersitContactHandlerFactory@QtMobility@@UBEHXZ @ 140 NONAME ; int QtMobility::QVersitContactHandlerFactory::index(void) const
+	??1QVersitContactHandlerFactory@QtMobility@@UAE@XZ @ 141 NONAME ; QtMobility::QVersitContactHandlerFactory::~QVersitContactHandlerFactory(void)
+	?setSubDocuments@QVersitDocument@QtMobility@@QAEXABV?$QList@VQVersitDocument@QtMobility@@@@@Z @ 142 NONAME ; void QtMobility::QVersitDocument::setSubDocuments(class QList<class QtMobility::QVersitDocument> const &)
+	??_EQVersitContactHandler@QtMobility@@UAE@I@Z @ 143 NONAME ; QtMobility::QVersitContactHandler::~QVersitContactHandler(unsigned int)
+	??_EQVersitContactHandlerFactory@QtMobility@@UAE@I@Z @ 144 NONAME ; QtMobility::QVersitContactHandlerFactory::~QVersitContactHandlerFactory(unsigned int)
+	?componentType@QVersitDocument@QtMobility@@QBE?AVQString@@XZ @ 145 NONAME ; class QString QtMobility::QVersitDocument::componentType(void) const
+	?setComponentType@QVersitDocument@QtMobility@@QAEXVQString@@@Z @ 146 NONAME ; void QtMobility::QVersitDocument::setComponentType(class QString)
 
--- a/src/s60installs/eabi/QtVersitu.def	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/s60installs/eabi/QtVersitu.def	Mon Oct 04 01:37:06 2010 +0300
@@ -136,8 +136,19 @@
 	_ZTVN10QtMobility29QVersitDefaultResourceHandlerE @ 135 NONAME
 	_ZN10QtMobility22QVersitContactExporter16setDetailHandlerEPNS_37QVersitContactExporterDetailHandlerV2E @ 136 NONAME
 	_ZN10QtMobility22QVersitContactImporter18setPropertyHandlerEPNS_39QVersitContactImporterPropertyHandlerV2E @ 137 NONAME
-	_ZN10QtMobility37QVersitContactExporterDetailHandlerV219createBackupHandlerEv @ 138 NONAME
-	_ZN10QtMobility39QVersitContactImporterPropertyHandlerV219createBackupHandlerEv @ 139 NONAME
-	_ZTIN10QtMobility37QVersitContactExporterDetailHandlerV2E @ 140 NONAME
-	_ZTIN10QtMobility39QVersitContactImporterPropertyHandlerV2E @ 141 NONAME
+	_ZN10QtMobility37QVersitContactExporterDetailHandlerV219createBackupHandlerEv @ 138 NONAME ABSENT
+	_ZN10QtMobility39QVersitContactImporterPropertyHandlerV219createBackupHandlerEv @ 139 NONAME ABSENT
+	_ZTIN10QtMobility37QVersitContactExporterDetailHandlerV2E @ 140 NONAME ABSENT
+	_ZTIN10QtMobility39QVersitContactImporterPropertyHandlerV2E @ 141 NONAME ABSENT
+	_ZN10QtMobility15QVersitDocument14addSubDocumentERKS0_ @ 142 NONAME
+	_ZN10QtMobility15QVersitDocument15setSubDocumentsERK5QListIS0_E @ 143 NONAME
+	_ZN10QtMobility15QVersitDocument16setComponentTypeE7QString @ 144 NONAME
+	_ZN10QtMobility22QVersitContactExporterC1ERK7QString @ 145 NONAME
+	_ZN10QtMobility22QVersitContactExporterC2ERK7QString @ 146 NONAME
+	_ZN10QtMobility22QVersitContactImporterC1ERK7QString @ 147 NONAME
+	_ZN10QtMobility22QVersitContactImporterC2ERK7QString @ 148 NONAME
+	_ZN10QtMobility28QVersitContactHandlerFactory11ProfileSyncE @ 149 NONAME DATA 5
+	_ZN10QtMobility28QVersitContactHandlerFactory13ProfileBackupE @ 150 NONAME DATA 7
+	_ZNK10QtMobility15QVersitDocument12subDocumentsEv @ 151 NONAME
+	_ZNK10QtMobility15QVersitDocument13componentTypeEv @ 152 NONAME
 
--- a/src/s60installs/qtmobility.iby	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/s60installs/qtmobility.iby	Mon Oct 04 01:37:06 2010 +0300
@@ -61,5 +61,6 @@
 //Resource
 data=DATAZ_\CONTACTS_RESOURCE_DIR\cntmodel.rsc                                           CONTACTS_RESOURCE_DIR\cntmodel.rsc
 data=\epoc32\data\z\private\2002ac7f\qtserviceframework_4.7_system.db                    private\2002ac7f\qtserviceframework_4.7_system.db
+data=\epoc32\data\z\private\10202D56\import\packages\2002AC89\backup_registration.xml    private\10202D56\import\packages\2002AC89\backup_registration.xml
 
 #endif // __QT_MOBILITY_IBY__
--- a/src/s60installs/s60installs.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/s60installs/s60installs.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -9,7 +9,7 @@
     TARGET = "QtMobility"
     TARGET.UID3 = 0x2002AC89
 
-    VERSION = 1.0.2
+    VERSION = 1.0.3
 
     vendorinfo = \
         "; Localised Vendor name" \
@@ -41,12 +41,30 @@
         EPOCROOT50 = $$(EPOCROOT50)
     }
 
+    #Symbian^3 and beyond requires special package flags
+    #we cannot use S60_VERSION == 5.2 as Qt 4.6.x does not define it yet
+    #see $QTDIR/mkspecs/common/symbian/symbian.conf for details
+    exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.2.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.2.sis)|exists($${EPOCROOT}epoc32/release/armv5/lib/libstdcppv5.dso) {
+        pkg_version = $$replace(VERSION,"\.",",")
+        qtmobilitydeployment.pkg_prerules += "$${LITERAL_HASH}{\"QtMobility\"},(0x2002AC89),$${pkg_version},TYPE=SA,RU,NR"
+    }
+
     contains(mobility_modules, messaging): qtmobilitydeployment.sources += \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtMessaging.dll
-
-    contains(mobility_modules, serviceframework): qtmobilitydeployment.sources += \
+	
+    contains(mobility_modules, serviceframework) { 
+        qtmobilitydeployment.sources += \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtServiceFramework.dll \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qsfwdatabasemanagerserver.exe
+        contains(QT_CONFIG, declarative): {
+            qtmobilitydeployment.sources += \
+            $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/declarative_serviceframework.dll
+            pluginstubs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\serviceframework\\qmakepluginstubs\\declarative_serviceframework.qtplugin\"  - \"!:\\resource\\qt\\imports\\QtMobility\\serviceframework\\declarative_serviceframework.qtplugin\""
+            qmldirs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\serviceframework\\qmldir\"  - \"!:\\resource\\qt\\imports\\QtMobility\\serviceframework\\qmldir\""
+        }
+    }
 
     contains(mobility_modules, location): qtmobilitydeployment.sources += \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtLocation.dll
@@ -54,9 +72,19 @@
     contains(mobility_modules, systeminfo): qtmobilitydeployment.sources += \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtSystemInfo.dll
 
-    contains(mobility_modules, publishsubscribe): qtmobilitydeployment.sources += \
+    contains(mobility_modules, publishsubscribe) {
+        qtmobilitydeployment.sources += \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtPublishSubscribe.dll \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qpspathmapperserver.exe
+        contains(QT_CONFIG, declarative) {
+            qtmobilitydeployment.sources += \
+            $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/declarative_publishsubscribe.dll
+            pluginstubs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\publishsubscribe\\qmakepluginstubs\\declarative_publishsubscribe.qtplugin\"  - \"!:\\resource\\qt\\imports\\QtMobility\\publishsubscribe\\declarative_publishsubscribe.qtplugin\""
+            qmldirs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\publishsubscribe\\qmldir\"  - \"!:\\resource\\qt\\imports\\QtMobility\\publishsubscribe\\qmldir\""
+        }
+    }
 
     contains(mobility_modules, versit): qtmobilitydeployment.sources += \
         $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtVersit.dll
@@ -115,7 +143,14 @@
 
             qtmobilitydeployment.pkg_postrules += symbiancntsim
         }
-
+	 contains(QT_CONFIG, declarative): {
+            qtmobilitydeployment.sources += \
+            $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/declarative_contacts.dll
+            pluginstubs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\contacts\\qmakepluginstubs\\declarative_contacts.qtplugin\"  - \"!:\\resource\\qt\\imports\\QtMobility\\contacts\\declarative_contacts.qtplugin\""
+            qmldirs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\contacts\\qmldir\"  - \"!:\\resource\\qt\\imports\\QtMobility\\contacts\\qmldir\""
+        }
     }
 
     contains(mobility_modules, multimedia) {
@@ -155,52 +190,72 @@
         pluginstubs += \
             "\"$$QT_MOBILITY_BUILD_TREE/plugins/multimedia/symbian/mmf/qmakepluginstubs/qtmultimediakit_mmfengine.qtplugin\" - \"!:\\resource\\qt\\plugins\\mediaservice\\qtmultimediakit_mmfengine.qtplugin\"" \
             "\"$$QT_MOBILITY_BUILD_TREE/plugins/multimedia/m3u/qmakepluginstubs/qtmultimediakit_m3u.qtplugin\"     - \"!:\\resource\\qt\\plugins\\playlistformats\\qtmultimediakit_m3u.qtplugin\"" \
+	    
+	contains(QT_CONFIG, declarative): {
+            qtmobilitydeployment.sources += \
+            $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/declarative_multimedia.dll
+            pluginstubs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\multimedia\\qmakepluginstubs\\declarative_multimedia.qtplugin\"  - \"!:\\resource\\qt\\imports\\Qt\\multimedia\\declarative_multimedia.qtplugin\""
+            qmldirs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\multimedia\\qmldir\"  - \"!:\\resource\\qt\\imports\\Qt\\multimedia\\qmldir\""
+        }
     }
 
     contains(mobility_modules, sensors) {
 
+        equals(sensors_symbian_enabled,yes) {
+            sensorplugin=symbian
+        } else:equals(sensors_s60_31_enabled,yes) {
+            sensorplugin=s60_sensor_api
+        } else {
+            error("Must have a Symbian sensor backend available")
+        }
+
         qtmobilitydeployment.sources += \
             $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/QtSensors.dll
 
-        sensors = ""
+        sensors = \
+            "IF package(0x1028315F)" \
+            "   \"$${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_sym.dll\" - \"!:\\sys\\bin\\qtsensors_sym.dll\"" \
+            "   \"$${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
+            "ELSEIF package(0x102752AE)" \
+            "   \"$${EPOCROOT32}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_sym.dll\" - \"!:\\sys\\bin\\qtsensors_sym.dll\"" \
+            "   \"$${EPOCROOT32}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
+            "ELSEIF package(0x102032BE)" \
+            "   \"$${EPOCROOT31}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_sym.dll\" - \"!:\\sys\\bin\\qtsensors_sym.dll\"" \
+            "   \"$${EPOCROOT31}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
+            "ELSE" \
+            "   \"$${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_sym.dll\" - \"!:\\sys\\bin\\qtsensors_sym.dll\"" \
+            "   \"$${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
+            "ENDIF"
 
-        equals(sensors_s60_31_enabled,yes) {
-            sensors += \
-                "IF package(0x102032BE)" \
-                "   \"$${EPOCROOT31}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_s60sensorapi.dll\" - \"!:\\sys\\bin\\qtsensor_s60sensorapi.dll\"" \
-                "   \"$${EPOCROOT31}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
-                "ENDIF"
-        } else:equals(sensors_symbian_enabled,yes) {
-            sensors += \
-                "IF package(0x102752AE)" \
-                "   \"$${EPOCROOT32}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_sym.dll\" - \"!:\\sys\\bin\\qtsensors_sym.dll\"" \
-                "   \"$${EPOCROOT32}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
-                "ELSE" \
-                "   \"$${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_sym.dll\" - \"!:\\sys\\bin\\qtsensors_sym.dll\"" \
-                "   \"$${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/qtsensors_generic.dll\" - \"!:\\sys\\bin\\qtsensors_generic.dll\"" \
-                "ENDIF"
-        }
+        pluginstubs += \
+            "\"$$QT_MOBILITY_BUILD_TREE/plugins/sensors/$$sensorplugin/qmakepluginstubs/qtsensors_sym.qtplugin\"  - \"!:\\resource\\qt\\plugins\\sensors\\qtsensors_sym.qtplugin\"" \
+            "\"$$QT_MOBILITY_BUILD_TREE/plugins/sensors/generic/qmakepluginstubs/qtsensors_generic.qtplugin\"  - \"!:\\resource\\qt\\plugins\\sensors\\qtsensors_generic.qtplugin\""
 
         !isEmpty(sensors):qtmobilitydeployment.pkg_postrules += sensors
-
-        equals(sensors_s60_31_enabled,yes) {
+        contains(QT_CONFIG, declarative): {
+            qtmobilitydeployment.sources += \
+            $${EPOCROOT50}epoc32/release/$(PLATFORM)/$(TARGET)/declarative_sensors.dll
             pluginstubs += \
-                "\"$$QT_MOBILITY_BUILD_TREE/plugins/sensors/s60_sensor_api/qmakepluginstubs/qtsensors_s60sensorapi.qtplugin\"  - \"!:\\resource\\qt\\plugins\\sensors\\qtsensors_s60sensorapi.qtplugin\""\
-                "\"$$QT_MOBILITY_BUILD_TREE/plugins/sensors/generic/qmakepluginstubs/qtsensors_generic.qtplugin\"  - \"!:\\resource\\qt\\plugins\\sensors\\qtsensors_generic.qtplugin\""
-        } else:equals(sensors_symbian_enabled,yes) {
-            pluginstubs += \
-                "\"$$QT_MOBILITY_BUILD_TREE/plugins/sensors/symbian/qmakepluginstubs/qtsensors_sym.qtplugin\"  - \"!:\\resource\\qt\\plugins\\sensors\\qtsensors_sym.qtplugin\""\
-                "\"$$QT_MOBILITY_BUILD_TREE/plugins/sensors/generic/qmakepluginstubs/qtsensors_generic.qtplugin\"  - \"!:\\resource\\qt\\plugins\\sensors\\qtsensors_generic.qtplugin\""
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\sensors\\qmakepluginstubs\\declarative_sensors.qtplugin\"  - \"!:\\resource\\qt\\imports\\QtMobility\\sensors\\declarative_sensors.qtplugin\""
+            qmldirs += \
+            "\"$$QT_MOBILITY_BUILD_TREE\\plugins\\declarative\\sensors\\qmldir\"  - \"!:\\resource\\qt\\imports\\QtMobility\\sensors\\qmldir\""
         }
-
     }
 
     !isEmpty(pluginstubs):qtmobilitydeployment.pkg_postrules += pluginstubs
+    !isEmpty(qmldirs):qtmobilitydeployment.pkg_postrules += qmldirs
 
     qtmobilitydeployment.path = /sys/bin
 
-    DEPLOYMENT += qtmobilitydeployment
-    
+    # Support backup and restore for QtMobility libraries and applications
+    mobilitybackup.sources = backup_registration.xml
+    mobilitybackup.path = c:/private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,)
+
+    DEPLOYMENT += qtmobilitydeployment\
+                mobilitybackup
+
     BLD_INF_RULES.prj_exports += "./qtmobility.iby           $$CORE_MW_LAYER_IBY_EXPORT_PATH(qtmobility.iby)"
     
 } else {
--- a/src/sensors/qsensor.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/sensors/qsensor.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -298,7 +298,30 @@
     Start retrieving values from the sensor.
     Returns true if the sensor was started, false otherwise.
 
-    Note that the sensor may fail to start for several reasons.
+    The sensor may fail to start for several reasons.
+
+    Once an application has started a sensor it must wait until the sensor receives a
+    new value before it can query the sensor's values. This is due to how the sensor
+    receives values from the system. Sensors do not (in general) poll for new values,
+    rather new values are pushed to the sensors as they happen.
+
+    For example, this code will not work as intended.
+
+    \badcode
+    sensor->start();
+    sensor->reading()->x(); // no data available
+    \endcode
+
+    To work correctly, the code that accesses the reading should ensure the
+    readingChanged() signal has been emitted.
+
+    \code
+        connect(sensor, SIGNAL(readingChanged()), this, SLOT(checkReading()));
+        sensor->start();
+    }
+    void MyClass::checkReading() {
+        sensor->reading()->x();
+    \endcode
 
     \sa QSensor::busy
 */
@@ -339,7 +362,10 @@
 
     Note that this will return 0 until a sensor backend is connected to a backend.
 
-    \sa isConnectedToBackend()
+    Also note that readings are not immediately available after start() is called.
+    Applications must wait for the readingChanged() signal to be emitted.
+
+    \sa isConnectedToBackend(), start()
 */
 
 QSensorReading *QSensor::reading() const
@@ -388,6 +414,11 @@
     \fn QSensor::readingChanged()
 
     This signal is emitted when the reading has changed.
+
+    Before this signal has been emitted for the first time, the sensor reading will
+    have uninitialized data.
+
+    \sa start()
 */
 
 /*!
--- a/src/sensors/qsensormanager.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/sensors/qsensormanager.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -227,6 +227,8 @@
     This is set in a config file and can be overridden if required.
     If no default is available the system will return the first registered
     sensor for \a type.
+
+    \sa {Determining the default sensor for a type}
 */
 QByteArray QSensor::defaultSensorForType(const QByteArray &type)
 {
@@ -238,7 +240,14 @@
     if (!d->backendsByType.contains(type))
         return QByteArray();
 
-    QSettings settings(QLatin1String("Nokia"), QLatin1String("Sensors"));
+    QSettings::Scope scope;
+#ifdef QTM_BUILD_UNITTESTS
+    // The unit test needs to modify Sensors.conf but it can't access the system directory
+    scope = QSettings::UserScope;
+#else
+    scope = QSettings::SystemScope;
+#endif
+    QSettings settings(scope, QLatin1String("Nokia"), QLatin1String("Sensors"));
     QVariant value = settings.value(QString(QLatin1String("Default/%1")).arg(QString::fromLatin1(type)));
     if (!value.isNull()) {
         QByteArray defaultIdentifier = value.toByteArray();
--- a/src/sensors/qsensorpluginloader.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/sensors/qsensorpluginloader.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -90,7 +90,14 @@
 
             continue;
         } else {
-            qWarning() << "QSensorPluginLoader: Failed to load plugin: " << plugins.at(i) << loader->errorString();
+            qWarning() << "QSensorPluginLoader: Failed to load plugin";
+            if (o == 0) {
+                qWarning() << "Reason: o == 0";
+            } else if (o->qt_metacast(m_iid) == 0) {
+                qWarning() << "Reason: o->qt_metacast(m_iid) == 0";
+            }
+            qWarning() << "Plugin:" << plugins.at(i);
+            qWarning() << "Error:" << loader->errorString();
         }
         delete o;
         loader->unload();
--- a/src/systeminfo/qsysteminfo.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -728,7 +728,7 @@
 
     Depending on platform, displayBrightness may not be available due to
     differing hardware, software or driver implementation. In which case this
-    will return 0.
+    will return -1.
 
     \sa QDesktopWidget::screenCount()
 */
@@ -738,7 +738,7 @@
 }
 
 /*!
-    Returns the color depth of the screen with the index \a screenNumber, in bits per pixel, or 0 if the screen is not found.
+    Returns the color depth of the screen with the index \a screenNumber, in bits per pixel, or -1 if the screen is not found, or an error occurs.
 
     \sa QDesktopWidget::screenCount()
 */
--- a/src/systeminfo/qsysteminfo_linux.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_linux.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -76,6 +76,20 @@
 #endif
 
 QTM_BEGIN_NAMESPACE
+static bool halAvailable()
+{
+#if !defined(QT_NO_DBUS)
+    QDBusConnection dbusConnection = QDBusConnection::systemBus();
+    if (dbusConnection.isConnected()) {
+        QDBusConnectionInterface *dbiface = dbusConnection.interface();
+        QDBusReply<bool> reply = dbiface->isServiceRegistered("org.freedesktop.Hal");
+        if (reply.isValid() && reply.value()) {
+            return reply.value();
+        }
+    }
+#endif
+    return false;
+}
 
 QSystemInfoPrivate::QSystemInfoPrivate(QSystemInfoLinuxCommonPrivate *parent)
  : QSystemInfoLinuxCommonPrivate(parent)
@@ -524,6 +538,103 @@
     return false;
 }
 
+QString QSystemDeviceInfoPrivate::model()
+{
+    if(halAvailable()) {
+#if !defined(QT_NO_DBUS)
+        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
+        QString model;
+        if (iface.isValid()) {
+            model = iface.getPropertyString("system.kernel.machine");
+            if(!model.isEmpty())
+                model += " ";
+            model += iface.getPropertyString("system.chassis.type");
+            if(!model.isEmpty())
+                return model;
+        }
+#endif
+    }
+    QFile file("/proc/cpuinfo");
+    if (!file.open(QIODevice::ReadOnly)) {
+        qDebug() << "Could not open /proc/cpuinfo";
+    } else {
+        QTextStream cpuinfo(&file);
+        QString line = cpuinfo.readLine();
+        while (!line.isNull()) {
+            line = cpuinfo.readLine();
+            if(line.contains("model name")) {
+                return line.split(": ").at(1).trimmed();
+            }
+        }
+    }
+    return QString();
+}
+
+QString QSystemDeviceInfoPrivate::productName()
+{
+    if(halAvailable()) {
+#if !defined(QT_NO_DBUS)
+        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
+        QString productName;
+        if (iface.isValid()) {
+            productName = iface.getPropertyString("info.product");
+            if(productName.isEmpty()) {
+                productName = iface.getPropertyString("system.product");
+                if(!productName.isEmpty())
+                    return productName;
+            } else {
+                return productName;
+            }
+        }
+#endif
+    }
+    const QDir dir("/etc");
+    if(dir.exists()) {
+        QStringList langList;
+        QFileInfoList localeList = dir.entryInfoList(QStringList() << "*release",
+                                                     QDir::Files | QDir::NoDotAndDotDot,
+                                                     QDir::Name);
+        foreach(const QFileInfo fileInfo, localeList) {
+            const QString filepath = fileInfo.filePath();
+            QFile file(filepath);
+            if (file.open(QIODevice::ReadOnly)) {
+                QTextStream prodinfo(&file);
+                QString line = prodinfo.readLine();
+                while (!line.isNull()) {
+                    if(filepath.contains("lsb.release")) {
+                        if(line.contains("DISTRIB_DESCRIPTION")) {
+                            return line.split("=").at(1).trimmed();
+                        }
+                    } else {
+                        return line;
+                    }
+                    line = prodinfo.readLine();
+                }
+            }
+        } //end foreach
+    }
+
+    QFile file("/etc/issue");
+    if (!file.open(QIODevice::ReadOnly)) {
+        qDebug() << "Could not open /proc/cpuinfo";
+    } else {
+        QTextStream prodinfo(&file);
+        QString line = prodinfo.readLine();
+        while (!line.isNull()) {
+            line = prodinfo.readLine();
+            if(!line.isEmpty()) {
+                QStringList lineList = line.split(" ");
+                for(int i = 0; i < lineList.count(); i++) {
+                    if(lineList.at(i).toFloat()) {
+                        return lineList.at(i-1) + " "+ lineList.at(i);
+                    }
+                }
+            }
+        }
+    }
+    return QString();
+}
+
  QSystemScreenSaverPrivate::QSystemScreenSaverPrivate(QSystemScreenSaverLinuxCommonPrivate *parent)
          : QSystemScreenSaverLinuxCommonPrivate(parent), currentPid(0)
  {
--- a/src/systeminfo/qsysteminfo_linux_common.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_linux_common.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -862,8 +862,13 @@
 
 int QSystemDisplayInfoLinuxCommonPrivate::colorDepth(int screen)
 {
+    QDesktopWidget wid;
+
+    if(wid.screenCount() - 1 < screen) {
+        return -1;
+    }
+
 #ifdef Q_WS_X11
-    QDesktopWidget wid;
     return wid.screen(screen)->x11Info().depth();
 #else
         return QPixmap::defaultDepth();
@@ -873,7 +878,10 @@
 
 int QSystemDisplayInfoLinuxCommonPrivate::displayBrightness(int screen)
 {
-    Q_UNUSED(screen);
+    QDesktopWidget wid;
+    if(wid.screenCount() - 1 < screen) {
+        return -1;
+    }
     if(halIsAvailable) {
 #if !defined(QT_NO_DBUS)
         QHalInterface iface;
@@ -1255,102 +1263,6 @@
     return QString();
 }
 
-QString QSystemDeviceInfoLinuxCommonPrivate::model()
-{
-    if(halIsAvailable) {
-#if !defined(QT_NO_DBUS)
-        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
-        QString model;
-        if (iface.isValid()) {
-            model = iface.getPropertyString("system.kernel.machine");
-            if(!model.isEmpty())
-                model += " ";
-            model += iface.getPropertyString("system.chassis.type");
-            if(!model.isEmpty())
-                return model;
-        }
-#endif
-    }
-    QFile file("/proc/cpuinfo");
-    if (!file.open(QIODevice::ReadOnly)) {
-        qDebug() << "Could not open /proc/cpuinfo";
-    } else {
-        QTextStream cpuinfo(&file);
-        QString line = cpuinfo.readLine();
-        while (!line.isNull()) {
-            line = cpuinfo.readLine();
-            if(line.contains("model name")) {
-                return line.split(": ").at(1).trimmed();
-            }
-        }
-    }
-    return QString();
-}
-
-QString QSystemDeviceInfoLinuxCommonPrivate::productName()
-{
-    if(halIsAvailable) {
-#if !defined(QT_NO_DBUS)
-        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
-        QString productName;
-        if (iface.isValid()) {
-            productName = iface.getPropertyString("info.product");
-            if(productName.isEmpty()) {
-                productName = iface.getPropertyString("system.product");
-                if(!productName.isEmpty())
-                    return productName;
-            } else {
-                return productName;
-            }
-        }
-#endif
-    }
-    const QDir dir("/etc");
-    if(dir.exists()) {
-        QStringList langList;
-        QFileInfoList localeList = dir.entryInfoList(QStringList() << "*release",
-                                                     QDir::Files | QDir::NoDotAndDotDot,
-                                                     QDir::Name);
-        foreach(const QFileInfo fileInfo, localeList) {
-            const QString filepath = fileInfo.filePath();
-            QFile file(filepath);
-            if (file.open(QIODevice::ReadOnly)) {
-                QTextStream prodinfo(&file);
-                QString line = prodinfo.readLine();
-                while (!line.isNull()) {
-                    if(filepath.contains("lsb.release")) {
-                        if(line.contains("DISTRIB_DESCRIPTION")) {
-                            return line.split("=").at(1).trimmed();
-                        }
-                    } else {
-                        return line;
-                    }
-                    line = prodinfo.readLine();
-                }
-            }
-        } //end foreach
-    }
-
-    QFile file("/etc/issue");
-    if (!file.open(QIODevice::ReadOnly)) {
-        qDebug() << "Could not open /proc/cpuinfo";
-    } else {
-        QTextStream prodinfo(&file);
-        QString line = prodinfo.readLine();
-        while (!line.isNull()) {
-            line = prodinfo.readLine();
-            if(!line.isEmpty()) {
-                QStringList lineList = line.split(" ");
-                for(int i = 0; i < lineList.count(); i++) {
-                    if(lineList.at(i).toFloat()) {
-                        return lineList.at(i-1) + " "+ lineList.at(i);
-                    }
-                }
-            }
-        }
-    }
-    return QString();
-}
 
 QSystemDeviceInfo::InputMethodFlags QSystemDeviceInfoLinuxCommonPrivate::inputMethodType()
 {
--- a/src/systeminfo/qsysteminfo_linux_common_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_linux_common_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -205,8 +205,8 @@
     QString imei() {return QString();}
     QString imsi() {return QString();}
     QString manufacturer();
-    QString model();
-    QString productName();
+    QString model()  {return QString();}
+    QString productName()  {return QString();}
 
     QSystemDeviceInfo::InputMethodFlags inputMethodType();
 
--- a/src/systeminfo/qsysteminfo_linux_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_linux_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -183,6 +183,8 @@
     bool isDeviceLocked();
     QSystemDeviceInfo::Profile currentProfile();
     void setConnection();
+    QString model();
+    QString productName();
 
 private:
 #if !defined(QT_NO_DBUS)
--- a/src/systeminfo/qsysteminfo_maemo.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_maemo.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -917,7 +917,10 @@
 
 int QSystemDisplayInfoPrivate::displayBrightness(int screen)
 {
-    Q_UNUSED(screen);
+    QDesktopWidget wid;
+    if(wid.screenCount() - 1 < screen) {
+        return -1;
+    }
     GConfItem currentBrightness("/system/osso/dsm/display/display_brightness");
     GConfItem maxBrightness("/system/osso/dsm/display/max_display_brightness_levels");
     if(maxBrightness.value().toInt()) {
@@ -1225,12 +1228,43 @@
     }
 }
 
+QString QSystemDeviceInfoPrivate::model()
+{
+    QString name;
+    if(productName()== "RX-51")
+        return "N900";
+
+    name = "Harmattan"; //fake this for now
+
+    return name;
+
+}
+
+QString QSystemDeviceInfoPrivate::productName()
+{
+#if !defined(QT_NO_DBUS)
+#if defined(Q_WS_MAEMO_6)
+    QString dBusService = "com.nokia.SystemInfo";
+#else
+    /* Maemo 5 */
+    QString dBusService = "com.nokia.SystemInfo";
+#endif
+    QDBusInterface connectionInterface(dBusService,
+                                       "/com/nokia/SystemInfo",
+                                       "com.nokia.SystemInfo",
+                                       QDBusConnection::systemBus());
+
+    QDBusReply< QByteArray > reply = connectionInterface.call("GetConfigValue","/component/product");
+    return reply.value();
+#endif
+}
+
 #endif
 
 //////////////
 ///////
 QSystemScreenSaverPrivate::QSystemScreenSaverPrivate(QObject *parent)
-        : QSystemScreenSaverLinuxCommonPrivate(parent)
+        : QSystemScreenSaverLinuxCommonPrivate(parent),isInhibited(0)
 {
     ssTimer = new QTimer(this);
 #if !defined(QT_NO_DBUS)
@@ -1260,7 +1294,10 @@
         // The reason for this is to avoid the situation where
         // a crashed/hung application keeps the display on.
         ssTimer->start(30000);
-     }
+        isInhibited = true;
+    } else {
+        isInhibited = false;
+    }
      return screenSaverInhibited();
 }
 
@@ -1277,17 +1314,37 @@
 bool QSystemScreenSaverPrivate::screenSaverInhibited()
 {
     bool displayOn = false;
+    GConfItem screenBlankItem("/system/osso/dsm/display/inhibit_blank_mode");
+    /* 0 - no inhibit
+       1 - inhibit dim with charger
+       2 - inhibit blank with charger (display still dims)
+       3 - inhibit dim (always)
+       4 - inhibit blank (always; display still dims)
+*/
+    int blankingItem = screenBlankItem.value().toInt();
+
+    bool isBlankingInhibited = false;
+    QSystemDeviceInfo devInfo(this);
+    QSystemDeviceInfo::PowerState batState = devInfo.currentPowerState();
+
+    if( ((batState == QSystemDeviceInfo::WallPower || batState == QSystemDeviceInfo::WallPowerChargingBattery)
+       && blankingItem == 2) || blankingItem == 4) {
+        isBlankingInhibited = true;
+    }
+
 #if !defined(QT_NO_DBUS)
     if (mceConnectionInterface->isValid()) {
         // The most educated guess for the screen saver being inhibited is to determine
         // whether the display is on. That is because the QSystemScreenSaver cannot
         // prevent other processes from blanking the screen (like, if
         // MCE decides to blank the screen for some reason).
+        // but that means it reports to be inhibited when display is on. meaning
+        // effectly always inhibited by default. so we try a bit harder
         QDBusReply<QString> reply = mceConnectionInterface->call("get_display_status");
         displayOn = ("on" == reply.value());
     }
 #endif
-    return displayOn;
+    return (displayOn && isBlankingInhibited && isInhibited);
 }
 
 #include "moc_qsysteminfo_maemo_p.cpp"
--- a/src/systeminfo/qsysteminfo_maemo_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_maemo_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -237,6 +237,8 @@
     bool isDeviceLocked();
     QSystemDeviceInfo::Profile currentProfile();
     QSystemDeviceInfo::PowerState currentPowerState();
+    QString model();
+    QString productName();
 
 protected:
 #if !defined(QT_NO_DBUS)
@@ -273,6 +275,7 @@
 
     bool screenSaverInhibited();
     bool setScreenSaverInhibit();
+    bool isInhibited;
 
 private Q_SLOTS:
     void wakeUpDisplay();
--- a/src/systeminfo/qsysteminfo_s60.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/systeminfo/qsysteminfo_s60.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -1025,6 +1025,10 @@
 
 QSystemDeviceInfo::SimStatus QSystemDeviceInfoPrivate::simStatus()
 {
+#ifdef SYMBIAN_3_1
+    if (!DeviceInfo::instance()->subscriberInfo()->imsi().isEmpty())
+        return QSystemDeviceInfo::SingleSimAvailable;
+#else //SYMBIAN_3_1
     TInt lockStatus = 0;
     TInt err = RProperty::Get(KPSUidStartup, KStartupSimLockStatus, lockStatus);
     if (err == KErrNone && (TPSSimLockStatus)lockStatus != ESimLockOk) {
@@ -1036,7 +1040,7 @@
     if (err == KErrNone && TPSSimStatus(simStatus) == ESimUsable) {
         return QSystemDeviceInfo::SingleSimAvailable;
     }
-
+#endif //SYMBIAN_3_1
     return QSystemDeviceInfo::SimNotAvailable;
 }
 
--- a/src/versit/README	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-Versit
-
-The Versit* synchronization component of Qt Mobility is still in ALPHA.  It has
- not undergone the same level of review and testing as the rest of the APIs.
-
-The API exposed by the classes in this component are not stable, and will 
-undergo modification or removal prior to the final release of Qt Mobility.
-
-[*] Versit is a trademark of the Internet Mail Consortium.
--- a/src/versit/qvcard21writer.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qvcard21writer.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -48,8 +48,7 @@
 QTM_USE_NAMESPACE
 
 /*! Constructs a writer. */
-QVCard21Writer::QVCard21Writer()
-    : QVersitDocumentWriter(QByteArray("VCARD"),QByteArray("2.1"))
+QVCard21Writer::QVCard21Writer() : QVersitDocumentWriter()
 {
 }
 
--- a/src/versit/qvcard30writer.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qvcard30writer.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -48,8 +48,7 @@
 QTM_USE_NAMESPACE
 
 /*! Constructs a writer. */
-QVCard30Writer::QVCard30Writer()
-    : QVersitDocumentWriter(QByteArray("VCARD"),QByteArray("3.0"))
+QVCard30Writer::QVCard30Writer() : QVersitDocumentWriter()
 {
     mPropertyNameMappings.insert(
         QLatin1String("X-NICKNAME"),QLatin1String("NICKNAME"));
--- a/src/versit/qvcardbackuphandlers_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QList>
-#include <QString>
-#include <QTextStream>
-#include <QUrl>
-#include "qvcardbackuphandlers_p.h"
-#include "qcontact.h"
-#include "qcontactdetail.h"
-#include "qversitdocument.h"
-#include "qversitproperty.h"
-
-QTM_USE_NAMESPACE
-
-QTM_BEGIN_NAMESPACE
-
-Q_DEFINE_LATIN1_CONSTANT(PropertyName, "X-NOKIA-QCONTACTFIELD");
-Q_DEFINE_LATIN1_CONSTANT(DetailDefinitionParameter, "DETAIL");
-Q_DEFINE_LATIN1_CONSTANT(FieldParameter, "FIELD");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameter, "DATATYPE");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterVariant, "VARIANT");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterDate, "DATE");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterDateTime, "DATETIME");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterTime, "TIME");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterBool, "BOOL");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterInt, "INT");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterUInt, "UINT");
-Q_DEFINE_LATIN1_CONSTANT(DatatypeParameterUrl, "URL");
-Q_DEFINE_LATIN1_CONSTANT(GroupPrefix, "G");
-
-QTM_END_NAMESPACE
-
-/*
- * Returns a list of details generated from a Versit group.
- */
-QList<QContactDetail> DetailGroupMap::detailsInGroup(const QString& groupName) const
-{
-    QList<int> detailIds = mDetailGroupName.keys(groupName);
-    QList<QContactDetail> details;
-    foreach (int detailId, detailIds) {
-        details << mDetailById[detailId];
-    }
-    return details;
-}
-
-/*
- * Inserts the association between \a detail and \a groupName to the map.
- * The detail must have a key (ie. have already been saved in a contact) and the group name must not
- * be the empty string.
- */
-void DetailGroupMap::insert(const QString& groupName, const QContactDetail& detail)
-{
-    Q_ASSERT(!groupName.isEmpty());
-    mDetailGroupName[detail.key()] = groupName;
-    mDetailById[detail.key()] = detail;
-}
-
-/*
- * Replaces the detail currently in the map with \a detail.
- * The detail must have a key (ie. have already been saved in a contact).
- */
-void DetailGroupMap::update(const QContactDetail& detail)
-{
-    Q_ASSERT(detail.key());
-    mDetailById[detail.key()] = detail;
-}
-
-/*!
- * Removes details and groups from the map.
- */
-void DetailGroupMap::clear()
-{
-    mDetailGroupName.clear();
-    mDetailById.clear();
-}
-
-
-QVCardImporterBackupHandler::QVCardImporterBackupHandler()
-{
-}
-
-void QVCardImporterBackupHandler::propertyProcessed(
-        const QVersitDocument& document,
-        const QVersitProperty& property,
-        bool alreadyProcessed,
-        const QContact& contact,
-        QList<QContactDetail>* updatedDetails)
-{
-    Q_UNUSED(document)
-    Q_UNUSED(contact)
-    QString group;
-    if (!property.groups().isEmpty())
-        group = property.groups().first();
-    if (!alreadyProcessed) {
-        if (property.name() != PropertyName)
-            return;
-        if (property.groups().size() != 1)
-            return;
-        QMultiHash<QString,QString> parameters = property.parameters();
-        QString definitionName = parameters.value(DetailDefinitionParameter);
-        QString fieldName = parameters.value(FieldParameter);
-
-        // Find a detail previously seen with the same definitionName, which was generated from
-        // a property from the same group
-        QContactDetail detail(definitionName);
-        foreach (const QContactDetail& previousDetail, mDetailGroupMap.detailsInGroup(group)) {
-            if (previousDetail.definitionName() == definitionName) {
-                detail = previousDetail;
-            }
-        }
-        // If not found, it's a new empty detail with the definitionName set.
-
-        detail.setValue(fieldName, deserializeValue(property));
-
-        // Replace the equivalent detail in updatedDetails with the new one
-        QMutableListIterator<QContactDetail> it(*updatedDetails);
-        while (it.hasNext()) {
-            if (it.next().key() == detail.key()) {
-                it.remove();
-                break;
-            }
-        }
-        updatedDetails->append(detail);
-    }
-    if (!group.isEmpty()) {
-        // Keep track of which details were generated from which Versit groups
-        foreach (const QContactDetail& detail, *updatedDetails) {
-            mDetailGroupMap.insert(group, detail);
-        }
-    }
-}
-
-QVariant QVCardImporterBackupHandler::deserializeValue(const QVersitProperty& property)
-{
-    // Import the field
-    if (property.parameters().contains(DatatypeParameter, DatatypeParameterVariant)) {
-        // The value was stored as a QVariant serialized in a QByteArray
-        QDataStream stream(property.variantValue().toByteArray());
-        QVariant value;
-        stream >> value;
-        return value;
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterDate)) {
-        // The value was a QDate serialized as a string
-        return QDate::fromString(property.value(), Qt::ISODate);
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterTime)) {
-        // The value was a QTime serialized as a string
-        return QTime::fromString(property.value(), Qt::ISODate);
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterDateTime)) {
-        // The value was a QDateTime serialized as a string
-        return QDateTime::fromString(property.value(), Qt::ISODate);
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterBool)) {
-        // The value was a bool serialized as a string
-        return property.value().toInt() != 0;
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterInt)) {
-        // The value was an int serialized as a string
-        return property.value().toInt();
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterUInt)) {
-        // The value was a uint serialized as a string
-        return property.value().toUInt();
-    } else if (property.parameters().contains(DatatypeParameter, DatatypeParameterUrl)) {
-        // The value was a QUrl serialized as a string
-        return QUrl(property.value());
-    } else {
-        // The value was stored as a QString or QByteArray
-        return property.variantValue();
-    }
-}
-
-void QVCardImporterBackupHandler::documentProcessed(
-        const QVersitDocument& document,
-        QContact* contact)
-{
-    Q_UNUSED(document)
-    Q_UNUSED(contact)
-    mDetailGroupMap.clear();
-}
-
-QVCardExporterBackupHandler::QVCardExporterBackupHandler()
-    : mDetailNumber(0)
-{
-}
-
-void QVCardExporterBackupHandler::detailProcessed(
-        const QContact& contact,
-        const QContactDetail& detail,
-        const QSet<QString>& processedFields,
-        const QVersitDocument& document,
-        QList<QVersitProperty>* toBeRemoved,
-        QList<QVersitProperty>* toBeAdded)
-{
-    Q_UNUSED(contact)
-    Q_UNUSED(document)
-    Q_UNUSED(toBeRemoved)
-    if (detail.accessConstraints().testFlag(QContactDetail::ReadOnly))
-        return;
-    QVariantMap fields = detail.variantValues();
-    // fields from the same detail have the same group so the importer can collate them
-    QString detailGroup = GroupPrefix + QString::number(mDetailNumber++);
-    int toBeAddedCount = toBeAdded->count();
-    bool propertiesSynthesized = false;
-    for (QVariantMap::const_iterator it = fields.constBegin(); it != fields.constEnd(); it++) {
-        if (!processedFields.contains(it.key()) && !it.value().toString().isEmpty()) {
-            // Generate a property for the unknown field
-            QVersitProperty property;
-            property.setGroups(QStringList(detailGroup));
-            property.setName(PropertyName);
-            property.insertParameter(DetailDefinitionParameter, detail.definitionName());
-            property.insertParameter(FieldParameter, it.key());
-
-            serializeValue(&property, it.value());
-
-            toBeAdded->append(property);
-            propertiesSynthesized = true;
-        }
-    }
-    if (propertiesSynthesized) {
-        // We need to group the already-generated properties with the newly synthesized ones
-        for (int i = 0; i < toBeAddedCount; i++) {
-            QVersitProperty& property = (*toBeAdded)[i];
-            property.setGroups(property.groups() << detailGroup);
-        }
-    }
-}
-
-void QVCardExporterBackupHandler::serializeValue(QVersitProperty* property, const QVariant& value)
-{
-    // serialize the value
-    if (value.type() == QVariant::String
-        || value.type() == QVariant::ByteArray) {
-        // store QStrings and QByteArrays as-is
-        property->setValue(value);
-    } else if (value.type() == QVariant::Date) {
-        // Store a QDate as a string
-        QString valueString(value.toDate().toString(Qt::ISODate));
-        property->insertParameter(DatatypeParameter, DatatypeParameterDate);
-        property->setValue(valueString);
-    } else if (value.type() == QVariant::Time) {
-        // Store a QTime as a string
-        QString valueString(value.toTime().toString(Qt::ISODate));
-        property->insertParameter(DatatypeParameter, DatatypeParameterTime);
-        property->setValue(valueString);
-    } else if (value.type() == QVariant::DateTime) {
-        // Store a QDateTime as a string
-        QString valueString(value.toDateTime().toString(Qt::ISODate));
-        property->insertParameter(DatatypeParameter, DatatypeParameterDateTime);
-        property->setValue(valueString);
-    } else if (value.type() == QVariant::Bool) {
-        // Store an int as a string
-        QString valueString(QString::number(value.toBool() ? 1 : 0));
-        property->insertParameter(DatatypeParameter, DatatypeParameterBool);
-        property->setValue(valueString);
-    } else if (value.type() == QVariant::Int) {
-        // Store an int as a string
-        QString valueString(QString::number(value.toInt()));
-        property->insertParameter(DatatypeParameter, DatatypeParameterInt);
-        property->setValue(valueString);
-    } else if (value.type() == QVariant::UInt) {
-        // Store a uint as a string
-        QString valueString(QString::number(value.toUInt()));
-        property->insertParameter(DatatypeParameter, DatatypeParameterUInt);
-        property->setValue(valueString);
-    } else if (value.type() == QVariant::Url) {
-        // Store a QUrl as a string
-        QString valueString(value.toUrl().toString());
-        property->insertParameter(DatatypeParameter, DatatypeParameterUrl);
-        property->setValue(valueString);
-    } else {
-        // Store other types by serializing the QVariant in a QByteArray
-        QByteArray valueBytes;
-        QDataStream stream(&valueBytes, QIODevice::WriteOnly);
-        stream << value;
-        property->insertParameter(DatatypeParameter, DatatypeParameterVariant);
-        property->setValue(valueBytes);
-    }
-}
-
-void QVCardExporterBackupHandler::contactProcessed(
-        const QContact& contact,
-        QVersitDocument* document)
-{
-    Q_UNUSED(contact)
-    Q_UNUSED(document)
-    mDetailNumber = 0;
-}
--- a/src/versit/qvcardbackuphandlers_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Mobility Components.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights.  These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVCARDBACKUPHANDLERS_P_H
-#define QVCARDBACKUPHANDLERS_P_H
-
-#include <QList>
-#include <QSet>
-#include "qversitcontactimporter.h"
-#include "qversitcontactexporter.h"
-
-QTM_BEGIN_NAMESPACE
-
-class QContact;
-class QContactDetail;
-
-/*
- * This is a map from Versit group names to the details that were generated from properties with the
- * said groups.  Multiple details can be associated with a single group.
- */
-class DetailGroupMap
-{
-public:
-    QList<QContactDetail> detailsInGroup(const QString& groupName) const;
-    void insert(const QString& groupName, const QContactDetail& detail);
-    void update(const QContactDetail& detail);
-    void clear();
-
-private:
-    QHash<int, QString> mDetailGroupName; // detailid -> group name
-    QHash<int, QContactDetail> mDetailById; // detailid -> detail
-};
-
-/* See QVersitContactImporter::createBackupHandler() */
-class QVCardImporterBackupHandler : public QVersitContactImporterPropertyHandlerV2
-{
-public:
-    QVCardImporterBackupHandler();
-    void propertyProcessed(const QVersitDocument& document,
-                           const QVersitProperty& property,
-                           bool alreadyProcessed,
-                           const QContact& contact,
-                           QList<QContactDetail>* updatedDetails);
-    void documentProcessed(const QVersitDocument& document,
-                           QContact* contact);
-
-private:
-    static QVariant deserializeValue(const QVersitProperty& property);
-    DetailGroupMap mDetailGroupMap; // remembers which details came from which groups
-
-};
-
-/* See QVersitContactExporter::createBackupHandler() */
-class QVCardExporterBackupHandler : public QVersitContactExporterDetailHandlerV2
-{
-public:
-    QVCardExporterBackupHandler();
-    void detailProcessed(const QContact& contact,
-                         const QContactDetail& detail,
-                         const QSet<QString>& processedFields,
-                         const QVersitDocument& document,
-                         QList<QVersitProperty>* toBeRemoved,
-                         QList<QVersitProperty>* toBeAdded);
-    void contactProcessed(const QContact& contact,
-                          QVersitDocument* document);
-private:
-    static void serializeValue(QVersitProperty* property, const QVariant& value);
-    int mDetailNumber;
-};
-
-QTM_END_NAMESPACE
-
-#endif
--- a/src/versit/qversitcontactexporter.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactexporter.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -42,7 +42,6 @@
 
 #include "qversitcontactexporter.h"
 #include "qversitcontactexporter_p.h"
-#include "qvcardbackuphandlers_p.h"
 #include "qmobilityglobal.h"
 
 #include <qcontact.h>
@@ -57,7 +56,6 @@
   implement custom export behaviour for certain contact details.
 
   This interface is replaced by QVersitContactExporterDetailHandlerV2.
-  \ingroup versit
 
   \sa QVersitContactExporter
  */
@@ -95,11 +93,11 @@
   \class QVersitContactExporterDetailHandlerV2
   \brief The QVersitContactExporterDetailHandlerV2 class is an interface for clients wishing to
   implement custom export behaviour for certain contact details.
+  \ingroup versit-extension
+  \inmodule QtVersit
 
   This interface supercedes QVersitContactImporterPropertyHandler.
 
-  \ingroup versit
-
   \sa QVersitContactExporter
  */
 
@@ -109,7 +107,7 @@
  */
 
 /*!
-  \fn void QVersitContactExporterDetailHandlerV2::detailProcessed(const QContact& contact, const QContactDetail& detail, const QSet<QString>& processedFields, const QVersitDocument& document, QList<QVersitProperty>* toBeRemoved, QList<QVersitProperty>* toBeAdded)
+  \fn void QVersitContactExporterDetailHandlerV2::detailProcessed(const QContact& contact, const QContactDetail& detail, const QVersitDocument& document, QSet<QString>* processedFields, QList<QVersitProperty>* toBeRemoved, QList<QVersitProperty>* toBeAdded)
 
   Process \a detail and provide a list of updated \l{QVersitProperty}{QVersitProperties} by
   modifying the \a toBeRemoved and \a toBeAdded lists.  
@@ -119,15 +117,17 @@
   provide support for QContactDetails not supported by QVersitContactExporter.
 
   The supplied \a contact is the container for the \a detail.  \a processedFields contains a list of
-  fields in the \a detail that were considered by the QVersitContactExporter in processing the
-  detail.  \a document holds the state of the document before the detail was processed by the
-  exporter.
+  fields in the \a detail that were considered by the QVersitContactExporter or another handler in
+  processing the detail.  \a document holds the state of the document before the detail was
+  processed by the exporter.
   
   \a toBeRemoved and \a toBeAdded are initially filled with a list of properties that the exporter
   will remove from and add to the document.  These lists can be modified (by removing, modifying or
   adding properties) by the handler to control the changes that will actually be made to the
   document.  If a property is to be modified in the document, the old version will appear in the
-  \a toBeRemoved list and the new version will appear in the \a toBeAdded list.
+  \a toBeRemoved list and the new version will appear in the \a toBeAdded list.  When the handler
+  uses a field from the detail, it should update the processedFields set to reflect this to inform
+  later handlers that the field has already been processed.
 
   After the handler returns control back to the exporter, the properties in the \a toBeRemoved
   list will be removed and the properties in the \a toBeAdded list will be appended to the document.
@@ -143,15 +143,11 @@
 */
 
 /*!
-  \fn int QVersitContactExporterDetailHandlerV2::version() const
-  Returns the version of the handler.  Currently, always returns 2.
-*/
-
-/*!
   \class QVersitContactExporter
   \brief The QVersitContactExporter class converts \l {QContact}{QContacts} into
   \l {QVersitDocument}{QVersitDocuments}.
   \ingroup versit
+  \inmodule QtVersit
 
   This class is used to convert lists of \l {QContact}{QContacts} (which may be stored in a
   QContactManager) into lists of \l {QVersitDocument}{QVersitDocuments} (which may be written to
@@ -159,6 +155,11 @@
   between contacts and Versit documents.  The exporter can be extended by clients by associating
   resource and detail handlers.
 
+  Here is a simple example of how to use QVersitContactExporter:
+  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export example
+
+  \section1 Extension via handlers
+
   A \l QVersitResourceHandler is associated with the exporter to supply the behaviour for loading
   files from persistent storage.  By default, this is set to a \l QVersitDefaultResourceHandler,
   which supports basic resource loading from the file system.  An alternative resource handler
@@ -166,13 +167,17 @@
 
   By associating a \l QVersitContactExporterDetailHandlerV2 with the exporter using
   setDetailHandler(), the client can pass in a handler to override the processing of details and/or
-  handle details that QVersitContactExporter doesn't support.  A "backup" handler is provided by
-  QVersitContactExporterDetailHandlerV2::createBackupHandler(), which serializes any details
-  that the standard QVersitContactExporter doesn't support to the vCard.
-
-
-  An example usage of QVersitContactExporter:
-  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export example
+  handle details that QVersitContactExporter doesn't support.  Also, handlers can be implicitly
+  associated to an exporter through the \l{Versit Plugins}{handler plugin mechanism}.  The exporter
+  can be constructed with a profile, which gives hints about what kind of handlers should be added
+  to it.  For example, the backup profile can be used to instruct the exporter to encode any unknown
+  details in the vCard such that it can be reconstructed later (a QVersitContactImporter constructed
+  under the backup profile can be used to decode it).  To illustrate, a backup exporter can be
+  constructed with:
+  \code
+  QVersitContactExporter exporter(QVersitContactHandlerFactory::ProfileBackup);
+  \endcode
+  For more details on how the backup plugin works, see \l{Versit Plugins}
 
   \section1 Exporting group relationships
   The exporter does not handle QContactRelationships at all.
@@ -201,55 +206,6 @@
 
 
 /*!
-  Constructs and returns a detail handler that encodes all details not handled by the base exporter.
-  The caller is responsible for deleting the object.
-
-  This handler encodes all writable details that the exporter doesn't recognise.  The format it uses
-  to encode the detail is as follows:
-  \list
-  \o All generated properties will have the name X-NOKIA-QCONTACTFIELD
-  \o All generated properties will have a single Versit group, and all properties generated from a
-     single detail will have the same group.
-  \o All generated properties will have at least the parameters DETAIL, which holds the definition
-     name of the QContactDetail from which it was generated, and FIELD, which holds the name of the
-     field within the detail from which it was generated.
-  \o If the field is of type QString or QByteArray, the property's value is set directly to the
-     value of the field.  (For a QByteArray value, the QVersitWriter will base-64 encode it.)
-  \o If the field is of type bool, int, uint, QDate, QTime, QDateTime or QUrl a the property's
-     value is set to a string representation of the field.  A parameter DATATYPE is added to the
-     property with value BOOL, INT, UINT, DATE, TIME or DATETIME depending on the type.
-  \o If the field is of some other type, the field value is encoded to a QByteArray via QDataStream
-     (and the resulting byte array is base-64 encoded by the QVersitWriter).  In this case, the
-     parameter DATATYPE=VARIANT is added to the Versit property.
-  \endlist
-
-  For example, a detail with definition name "Pet" and fields "Name"="Rex" and
-  "Age"=(int)14 will be exported to the vCard properties:
-  \code
-  G0.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Name:Rex
-  G0.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Age;DATATYPE=INT:14
-  \endcode
-
-  And the next detail (say, "Pet" with a field "Name"="Molly" will generate:
-  \code
-  G1.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Name:Molly
-  \endcode
-
-  The properties produced by this class can be imported by the importer "backup" property handler
-  (created by QVersitContactImporterPropertyHandlerV2::createBackupHandler()) to reproduce the
-  original \l{QContactDetail}{QContactDetails}.
-
-  Clients wishing to implement their own detail handler and also benefit from the functionality of
-  the backup handler can use this function to construct one, and wrap a custom
-  QVersitContactExporterDetailHandlerV2 around it.  In the implementation of detailProcessed and
-  contactProcessed, the respective functions in the backup handler should be called as the last
-  step (ensuring the arguments are correctly updated and passed through).
- */
-QVersitContactExporterDetailHandlerV2* QVersitContactExporterDetailHandlerV2::createBackupHandler() {
-    return new QVCardExporterBackupHandler;
-}
-
-/*!
  * Constructs a new contact exporter
  */
 QVersitContactExporter::QVersitContactExporter()
@@ -258,6 +214,18 @@
 }
 
 /*!
+ * Constructs a new exporter for the given \a profile.  The profile strings should be one of those
+ * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Versit
+ * Plugin}{Versit plugin}.
+ *
+ * The profile determines which plugins will be loaded to supplement the exporter.
+ */
+QVersitContactExporter::QVersitContactExporter(const QString& profile)
+    : d(new QVersitContactExporterPrivate(profile))
+{
+}
+
+/*!
  * Frees any memory in use by this contact exporter.
  */
 QVersitContactExporter::~QVersitContactExporter()
@@ -283,6 +251,7 @@
     foreach (const QContact& contact, contacts) {
         QVersitDocument versitDocument;
         versitDocument.setType(versitType);
+        versitDocument.setComponentType(QLatin1String("VCARD"));
         QVersitContactExporter::Error error;
         if (d->exportContact(contact, versitDocument, &error)) {
             d->mDocuments.append(versitDocument);
@@ -346,8 +315,7 @@
  */
 void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandlerV2* handler)
 {
-    if (handler)
-        d->mDetailHandlerVersion = handler->version();
+    d->mDetailHandlerVersion = 2;
     d->mDetailHandler = 0;
     d->mDetailHandler2 = handler;
 }
--- a/src/versit/qversitcontactexporter.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactexporter.h	Mon Oct 04 01:37:06 2010 +0300
@@ -71,17 +71,16 @@
 class Q_VERSIT_EXPORT QVersitContactExporterDetailHandlerV2
 {
 public:
-    static QVersitContactExporterDetailHandlerV2* createBackupHandler();
     virtual ~QVersitContactExporterDetailHandlerV2() {}
+
     virtual void detailProcessed(const QContact& contact,
                                  const QContactDetail& detail,
-                                 const QSet<QString>& processedFields,
                                  const QVersitDocument& document,
+                                 QSet<QString>* processedFields,
                                  QList<QVersitProperty>* toBeRemoved,
                                  QList<QVersitProperty>* toBeAdded) = 0;
     virtual void contactProcessed(const QContact& contact,
                                   QVersitDocument* document) = 0;
-    virtual int version() const { return 2; }
 };
 
 class Q_VERSIT_EXPORT QVersitContactExporter
@@ -94,6 +93,7 @@
     };
 
     QVersitContactExporter();
+    QVersitContactExporter(const QString& profile);
     ~QVersitContactExporter();
 
     bool exportContacts(const QList<QContact>& contacts, QVersitDocument::VersitType versitType);
@@ -105,11 +105,8 @@
     void setResourceHandler(QVersitResourceHandler* handler);
     QVersitResourceHandler* resourceHandler() const;
 
-    // Deprecated:
-
+    /* deprecated and internal */
     void Q_DECL_DEPRECATED setDetailHandler(QVersitContactExporterDetailHandler* handler);
-    QList<QVersitDocument> Q_DECL_DEPRECATED exportContacts(const QList<QContact>& contacts);
-    /* deprecated and internal */
     Q_DECL_DEPRECATED QVersitContactExporterDetailHandler* detailHandler() const;
 
 private:
--- a/src/versit/qversitcontactexporter_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactexporter_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -41,7 +41,7 @@
 
 #include "qversitcontactexporter.h"
 #include "qversitcontactexporter_p.h"
-#include "qversitdefs_p.h"
+#include "qversitcontactsdefs_p.h"
 #include "versitutils_p.h"
 #include "qmobilityglobal.h"
 
@@ -66,6 +66,8 @@
 #include <qcontactfamily.h>
 #include <qcontactdisplaylabel.h>
 #include <qcontactthumbnail.h>
+#include "qversitcontacthandler.h"
+#include "qversitcontactpluginloader_p.h"
 
 #include <QUrl>
 #include <QBuffer>
@@ -75,20 +77,19 @@
 /*!
  * Constructor.
  */
-QVersitContactExporterPrivate::QVersitContactExporterPrivate() :
+QVersitContactExporterPrivate::QVersitContactExporterPrivate(const QString& profile) :
     mDetailHandler(NULL),
     mDetailHandler2(NULL),
     mDetailHandlerVersion(0),
     mDefaultResourceHandler(new QVersitDefaultResourceHandler),
-    mResourceHandler(mDefaultResourceHandler),
-    mVersitType(QVersitDocument::InvalidType)
+    mResourceHandler(mDefaultResourceHandler)
 {
     // Detail mappings
     int versitPropertyCount =
-        sizeof(versitContactDetailMappings)/sizeof(VersitContactDetailMapping);
+        sizeof(versitContactDetailMappings)/sizeof(VersitDetailMapping);
     for (int i=0; i < versitPropertyCount; i++) {
         mPropertyMappings.insert(
-                QLatin1String(versitContactDetailMappings[i].contactDetailDefinitionName),
+                QLatin1String(versitContactDetailMappings[i].detailDefinitionName),
                 QLatin1String(versitContactDetailMappings[i].versitPropertyName));
     }
 
@@ -107,6 +108,8 @@
                 QLatin1String(versitSubTypeMappings[i].contactString),
                 QLatin1String(versitSubTypeMappings[i].versitString));
     }
+
+    mPluginDetailHandlers = QVersitContactPluginLoader::instance()->createContactHandlers(profile);
 }
 
 /*!
@@ -126,15 +129,12 @@
     QVersitDocument& document,
     QVersitContactExporter::Error* error)
 {
-    mVersitType = document.type();
     QList<QContactDetail> allDetails = contact.details();
     if (allDetails.isEmpty()) {
         *error = QVersitContactExporter::EmptyContactError;
         return false;
     }
-    for (int i = 0; i < allDetails.size(); i++) {
-        QContactDetail detail = allDetails.at(i);
-
+    foreach (const QContactDetail& detail, allDetails) {
         // If the custom detail handler handles it, we don't have to.
         if (mDetailHandler
             && mDetailHandler->preProcessDetail(contact, detail, &document))
@@ -188,9 +188,15 @@
             encodeDisplayLabel(detail, document, &removedProperties, &generatedProperties, &processedFields);
         }
 
+        // run plugin handlers
+        foreach (QVersitContactExporterDetailHandlerV2* handler, mPluginDetailHandlers) {
+            handler->detailProcessed(contact, detail, document,
+                                     &processedFields, &removedProperties, &generatedProperties);
+        }
+        // run the v2 handler, if set
         if (mDetailHandler2 && mDetailHandlerVersion > 1) {
-            mDetailHandler2->detailProcessed(contact, detail, processedFields, document,
-                                             &removedProperties, &generatedProperties);
+            mDetailHandler2->detailProcessed(contact, detail, document,
+                                             &processedFields, &removedProperties, &generatedProperties);
         }
 
         foreach(const QVersitProperty& property, removedProperties) {
@@ -205,6 +211,11 @@
         }
     }
 
+    // run plugin handlers
+    foreach (QVersitContactExporterDetailHandlerV2* handler, mPluginDetailHandlers) {
+        handler->contactProcessed(contact, &document);
+    }
+    // run the v2 handler, if set
     if (mDetailHandler2 && mDetailHandlerVersion > 1) {
         mDetailHandler2->contactProcessed(contact, &document);
     }
@@ -261,7 +272,8 @@
 
     // Generate an FN field if none is already there
     // Don't override previously exported FN properties (eg. exported by a DisplayLabel detail)
-    QVersitProperty fnProperty = takeProperty(document, QLatin1String("FN"), removedProperties);
+    QVersitProperty fnProperty =
+        VersitUtils::takeProperty(document, QLatin1String("FN"), removedProperties);
     if (fnProperty.value().isEmpty()) {
         fnProperty.setName(QLatin1String("FN"));
         if (!contactName.customLabel().isEmpty()) {
@@ -630,7 +642,8 @@
     QSet<QString>* processedFields)
 {
     QContactNickname nicknameDetail = static_cast<QContactNickname>(detail);
-    QVersitProperty property = takeProperty(document, QLatin1String("X-NICKNAME"), removedProperties);
+    QVersitProperty property =
+        VersitUtils::takeProperty(document, QLatin1String("X-NICKNAME"), removedProperties);
     property.setName(QLatin1String("X-NICKNAME"));
     QStringList value(property.variantValue().toStringList());
     value.append(nicknameDetail.nickname());
@@ -651,7 +664,8 @@
     QSet<QString>* processedFields)
 {
     QContactTag tagDetail = static_cast<QContactTag>(detail);
-    QVersitProperty property = takeProperty(document, QLatin1String("CATEGORIES"), removedProperties);
+    QVersitProperty property =
+        VersitUtils::takeProperty(document, QLatin1String("CATEGORIES"), removedProperties);
     property.setName(QLatin1String("CATEGORIES"));
     QStringList value(property.variantValue().toStringList());
     value.append(tagDetail.tag());
@@ -745,7 +759,8 @@
     QSet<QString>* processedFields)
 {
     // Override any previous FN property
-    QVersitProperty property = takeProperty(document, QLatin1String("FN"), removedProperties);
+    QVersitProperty property =
+        VersitUtils::takeProperty(document, QLatin1String("FN"), removedProperties);
     property.setName(mPropertyMappings.value(detail.definitionName()));
     QContactDisplayLabel displayLabel = static_cast<QContactDisplayLabel>(detail);
     if (!displayLabel.label().isEmpty()) {
@@ -756,21 +771,6 @@
 }
 
 /*!
- * Finds a property in the \a document with the given \a propertyName, removes it and returns it.
- */
-QVersitProperty QVersitContactExporterPrivate::takeProperty(const QVersitDocument& document,
-                                                            const QString& propertyName,
-                                                            QList<QVersitProperty>* toBeRemoved) {
-    foreach (const QVersitProperty& currentProperty, document.properties()) {
-        if (currentProperty.name() == propertyName) {
-            *toBeRemoved << currentProperty;
-            return currentProperty;
-        }
-    }
-    return QVersitProperty();
-}
-
-/*!
  * Check if \a resourceIdentifier represents a valid remote resource
  */
 bool QVersitContactExporterPrivate::isValidRemoteUrl(
--- a/src/versit/qversitcontactexporter_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactexporter_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -56,7 +56,6 @@
 #include "qversitdocument.h"
 #include "qversitproperty.h"
 #include "qmobilityglobal.h"
-#include "qvcardbackuphandlers_p.h"
 
 #include <QHash>
 #include <QObject>
@@ -64,11 +63,12 @@
 QTM_BEGIN_NAMESPACE
 class QContact;
 class QContactDetail;
+class QVersitContactHandler;
 
 class Q_AUTOTEST_EXPORT QVersitContactExporterPrivate
 {
 public:
-    QVersitContactExporterPrivate();
+    QVersitContactExporterPrivate(const QString& profile = QString());
     ~QVersitContactExporterPrivate();
 
     bool exportContact(const QContact& contact, QVersitDocument& versitDocument,
@@ -168,8 +168,7 @@
             QList<QVersitProperty>* removedProperties,
             QList<QVersitProperty>* generatedProperties,
             QSet<QString>* processedFields);
-    QVersitProperty takeProperty(const QVersitDocument& document, const QString& propertyName,
-                                 QList<QVersitProperty>* toBeRemoved);
+
     bool isValidRemoteUrl(const QString& resourceIdentifier);
     void encodeParameters(QVersitProperty& property,
         const QStringList& contexts,
@@ -181,12 +180,12 @@
     QMap<int, QVersitContactExporter::Error> mErrors;
     QVersitContactExporterDetailHandler* mDetailHandler;
     QVersitContactExporterDetailHandlerV2* mDetailHandler2;
+    QList<QVersitContactHandler*> mPluginDetailHandlers;
     int mDetailHandlerVersion;
     QVersitDefaultResourceHandler* mDefaultResourceHandler;
     QVersitResourceHandler* mResourceHandler;
     QHash<QString,QString> mPropertyMappings;
     QHash<QString,QString> mParameterMappings;
-    QVersitDocument::VersitType mVersitType;
 };
 
 QTM_END_NAMESPACE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitcontacthandler.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qversitcontacthandler.h"
+
+QTM_USE_NAMESPACE
+
+Q_DEFINE_LATIN1_CONSTANT(QVersitContactHandlerFactory::ProfileSync, "Sync");
+Q_DEFINE_LATIN1_CONSTANT(QVersitContactHandlerFactory::ProfileBackup, "Backup");
+
+/*!
+  \class QVersitContactHandler
+  \brief The QVersitContactHandler class is a union of the
+  QVersitContactImporterPropertyHandlerV2 and QVersitContactExporterDetailHandlerV2 interfaces.
+  \ingroup versit-extension
+ */
+
+/*!
+  \class QVersitContactHandlerFactory
+  \brief The QVersitContactHandlerFactory class provides the interface for Versit plugins.
+  \ingroup versit-extension
+
+  This class provides a simple interface for the creation of QVersitContactHandler instances.
+  Implement this interface to write a Versit plugin.  For more details, see \l{Versit Plugins}.
+ */
+
+/*!
+   \variable QVersitContactHandlerFactory::ProfileSync
+
+   The constant string signifying a plugin that is relevant to import and export in a
+   synchronization context.
+   \sa QVersitContactHandlerFactory::profiles(), QVersitContactImporter(), QVersitContactExporter()
+ */
+
+/*!
+   \variable QVersitContactHandlerFactory::ProfileBackup
+
+   The constant string signifying a plugin that is relevant to import and export in a backup/restore
+   context.
+   \sa profiles(),
+   QVersitContactImporter::QVersitContactImporter(),
+   QVersitContactExporter::QVersitContactExporter()
+ */
+
+/*!
+  \fn QVersitContactHandlerFactory::~QVersitContactHandlerFactory()
+  This frees any memory used by the QVersitContactHandlerFactory.
+ */
+
+/*!
+  \fn QSet<QString> QVersitContactHandlerFactory::profiles() const
+  This function can be overridden to allow a plugin to report which profiles it is to be active
+  under.  If this (as in the default case) returns the empty set, it indicates that the plugin
+  should be loaded under all profiles.  If it returns a non-empty set, it will only be loaded for
+  those profiles that are specified by the importer/exporter class.
+ */
+
+/*!
+  \fn QString QVersitContactHandlerFactory::name() const
+  This function should return a unique string that identifies the handlers provided by this factory.
+  Typically, this will be of the form "com.nokia.qt.mobility.versit.samplehandler" with the
+  appropriate domain and handler name substituted.
+ */
+
+/*!
+  \fn int index() const
+  This function should return an index that helps with determining the order in which to run the
+  plugins.  Plugins are run in the following order:
+  \list
+  \o Positively-indexed, ascending
+  \o Zero-indexed
+  \o Negatively-indexed, ascending
+  \endlist
+  For example, plugins with an index of 1 are run first and plugins of index -1 are run last.
+  If more than one plugin share an index, the order of execution between them is undefined.
+
+  By default, this returns 0, which is recommended for plugins with no special ordering
+  requirements.
+ */
+
+/*!
+  \fn QVersitContactHandler* QVersitContactHandlerFactory::createHandler() const
+  This function is called by the Versit importer or exporter class to create an instance of the
+  handler provided by this factory.
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitcontacthandler.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVERSITCONTACTHANDLER_H
+#define QVERSITCONTACTHANDLER_H
+
+#include "qversitcontactimporter.h"
+#include "qversitcontactexporter.h"
+
+QTM_BEGIN_NAMESPACE
+
+// qdoc seems to not find QVersitContactHandler if it is declared first.. ugh
+class QVersitContactHandler;
+
+class Q_VERSIT_EXPORT QVersitContactHandlerFactory
+{
+public:
+    virtual ~QVersitContactHandlerFactory() {}
+    virtual QSet<QString> profiles() const { return QSet<QString>(); }
+    virtual QString name() const = 0;
+    virtual int index() const { return 0; }
+    virtual QVersitContactHandler* createHandler() const = 0;
+
+#ifdef Q_QDOC
+    static const QLatin1Constant ProfileSync;
+    static const QLatin1Constant ProfileBackup;
+#else
+    Q_DECLARE_LATIN1_CONSTANT(ProfileSync, "Sync");
+    Q_DECLARE_LATIN1_CONSTANT(ProfileBackup, "Backup");
+#endif
+};
+
+class Q_VERSIT_EXPORT QVersitContactHandler : public QVersitContactImporterPropertyHandlerV2,
+                                              public QVersitContactExporterDetailHandlerV2
+{
+public:
+    virtual ~QVersitContactHandler() {}
+};
+
+QTM_END_NAMESPACE
+
+#define QT_VERSIT_CONTACT_HANDLER_INTERFACE "com.nokia.qt.mobility.versit.contacthandlerfactory/1.0"
+Q_DECLARE_INTERFACE(QtMobility::QVersitContactHandlerFactory, QT_VERSIT_CONTACT_HANDLER_INTERFACE);
+
+#endif
--- a/src/versit/qversitcontactimporter.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactimporter.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -42,7 +42,6 @@
 #include "qcontactmanagerengine.h"
 #include "qversitcontactimporter.h"
 #include "qversitcontactimporter_p.h"
-#include "qvcardbackuphandlers_p.h"
 #include "qversitdocument.h"
 #include "qversitproperty.h"
 #include "qmobilityglobal.h"
@@ -57,8 +56,6 @@
 
   This interface is replaced by QVersitContactImporterPropertyHandlerV2.
 
-  \ingroup versit
-
   \sa QVersitContactImporter
  */
 
@@ -100,11 +97,11 @@
   \class QVersitContactImporterPropertyHandlerV2
   \brief The QVersitContactImporterPropertyHandlerV2 class is an interface for clients wishing to
   implement custom import behaviour for vCard properties.
+  \ingroup versit-extension
+  \inmodule QtVersit
 
   This interface supercedes QVersitContactImporterPropertyHandler.
 
-  \ingroup versit
-
   \sa QVersitContactImporter
  */
 
@@ -114,18 +111,20 @@
  */
 
 /*!
-  \fn void QVersitContactImporterPropertyHandlerV2::propertyProcessed(const QVersitDocument& document, const QVersitProperty& property, bool alreadyProcessed, const QContact& contact, QList<QContactDetail>* updatedDetails)
+  \fn void QVersitContactImporterPropertyHandlerV2::propertyProcessed(const QVersitDocument& document, const QVersitProperty& property, const QContact& contact, bool* alreadyProcessed, QList<QContactDetail>* updatedDetails)
   Process \a property and provide a list of updated details by adding them to \a updatedDetails.
 
   This function is called on every QVersitProperty encountered during an import, after the property
   has been processed by the QVersitContactImporter.  An implementation of this function can be made
   to provide support for vCard properties not supported by QVersitContactImporter.
 
-  The supplied \a document is the container for the \a property.  \a alreadyProcessed is true if the
-  QVersitContactImporter was successful in processing the property.  \a contact holds the state of
-  the contact before the property was processed by the importer.  \a updatedDetails is initially
-  filled with a list of details that the importer will update, and can be modified (by removing,
-  modifying or adding details to the list)
+  The supplied \a document is the container for the \a property.  \a alreadyProcessed is true if
+  the QVersitContactImporter or another handler was successful in processing the property.  If it is
+  false and the handler processes the property, it should be set to true to inform later handlers
+  that the property requires no further processing.  \a contact holds the state of the contact
+  before the property was processed by the importer.  \a updatedDetails is initially filled with a
+  list of details that the importer will update, and can be modified (by removing, modifying or
+  adding details to the list)
  */
 
 /*!
@@ -138,16 +137,12 @@
 */
 
 /*!
-  \fn int QVersitContactImporterPropertyHandlerV2::version() const
-  Returns the version of the handler.  Currently, always returns 2.
-*/
-
-/*!
   \class QVersitContactImporter
   \brief The QVersitContactImporter class converts \l{QVersitDocument}{QVersitDocuments} to
   \l{QContact}{QContacts}.
 
   \ingroup versit
+  \inmodule QtVersit
 
   This class is used to convert lists of \l{QVersitDocument}{QVersitDocuments} (which may be
   produced by a QVersitReader) to lists of \l{QContact}{QContacts} (which may be saved into a
@@ -155,6 +150,11 @@
   documents and QContacts.  The importer can be extended by clients by associating resource
   and property handlers.
 
+  Here is a simple example of how to use QVersitContactImporter:
+  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Import example
+
+  \section1 Extension via handlers
+
   A \l QVersitResourceHandler is associated with the importer to supply the behaviour for saving
   files to persistent storage.  By default, this is set to a \l QVersitDefaultResourceHandler,
   which does not save files to persistent storage.  Note that although photos found in vCards
@@ -164,12 +164,16 @@
 
   By associating a QVersitContactImporterPropertyHandlerV2 with the importer using
   setPropertyHandler(), the client can pass in a handler to override the processing of properties
-  and/or handle properties that QVersitContactImporter doesn't support.  A "backup" handler is
-  provided by QVersitContactImporterPropertyHandlerV2::createBackupHandler() which imports
-  properties generated by the corresponding backup handler for the QVersitContactExporter.
-
-  An example usage of QVersitContactImporter:
-  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Import example
+  and/or handle properties that QVersitContactImporter doesn't support.  Also, handlers can be
+  implicitly associated to an importer through the \l{Versit Plugins}{handler plugin mechanism}.
+  The importer can be constructed with a profile, which gives hints about what kind of handlers
+  should be added to it.  For example, the backup profile can be used to instruct the importer to
+  interpret properties that have been generated by a backup-profiled QVersitContactExporter.  To
+  illustrate, a backup importer can be constructed with:
+  \code
+  QVersitContactImporter importer(QVersitContactHandlerFactory::ProfileBackup);
+  \endcode
+  For more details on how the backup plugin works, see \l{Versit Plugins}
 
   \section1 Importing categories
   The importer imports the vCard CATEGORIES property by converting each category to a QContactTag.
@@ -193,27 +197,24 @@
   */
 
 
-/*!
-  Constructs and returns a property handler that restores data from a vCard generated using the
-  exporter backup detail handler (see QVersitContactExporterDetailHandlerV2::createBackupHandler()).
-  The caller is responsible for deleting the object.
-
-  Clients wishing to implement their own property handler and also benefit from the functionality of
-  the default handler can use this function to construct one, and wrap a custom
-  QVersitContactImporterPropertyHandlerV2 around it.  In the implementation of propertyProcessed and
-  documentProcessed, the respective functions in the backup handler should be called as the last
-  step (ensuring the arguments are correctly updated and passed through).
- */
-QVersitContactImporterPropertyHandlerV2* QVersitContactImporterPropertyHandlerV2::createBackupHandler() {
-    return new QVCardImporterBackupHandler;
-}
-
 /*! Constructs a new importer */
 QVersitContactImporter::QVersitContactImporter()
     : d(new QVersitContactImporterPrivate)
 {
 }
 
+/*!
+ * Constructs a new importer for the given \a profile.  The profile strings should be one of those
+ * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Versit
+ * Plugins}{Versit plugin}.
+ *
+ * The profile determines which plugins will be loaded to supplement the importer.
+ */
+QVersitContactImporter::QVersitContactImporter(const QString& profile)
+    : d(new QVersitContactImporterPrivate(profile))
+{
+}
+
 /*! Frees the memory used by the importer */
 QVersitContactImporter::~QVersitContactImporter()
 {
@@ -302,8 +303,7 @@
  */
 void QVersitContactImporter::setPropertyHandler(QVersitContactImporterPropertyHandlerV2* handler)
 {
-    if (handler)
-        d->mPropertyHandlerVersion = handler->version();
+    d->mPropertyHandlerVersion = 2;
     d->mPropertyHandler = 0;
     d->mPropertyHandler2 = handler;
 }
--- a/src/versit/qversitcontactimporter.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactimporter.h	Mon Oct 04 01:37:06 2010 +0300
@@ -73,16 +73,14 @@
 class Q_VERSIT_EXPORT QVersitContactImporterPropertyHandlerV2
 {
 public:
-    static QVersitContactImporterPropertyHandlerV2* createBackupHandler();
     virtual ~QVersitContactImporterPropertyHandlerV2() {}
     virtual void propertyProcessed(const QVersitDocument& document,
                                    const QVersitProperty& property,
-                                   bool alreadyProcessed,
                                    const QContact& contact,
+                                   bool *alreadyProcessed,
                                    QList<QContactDetail>* updatedDetails) = 0;
     virtual void documentProcessed(const QVersitDocument& document,
                                    QContact* contact) = 0;
-    virtual int version() const { return 2; }
 };
 
 class Q_VERSIT_EXPORT QVersitContactImporter
@@ -95,6 +93,7 @@
     };
 
     QVersitContactImporter();
+    QVersitContactImporter(const QString& profile);
     ~QVersitContactImporter();
 
     bool importDocuments(const QList<QVersitDocument>& documents);
@@ -106,11 +105,8 @@
     void setResourceHandler(QVersitResourceHandler* handler);
     QVersitResourceHandler* resourceHandler() const;
 
-    // Deprecated:
-
-    QList<QContact> Q_DECL_DEPRECATED importContacts(const QList<QVersitDocument>& documents);
+    /* deprecated and internal */
     void Q_DECL_DEPRECATED setPropertyHandler(QVersitContactImporterPropertyHandler* handler);
-    /* deprecated and internal */
     Q_DECL_DEPRECATED QVersitContactImporterPropertyHandler* propertyHandler() const;
 
 private:
--- a/src/versit/qversitcontactimporter_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactimporter_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -39,11 +39,12 @@
 **
 ****************************************************************************/
 
-#include "qversitdefs_p.h"
+#include "qversitcontactsdefs_p.h"
 #include "qversitcontactimporter_p.h"
 #include "qversitdocument.h"
 #include "qversitproperty.h"
 #include "qmobilityglobal.h"
+#include "qmobilitypluginsearch.h"
 
 #include <qcontactmanagerengine.h>
 #include <qcontact.h>
@@ -68,6 +69,8 @@
 #include <qcontactdisplaylabel.h>
 #include <qcontactthumbnail.h>
 #include <qcontactringtone.h>
+#include "qversitcontacthandler.h"
+#include "qversitcontactpluginloader_p.h"
 
 #include <QHash>
 #include <QFile>
@@ -77,7 +80,7 @@
 /*!
  * Constructor.
  */
-QVersitContactImporterPrivate::QVersitContactImporterPrivate() :
+QVersitContactImporterPrivate::QVersitContactImporterPrivate(const QString& profile) :
     mPropertyHandler(NULL),
     mPropertyHandler2(NULL),
     mPropertyHandlerVersion(0),
@@ -86,15 +89,15 @@
 {
     // Contact detail mappings
     int versitPropertyCount =
-        sizeof(versitContactDetailMappings)/sizeof(VersitContactDetailMapping);
+        sizeof(versitContactDetailMappings)/sizeof(VersitDetailMapping);
     for (int i=0; i < versitPropertyCount; i++) {
         QString versitPropertyName =
             QLatin1String(versitContactDetailMappings[i].versitPropertyName);
         QPair<QString,QString> contactDetail;
         contactDetail.first =
-            QLatin1String(versitContactDetailMappings[i].contactDetailDefinitionName);
+            QLatin1String(versitContactDetailMappings[i].detailDefinitionName);
         contactDetail.second =
-            QLatin1String(versitContactDetailMappings[i].contactDetailValueKey);
+            QLatin1String(versitContactDetailMappings[i].detailFieldName);
         mDetailMappings.insert(versitPropertyName,contactDetail);
     }
 
@@ -113,6 +116,8 @@
             QLatin1String(versitSubTypeMappings[i].versitString),
             QLatin1String(versitSubTypeMappings[i].contactString));
     }
+
+    mPluginPropertyHandlers = QVersitContactPluginLoader::instance()->createContactHandlers(profile);
 }
 
 /*!
@@ -121,6 +126,9 @@
 QVersitContactImporterPrivate::~QVersitContactImporterPrivate()
 {
     delete mDefaultResourceHandler;
+    foreach (QVersitContactHandler* pluginHandler, mPluginPropertyHandlers) {
+        delete pluginHandler;
+    }
 }
 
 /*!
@@ -157,6 +165,11 @@
     contact->setType(QContactType::TypeContact);
     QContactManagerEngine::setContactDisplayLabel(contact, QVersitContactImporterPrivate::synthesizedDisplayLabel(*contact));
 
+    // run plugin handlers
+    foreach (QVersitContactImporterPropertyHandlerV2* handler, mPluginPropertyHandlers) {
+        handler->documentProcessed(document, contact);
+    }
+    // run the v2 handler, if set
     if (mPropertyHandler2 && mPropertyHandlerVersion > 1) {
         mPropertyHandler2->documentProcessed(document, contact);
     }
@@ -217,14 +230,20 @@
         success = createNameValueDetail(property, contact, &updatedDetails);
     }
 
+    // run plugin handlers
+    foreach (QVersitContactImporterPropertyHandlerV2* handler, mPluginPropertyHandlers) {
+        handler->propertyProcessed(document, property, *contact, &success, &updatedDetails);
+    }
+    // run the v2 handler, if set
     if (mPropertyHandler2 && mPropertyHandlerVersion > 1) {
-        mPropertyHandler2->propertyProcessed(document, property, success, *contact, &updatedDetails);
+        mPropertyHandler2->propertyProcessed(document, property, *contact, &success, &updatedDetails);
     }
 
     foreach (QContactDetail detail, updatedDetails) {
         contact->saveDetail(&detail);
     }
 
+    // run the v1 handler, if set
     if (mPropertyHandler && mPropertyHandlerVersion == 1)
         mPropertyHandler->postProcessProperty(document, property, success, contactIndex, contact);
 }
--- a/src/versit/qversitcontactimporter_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitcontactimporter_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -55,7 +55,6 @@
 
 #include "qmobilityglobal.h"
 #include "qversitcontactimporter.h"
-#include "qvcardbackuphandlers_p.h"
 
 #include <QList>
 #include <QDateTime>
@@ -69,16 +68,16 @@
 class QContactOrganization;
 class QVersitProperty;
 class QVersitDocument;
+class QVersitContactHandler;
 
 class Q_AUTOTEST_EXPORT QVersitContactImporterPrivate
 {
 public:
-    QVersitContactImporterPrivate();
+    QVersitContactImporterPrivate(const QString& profile = QString());
     ~QVersitContactImporterPrivate();
 
     bool importContact(const QVersitDocument& versitDocument, int contactIndex,
                        QContact* contact, QVersitContactImporter::Error* error);
-    QList<QVersitProperty> unconvertedVersitProperties();
 
     static QString synthesizedDisplayLabel(const QContact& contact);
 
@@ -115,6 +114,7 @@
     QMap<int, QVersitContactImporter::Error> mErrors;
     QVersitContactImporterPropertyHandler* mPropertyHandler;
     QVersitContactImporterPropertyHandlerV2* mPropertyHandler2;
+    QList<QVersitContactHandler*> mPluginPropertyHandlers;
     int mPropertyHandlerVersion;
     QVersitDefaultResourceHandler* mDefaultResourceHandler;
     QVersitResourceHandler* mResourceHandler;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitcontactpluginloader_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QPluginLoader>
+
+#include "qversitcontactpluginloader_p.h"
+#include "qmobilitypluginsearch.h"
+
+QTM_USE_NAMESPACE
+
+/*!
+   A less-than function for factory indices (see QVersitContactHandlerFactory::index()).
+   Positive values come first (ascendingly), then zero, then negative values (ascendingly).
+ */
+bool factoryLessThan(QVersitContactHandlerFactory* a, QVersitContactHandlerFactory* b) {
+    if ((a->index() > 0 && b->index() > 0)
+            || (a->index() < 0 && b->index() < 0))
+        // same sign
+        return a->index() < b->index();
+    else
+        // a is zero
+        // or b is zero
+        // or opposite sign
+        return b->index() < a->index();
+}
+
+QVersitContactPluginLoader* QVersitContactPluginLoader::mInstance = NULL;
+
+/*!
+ * \class QVersitContactPluginLoader
+ * This is a singleton class that loads Versit plugins for contacts processing
+ */
+
+QVersitContactPluginLoader::QVersitContactPluginLoader()
+{
+}
+
+/*!
+ * Returns the singleton instance of the QVersitContactPluginLoader.
+ */
+QVersitContactPluginLoader* QVersitContactPluginLoader::instance()
+{
+    if (!mInstance)
+        mInstance = new QVersitContactPluginLoader;
+    return mInstance;
+}
+
+void QVersitContactPluginLoader::loadPlugins() {
+    QStringList plugins = mobilityPlugins(QLatin1String("versit"));
+    if (plugins != mPluginPaths) {
+        mPluginPaths = plugins;
+
+        foreach (const QString& pluginPath, mPluginPaths) {
+            QPluginLoader qpl(pluginPath);
+            QObject* plugin = qpl.instance();
+            QVersitContactHandlerFactory* contactPlugin =
+                qobject_cast<QVersitContactHandlerFactory*>(plugin);
+            if (contactPlugin && !mLoadedFactories.contains(contactPlugin->name())) {
+                mLoadedFactories.insert(contactPlugin->name());
+                mContactHandlerFactories.append(contactPlugin);
+            }
+        }
+        qSort(mContactHandlerFactories.begin(), mContactHandlerFactories.end(), factoryLessThan);
+    }
+}
+
+/*!
+ * Creates and returns handlers from the plugin.  If \a profile is the empty string, only handlers
+ * with an empty profile list are returned.  If \a profile is nonempty, only handlers with either
+ * an empty profile list or a profile list that contains the given \a profile are returned.
+ *
+ * The caller is responsible for deleting all returned handlers.
+ */
+QList<QVersitContactHandler*> QVersitContactPluginLoader::createContactHandlers(const QString& profile)
+{
+    loadPlugins();
+
+    QList<QVersitContactHandler*> handlers;
+    foreach (const QVersitContactHandlerFactory* factory, mContactHandlerFactories) {
+        if (factory->profiles().isEmpty() ||
+                (!profile.isEmpty() && factory->profiles().contains(profile))) {
+            QVersitContactHandler* handler = factory->createHandler();
+            handlers.append(handler);
+        }
+    }
+    return handlers;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitcontactpluginloader_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVERSITCONTACTPLUGINLOADER_P_H
+#define QVERSITCONTACTPLUGINLOADER_P_H
+
+#include <QMap>
+#include <QStringList>
+#include <QList>
+
+#include "qmobilityglobal.h"
+#include "qversitcontacthandler.h"
+
+QTM_BEGIN_NAMESPACE
+
+class QVersitContactPluginLoader
+{
+    private:
+        QVersitContactPluginLoader();
+
+    public:
+        static QVersitContactPluginLoader* instance();
+        QList<QVersitContactHandler*> createContactHandlers(const QString& profile);
+
+    private:
+        void loadPlugins();
+
+        static QVersitContactPluginLoader* mInstance;
+        QSet<QString> mLoadedFactories;
+        QList<QVersitContactHandlerFactory*> mContactHandlerFactories;
+        QStringList mPluginPaths;
+};
+
+QTM_END_NAMESPACE
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitcontactsdefs_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QVERSITCONTACTSDEFS_P_H
+#define QVERSITCONTACTSDEFS_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtcontacts.h"
+#include "qversitdefs_p.h"
+
+QTM_BEGIN_NAMESPACE
+
+//! [Property name mappings]
+// Mappings from versit property names to Qt contact details
+const VersitDetailMapping versitContactDetailMappings[] = {
+    {"ADR",           QContactAddress::DefinitionName.latin1(),
+                      ""},
+    {"BDAY",          QContactBirthday::DefinitionName.latin1(),
+                      QContactBirthday::FieldBirthday.latin1()},
+    {"CATEGORIES",    QContactTag::DefinitionName.latin1(),
+                      QContactTag::FieldTag.latin1()},
+    {"FN",            QContactDisplayLabel::DefinitionName.latin1(),
+                      ""},
+    {"GEO",           QContactGeoLocation::DefinitionName.latin1(),
+                      ""},
+    {"EMAIL",         QContactEmailAddress::DefinitionName.latin1(),
+                      QContactEmailAddress::FieldEmailAddress.latin1()},
+    {"IMPP",          QContactOnlineAccount::DefinitionName.latin1(),
+                      QContactOnlineAccount::SubTypeImpp.latin1()},
+    {"LOGO",          QContactOrganization::DefinitionName.latin1(),
+                      QContactOrganization::FieldLogoUrl.latin1()},
+    {"N",             QContactName::DefinitionName.latin1(),
+                      ""},
+    {"NICKNAME",      QContactNickname::DefinitionName.latin1(),
+                      QContactNickname::FieldNickname.latin1()},
+    {"NOTE",          QContactNote::DefinitionName.latin1(),
+                      QContactNote::FieldNote.latin1()},
+    {"ORG",           QContactOrganization::DefinitionName.latin1(),
+                      QContactOrganization::FieldName.latin1()},
+    {"PHOTO",         QContactThumbnail::DefinitionName.latin1(),
+                      ""},
+    {"REV",           QContactTimestamp::DefinitionName.latin1(),
+                      ""},
+    {"ROLE",          QContactOrganization::DefinitionName.latin1(),
+                      QContactOrganization::FieldRole.latin1()},
+    {"SOUND",         QContactRingtone::DefinitionName.latin1(),
+                      QContactRingtone::FieldAudioRingtoneUrl.latin1()},
+    {"TEL",           QContactPhoneNumber::DefinitionName.latin1(),
+                      QContactPhoneNumber::FieldNumber.latin1()},
+    {"TITLE",         QContactOrganization::DefinitionName.latin1(),
+                      QContactOrganization::FieldTitle.latin1()},
+    {"UID",           QContactGuid::DefinitionName.latin1(),
+                      QContactGuid::FieldGuid.latin1()},
+    {"URL",           QContactUrl::DefinitionName.latin1(),
+                      QContactUrl::FieldUrl.latin1()},
+    {"X-ANNIVERSARY", QContactAnniversary::DefinitionName.latin1(),
+                      ""},
+    {"X-ASSISTANT",   QContactOrganization::DefinitionName.latin1(),
+                      QContactOrganization::FieldAssistantName.latin1()},
+    {"X-ASSISTANT-TEL", QContactPhoneNumber::DefinitionName.latin1(),
+                      QContactPhoneNumber::SubTypeAssistant.latin1()},
+    {"X-CHILDREN",    QContactFamily::DefinitionName.latin1(),
+                      QContactFamily::FieldChildren.latin1()},
+    {"X-EPOCSECONDNAME",QContactNickname::DefinitionName.latin1(),
+                      QContactNickname::FieldNickname.latin1()},
+    {"X-GENDER",      QContactGender::DefinitionName.latin1(),
+                      QContactGender::FieldGender.latin1()},
+    {"X-IMPP",        QContactOnlineAccount::DefinitionName.latin1(),
+                      QContactOnlineAccount::SubTypeImpp.latin1()},
+    {"X-JABBER",      QContactOnlineAccount::DefinitionName.latin1(),
+                      QContactOnlineAccount::SubTypeImpp.latin1()},
+    {"X-NICKNAME",    QContactNickname::DefinitionName.latin1(),
+                      QContactNickname::FieldNickname.latin1()},
+    {"X-SIP",         QContactOnlineAccount::DefinitionName.latin1(),
+                      ""},
+    {"X-SPOUSE",      QContactFamily::DefinitionName.latin1(),
+                      QContactFamily::FieldSpouse.latin1()}
+};
+//! [Property name mappings]
+
+// Mappings from versit TYPE parameters to Qt contact detail contexts
+const VersitMapping versitContextMappings[] = {
+    {"HOME", QContactDetail::ContextHome.latin1()},
+    {"WORK", QContactDetail::ContextWork.latin1()},
+};
+
+//! [Property type parameter mappings]
+// Mappings from versit TYPE parameters to Qt contact detail subtypes
+const VersitMapping versitSubTypeMappings[] = {
+    {"DOM",    QContactAddress::SubTypeDomestic.latin1()},
+    {"INTL",   QContactAddress::SubTypeInternational.latin1()},
+    {"POSTAL", QContactAddress::SubTypePostal.latin1()},
+    {"PARCEL", QContactAddress::SubTypeParcel.latin1()},
+    {"VOICE",  QContactPhoneNumber::SubTypeVoice.latin1()},
+    {"CELL",   QContactPhoneNumber::SubTypeMobile.latin1()},
+    {"MODEM",  QContactPhoneNumber::SubTypeModem.latin1()},
+    {"CAR",    QContactPhoneNumber::SubTypeCar.latin1()},
+    {"VIDEO",  QContactPhoneNumber::SubTypeVideo.latin1()},
+    {"FAX",    QContactPhoneNumber::SubTypeFax.latin1()},
+    {"BBS",    QContactPhoneNumber::SubTypeBulletinBoardSystem.latin1()},
+    {"PAGER",  QContactPhoneNumber::SubTypePager.latin1()},
+    {"SWIS",   QContactOnlineAccount::SubTypeVideoShare.latin1()},
+    {"VOIP",   QContactOnlineAccount::SubTypeSipVoip.latin1()}
+};
+//! [Property type parameter mappings]
+
+QTM_END_NAMESPACE
+
+#endif // QVERSITCONTACTSDEFS_P_H
--- a/src/versit/qversitdefs_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdefs_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -56,138 +56,21 @@
 
 #include "qmobilityglobal.h"
 
-#include <qcontactdetail.h>
-#include <qcontactname.h>
-#include <qcontactemailaddress.h>
-#include <qcontactphonenumber.h>
-#include "qcontactaddress.h"
-#include <qcontacturl.h>
-#include <qcontactguid.h>
-#include <qcontactorganization.h>
-#include <qcontacttimestamp.h>
-#include <qcontactbirthday.h>
-#include <qcontactnote.h>
-#include <qcontactgeolocation.h>
-#include <qcontactavatar.h>
-#include <qcontactgender.h>
-#include <qcontactnickname.h>
-#include <qcontactanniversary.h>
-#include <qcontactonlineaccount.h>
-#include <qcontactfamily.h>
-#include <qcontactdisplaylabel.h>
-#include <qcontacttag.h>
-#include <qcontactringtone.h>
-#include <qcontactthumbnail.h>
-
 QTM_BEGIN_NAMESPACE
 
-// Mapping between a string in versit specifications and Qt contact details
-struct VersitContactDetailMapping {
-    const char* versitPropertyName;
-    const char* contactDetailDefinitionName;
-    const char* contactDetailValueKey;
-};
-
-//! [Property name mappings]
-// Mappings from versit property names to Qt contact details
-const VersitContactDetailMapping versitContactDetailMappings[] = {
-    {"ADR",           QContactAddress::DefinitionName.latin1(),
-                      ""},
-    {"BDAY",          QContactBirthday::DefinitionName.latin1(),
-                      QContactBirthday::FieldBirthday.latin1()},
-    {"CATEGORIES",    QContactTag::DefinitionName.latin1(),
-                      QContactTag::FieldTag.latin1()},
-    {"FN",            QContactDisplayLabel::DefinitionName.latin1(),
-                      ""},
-    {"GEO",           QContactGeoLocation::DefinitionName.latin1(),
-                      ""},
-    {"EMAIL",         QContactEmailAddress::DefinitionName.latin1(),
-                      QContactEmailAddress::FieldEmailAddress.latin1()},
-    {"IMPP",          QContactOnlineAccount::DefinitionName.latin1(),
-                      QContactOnlineAccount::SubTypeImpp.latin1()},
-    {"LOGO",          QContactOrganization::DefinitionName.latin1(),
-                      QContactOrganization::FieldLogoUrl.latin1()},
-    {"N",             QContactName::DefinitionName.latin1(),
-                      ""},
-    {"NICKNAME",      QContactNickname::DefinitionName.latin1(),
-                      QContactNickname::FieldNickname.latin1()},
-    {"NOTE",          QContactNote::DefinitionName.latin1(),
-                      QContactNote::FieldNote.latin1()},
-    {"ORG",           QContactOrganization::DefinitionName.latin1(),
-                      QContactOrganization::FieldName.latin1()},
-    {"PHOTO",         QContactThumbnail::DefinitionName.latin1(),
-                      ""},
-    {"REV",           QContactTimestamp::DefinitionName.latin1(),
-                      ""},
-    {"ROLE",          QContactOrganization::DefinitionName.latin1(),
-                      QContactOrganization::FieldRole.latin1()},
-    {"SOUND",         QContactRingtone::DefinitionName.latin1(),
-                      QContactRingtone::FieldAudioRingtoneUrl.latin1()},
-    {"TEL",           QContactPhoneNumber::DefinitionName.latin1(),
-                      QContactPhoneNumber::FieldNumber.latin1()},
-    {"TITLE",         QContactOrganization::DefinitionName.latin1(),
-                      QContactOrganization::FieldTitle.latin1()},
-    {"UID",           QContactGuid::DefinitionName.latin1(),
-                      QContactGuid::FieldGuid.latin1()},
-    {"URL",           QContactUrl::DefinitionName.latin1(),
-                      QContactUrl::FieldUrl.latin1()},
-    {"X-ANNIVERSARY", QContactAnniversary::DefinitionName.latin1(),
-                      ""},
-    {"X-ASSISTANT",   QContactOrganization::DefinitionName.latin1(),
-                      QContactOrganization::FieldAssistantName.latin1()},
-    {"X-ASSISTANT-TEL", QContactPhoneNumber::DefinitionName.latin1(),
-                      QContactPhoneNumber::SubTypeAssistant.latin1()},
-    {"X-CHILDREN",    QContactFamily::DefinitionName.latin1(),
-                      QContactFamily::FieldChildren.latin1()},
-    {"X-EPOCSECONDNAME",QContactNickname::DefinitionName.latin1(),
-                      QContactNickname::FieldNickname.latin1()},
-    {"X-GENDER",      QContactGender::DefinitionName.latin1(),
-                      QContactGender::FieldGender.latin1()},
-    {"X-IMPP",        QContactOnlineAccount::DefinitionName.latin1(),
-                      QContactOnlineAccount::SubTypeImpp.latin1()},
-    {"X-JABBER",      QContactOnlineAccount::DefinitionName.latin1(),
-                      QContactOnlineAccount::SubTypeImpp.latin1()},
-    {"X-NICKNAME",    QContactNickname::DefinitionName.latin1(),
-                      QContactNickname::FieldNickname.latin1()},
-    {"X-SIP",         QContactOnlineAccount::DefinitionName.latin1(),
-                      ""},
-    {"X-SPOUSE",      QContactFamily::DefinitionName.latin1(),
-                      QContactFamily::FieldSpouse.latin1()}
-};
-//! [Property name mappings]
-
 // Mapping between a string in versit specifications and Qt contacts
 struct VersitMapping {
     const char* versitString;
     const char* contactString;
 };
 
-// Mappings from versit TYPE parameters to Qt contact detail contexts
-const VersitMapping versitContextMappings[] = {
-    {"HOME", QContactDetail::ContextHome.latin1()},
-    {"WORK", QContactDetail::ContextWork.latin1()},
+// Mapping between a string in versit specifications and Qt contact details
+struct VersitDetailMapping {
+    const char* versitPropertyName;
+    const char* detailDefinitionName;
+    const char* detailFieldName;
 };
 
-//! [Property type parameter mappings]
-// Mappings from versit TYPE parameters to Qt contact detail subtypes
-const VersitMapping versitSubTypeMappings[] = {
-    {"DOM",    QContactAddress::SubTypeDomestic.latin1()},
-    {"INTL",   QContactAddress::SubTypeInternational.latin1()},
-    {"POSTAL", QContactAddress::SubTypePostal.latin1()},
-    {"PARCEL", QContactAddress::SubTypeParcel.latin1()},
-    {"VOICE",  QContactPhoneNumber::SubTypeVoice.latin1()},
-    {"CELL",   QContactPhoneNumber::SubTypeMobile.latin1()},
-    {"MODEM",  QContactPhoneNumber::SubTypeModem.latin1()},
-    {"CAR",    QContactPhoneNumber::SubTypeCar.latin1()},
-    {"VIDEO",  QContactPhoneNumber::SubTypeVideo.latin1()},
-    {"FAX",    QContactPhoneNumber::SubTypeFax.latin1()},
-    {"BBS",    QContactPhoneNumber::SubTypeBulletinBoardSystem.latin1()},
-    {"PAGER",  QContactPhoneNumber::SubTypePager.latin1()},
-    {"SWIS",   QContactOnlineAccount::SubTypeVideoShare.latin1()},
-    {"VOIP",   QContactOnlineAccount::SubTypeSipVoip.latin1()}
-};
-//! [Property type parameter mappings]
-
 //! [File extension mappings]
 // Mappings from mime types to file extensions
 const VersitMapping versitFileExtensionMappings[] = {
--- a/src/versit/qversitdocument.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdocument.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -51,6 +51,7 @@
   \class QVersitDocument
   \brief The QVersitDocument class is a container for a list of versit properties.
   \ingroup versit
+  \inmodule QtVersit
 
   A vCard is represented in abstract form as a QVersitDocument that consists of a number of
   properties such as a name (N), a telephone number (TEL) and an email address (EMAIL), for
@@ -58,9 +59,31 @@
   QVersitDocument.
 
   In addition to the list of properties, QVersitDocument also records the type of the Versit
-  document via the VersitType field.  This enum describes the format in which the document is to be
+  document in two ways.  The VersitType enum describes the format in which the document is to be
   serialized by QVersitWriter (or the format from which it was read by QVersitReader), and should
-  not be used to infer any semantics about the document data.
+  not be used to infer any semantics about the document data.  The componentType field is a string
+  corresponding directly to the value of the BEGIN line in a document.  For example, for a vCard,
+  this will always be the string "VCARD"; for an iCalendar, it could be "VCALENDAR", "VEVENT",
+  "VTODO", "VJOURNAL", "VALARM" or "VTIMEZONE".
+
+  As well as properties, a QVersitDocument can hold other documents.  For iCalendar, this is how
+  a single VCALENDAR document can compose documents of type VEVENT, VTODO, etc.
+
+  For example, for the following iCalendar:
+  \code
+  BEGIN:VCALENDAR
+  VERSION:2.0
+  BEGIN:VEVENT
+  SUMMARY:Christmas
+  DTSTART:20001225
+  END:VEVENT
+  END:VCALENDAR
+  \endcode
+
+  This can be represented as a QVersitDocument of with componentType VCALENDAR and versitType
+  ICalendar20Type.  It contains no properties (note: the VERSION property is not stored explicitly
+  as a property) and one sub-document.  The sub-document has componentType VEVENT and versitType
+  ICalendar20Type, and contains two properties.
 
   QVersitDocument supports implicit sharing.
 
@@ -69,10 +92,12 @@
 
 /*!
   \enum QVersitDocument::VersitType
-  This enum describes a versit document type and version.
+  This enum describes a Versit document serialization format and version.
   \value InvalidType No type specified or a document with an invalid type was parsed
   \value VCard21Type vCard version 2.1
   \value VCard30Type vCard version 3.0
+  \value VCard40Type vCard version 4.0
+  \value ICalendar20Type iCalendar version 2.0
  */
 
 /*! Constructs a new empty document */
@@ -109,7 +134,9 @@
 bool QVersitDocument::operator==(const QVersitDocument& other) const
 {
     return d->mVersitType == other.d->mVersitType &&
-            d->mProperties == other.d->mProperties;
+            d->mProperties == other.d->mProperties &&
+            d->mSubDocuments == other.d->mSubDocuments &&
+            d->mComponentType == other.d->mComponentType;
 }
 
 /*! Returns true if this is not equal to \a other; false otherwise. */
@@ -122,25 +149,33 @@
 uint qHash(const QVersitDocument &key)
 {
     int hash = QT_PREPEND_NAMESPACE(qHash)(key.type());
+    hash += QT_PREPEND_NAMESPACE(qHash)(key.componentType());
     foreach (const QVersitProperty& property, key.properties()) {
         hash += qHash(property);
     }
+    foreach (const QVersitDocument& nested, key.subDocuments()) {
+        hash += qHash(nested);
+    }
     return hash;
 }
 
 #ifndef QT_NO_DEBUG_STREAM
 QDebug operator<<(QDebug dbg, const QVersitDocument& document)
 {
-    dbg.nospace() << "QVersitDocument(" << document.type() << ')';
+    dbg.nospace() << "QVersitDocument(" << document.type() << ", " << document.componentType() << ')';
     foreach (const QVersitProperty& property, document.properties()) {
         dbg.space() << '\n' << property;
     }
+    foreach (const QVersitDocument& nested, document.subDocuments()) {
+        dbg.space() << '\n' << nested;
+    }
     return dbg.maybeSpace();
 }
 #endif
 
 /*!
- * Sets the versit document type to \a type.
+ * Sets the versit document type to \a type.  This determines the format in which the document is
+ * to be serialized.
  */
 void QVersitDocument::setType(VersitType type)
 {
@@ -156,6 +191,22 @@
 }
 
 /*!
+ * Sets the versit component type to \a componentType (eg. VCARD, VCALENDAR, VEVENT, etc.)
+ */
+void QVersitDocument::setComponentType(QString componentType)
+{
+    d->mComponentType = componentType;
+}
+
+/*!
+ * Gets the versit component type
+ */
+QString QVersitDocument::componentType() const
+{
+    return d->mComponentType;
+}
+
+/*!
  * Add \a property to the list of contained versit properties.
  * The property is appended as the last property of the list.
  */
@@ -191,10 +242,35 @@
 void QVersitDocument::clear()
 {
     d->mProperties.clear();
+    d->mSubDocuments.clear();
     d->mVersitType = QVersitDocument::InvalidType;
 }
 
 /*!
+ * Adds \a subdocument to the Versit document.
+ */
+void QVersitDocument::addSubDocument(const QVersitDocument& subdocument)
+{
+    d->mSubDocuments.append(subdocument);
+}
+
+/*!
+ * Sets the list of subdocuments to \a documents.
+ */
+void QVersitDocument::setSubDocuments(const QList<QVersitDocument>& documents)
+{
+    d->mSubDocuments = documents;
+}
+
+/*!
+ * Returns the list of subdocuments contained within this Versit document.
+ */
+QList<QVersitDocument> QVersitDocument::subDocuments() const
+{
+    return d->mSubDocuments;
+}
+
+/*!
  * Gets the list of the contained versit properties.
  * Note that the actual properties cannot be modified using the copy.
  */
@@ -208,7 +284,9 @@
  */
 bool QVersitDocument::isEmpty() const
 {
-    return d->mProperties.count() == 0 && d->mVersitType == QVersitDocument::InvalidType;
+    return d->mProperties.isEmpty()
+        && d->mSubDocuments.isEmpty()
+        && d->mVersitType == QVersitDocument::InvalidType;
 }
 
 QTM_END_NAMESPACE
--- a/src/versit/qversitdocument.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdocument.h	Mon Oct 04 01:37:06 2010 +0300
@@ -63,8 +63,10 @@
 public:
     enum VersitType {
         InvalidType,
-        VCard21Type,   // vCard version 2.1
-        VCard30Type    // vCard version 3.0 (RFC 2426)
+        VCard21Type,    // vCard version 2.1
+        VCard30Type,    // vCard version 3.0 (RFC 2426)
+        ICalendar20Type,// iCalendar version 2.0 (RFC 2445)
+        VCard40Type,    // vCard version 4.0
     };
 
     QVersitDocument();
@@ -76,15 +78,25 @@
     bool operator==(const QVersitDocument& other) const;
     bool operator!=(const QVersitDocument& other) const;
 
-    // metadata about the versit document itself.
+    // Metadata about the versit document
+    // The type determines the format for serialization
     void setType(VersitType type);
     VersitType type() const;
 
+    // The componentType is the value of the BEGIN property
+    void setComponentType(QString componentType);
+    QString componentType() const;
+
+    // The content
     void addProperty(const QVersitProperty& property);
     void removeProperty(const QVersitProperty& property);
     void removeProperties(const QString& name);
     QList<QVersitProperty> properties() const;
 
+    void addSubDocument(const QVersitDocument& subdocument);
+    void setSubDocuments(const QList<QVersitDocument>& documents);
+    QList<QVersitDocument> subDocuments() const;
+
     bool isEmpty() const;
     void clear();
 
--- a/src/versit/qversitdocument_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdocument_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -52,6 +52,8 @@
 QVersitDocumentPrivate::QVersitDocumentPrivate(const QVersitDocumentPrivate& other)
     : QSharedData(other),
     mVersitType(other.mVersitType),
-    mProperties(other.mProperties)
+    mComponentType(other.mComponentType),
+    mProperties(other.mProperties),
+    mSubDocuments(other.mSubDocuments)
 {
 }
--- a/src/versit/qversitdocument_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdocument_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -78,7 +78,9 @@
     }
 
     QVersitDocument::VersitType mVersitType;
+    QString mComponentType;
     QList<QVersitProperty> mProperties;
+    QList<QVersitDocument> mSubDocuments;
 };
 
 QTM_END_NAMESPACE
--- a/src/versit/qversitdocumentwriter_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdocumentwriter_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -60,11 +60,8 @@
  * \a version is the version of the Versit format, as printed on the VERSION line of output.
  * eg. "2.1"
  */
-QVersitDocumentWriter::QVersitDocumentWriter(
-    const QByteArray& documentType,
-    const QByteArray& version)
-    : mDocumentType(documentType),
-    mVersion(version),
+QVersitDocumentWriter::QVersitDocumentWriter()
+    : mDevice(0),
     mCodec(0),
     mEncoder(0),
     mUtf8Encoder(QTextCodec::codecForName("UTF-8")->makeEncoder()),
@@ -106,21 +103,47 @@
 }
 
 /*!
-* Encodes the \a document and writes it to the device
-*/
-void QVersitDocumentWriter::encodeVersitDocument(const QVersitDocument& document)
+ * Encodes the \a document and writes it to the device.  A "VERSION:" line is added iff \a
+ * encodeVersion is true.
+ */
+void QVersitDocumentWriter::encodeVersitDocument(const QVersitDocument& document, bool encodeVersion)
 {
     mSuccessful = true;
-    QList<QVersitProperty> properties = document.properties();
 
-    writeString(QLatin1String("BEGIN:" + mDocumentType));
+    writeString(QLatin1String("BEGIN:") + document.componentType());
     writeCrlf();
-    writeString(QLatin1String("VERSION:" + mVersion));
-    writeCrlf();
-    foreach (const QVersitProperty& property, properties) {
+    if (encodeVersion) {
+        switch (document.type()) {
+        case QVersitDocument::VCard21Type:
+            writeString(QLatin1String("VERSION:2.1"));
+            writeCrlf();
+            break;
+        case QVersitDocument::VCard30Type:
+            writeString(QLatin1String("VERSION:3.0"));
+            writeCrlf();
+            break;
+        case QVersitDocument::VCard40Type:
+            writeString(QLatin1String("VERSION:4.0"));
+            writeCrlf();
+            break;
+        case QVersitDocument::ICalendar20Type:
+            writeString(QLatin1String("VERSION:2.0"));
+            writeCrlf();
+            break;
+        default:
+            ; // don't print version
+        }
+    }
+
+    foreach (const QVersitProperty& property, document.properties()) {
         encodeVersitProperty(property);
     }
-    writeString(QLatin1String("END:" + mDocumentType));
+
+    foreach (const QVersitDocument& document, document.subDocuments()) {
+        encodeVersitDocument(document, false);
+    }
+
+    writeString(QLatin1String("END:") + document.componentType());
     writeCrlf();
 }
 
--- a/src/versit/qversitdocumentwriter_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitdocumentwriter_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -68,7 +68,7 @@
 class Q_AUTOTEST_EXPORT QVersitDocumentWriter
 {
 public:
-    QVersitDocumentWriter(const QByteArray& documentType, const QByteArray& version);
+    QVersitDocumentWriter();
     virtual ~QVersitDocumentWriter();
 
     void setCodec(QTextCodec* codec);
@@ -76,14 +76,12 @@
 
     virtual void encodeVersitProperty(const QVersitProperty& property) = 0;
     virtual void encodeParameters(const QMultiHash<QString,QString>& parameters) = 0;
-    void encodeVersitDocument(const QVersitDocument& document);
+    void encodeVersitDocument(const QVersitDocument& document, bool encodeVersion = true);
     void encodeGroupsAndName(const QVersitProperty& property);
 
     void writeString(const QString& string, bool useUtf8 = false);
     void writeCrlf();
 
-    QByteArray mDocumentType;
-    QByteArray mVersion;
     QIODevice* mDevice;
     QTextCodec* mCodec;
     QTextEncoder* mEncoder;
--- a/src/versit/qversitproperty.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitproperty.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -52,6 +52,7 @@
   \class QVersitProperty
   \brief The QVersitProperty class stores the name, value, groups and parameters of a Versit property.
   \ingroup versit
+  \inmodule QtVersit
 
   A vCard is represented in abstract form as a QVersitDocument that consists of a number of
   properties such as a name (N), a telephone number (TEL) and an email address (EMAIL), for
@@ -182,7 +183,10 @@
     for (it = parameters.constBegin(); it != parameters.constEnd(); ++it) {
         dbg.nospace() << ';' << it.key() << '=' << it.value();
     }
-    dbg.nospace() << ':' << property.variantValue();
+    if (property.valueType() == QVersitProperty::VersitDocumentType)
+        dbg.nospace() << ':' << property.value<QVersitDocument>();
+    else
+        dbg.nospace() << ':' << property.variantValue();
     dbg.nospace() << ')';
     return dbg.maybeSpace();
 }
@@ -362,6 +366,7 @@
     d->mName.clear();
     d->mValue.clear();
     d->mParameters.clear();
+    d->mValueType = QVersitProperty::PlainType;
 }
 
 QTM_END_NAMESPACE
--- a/src/versit/qversitreader.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitreader.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -53,8 +53,10 @@
 
 /*!
   \class QVersitReader
-  \brief The QVersitReader class reads Versit documents such as vCards from a device.
+  \brief The QVersitReader class provides an interface for reading versit
+  documents such as vCards from a Stream.
   \ingroup versit
+  \inmodule QtVersit
 
   QVersitReader concatenation of Versit documents such as vCards
   from a text stream and returns a list of QVersitDocument instances.
@@ -213,7 +215,8 @@
  * when the reading has finished.
  */
 bool QVersitReader::startReading()
-{    if (d->state() == ActiveState || d->isRunning()) {
+{
+    if (d->state() == ActiveState || d->isRunning()) {
         d->setError(QVersitReader::NotReadyError);
         return false;
     } else if (!d->mIoDevice || !d->mIoDevice->isReadable()) {
@@ -239,6 +242,8 @@
 /*!
  * If the state is ActiveState, blocks until the reader has finished reading or \a msec milliseconds
  * has elapsed, returning true if it successfully finishes or is cancelled by the user.
+ * If \m msec is negative or zero, the function blocks until the writer has finished, regardless of
+ * how long it takes.
  * If the state is FinishedState, returns true immediately.
  * Otherwise, returns false immediately.
  */
@@ -246,7 +251,10 @@
 {
     State state = d->state();
     if (state == ActiveState) {
-        return d->wait(msec);
+        if (msec <= 0)
+            return d->wait(ULONG_MAX);
+        else
+            return d->wait(msec);
     } else if (state == FinishedState) {
         return true;
     } else {
--- a/src/versit/qversitreader_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitreader_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -53,6 +53,9 @@
 // Some big enough value for nested versit documents to prevent infinite recursion
 #define MAX_VERSIT_DOCUMENT_NESTING_DEPTH 20
 
+QHash<QPair<QVersitDocument::VersitType,QString>, QVersitProperty::ValueType>*
+    QVersitReaderPrivate::mValueTypeMap = 0;
+
 /*!
   \class LineReader
   \brief The LineReader class is a wrapper around a QIODevice that allows line-by-line reading.
@@ -72,25 +75,29 @@
     mCodec(codec),
     mChunkSize(chunkSize),
     mCrlfList(*VersitUtils::newlineList(mCodec)),
-    mBuffer(VersitCursor(QByteArray())),
-    mOdometer(0)
+    mBuffer(LByteArray(QByteArray())),
+    mOdometer(0),
+    mSearchFrom(0)
 {
 }
 
 /*!
-  Attempts to read a line and returns a VersitCursor describing the line.  The cursor returned
-  includes the data, as well as the position and selection index bounds.  Data within those bounds
-  represents the line.  Data outside those bounds should not be used.
- */
-VersitCursor LineReader::readLine()
+  Attempts to read a line and returns an LByteArray containing the line.
+  */
+LByteArray LineReader::readLine()
 {
-    mBuffer.position = mBuffer.selection;
-    mSearchFrom = mBuffer.position;
+    if (!mFirstLine.isEmpty()) {
+        LByteArray retval(mFirstLine);
+        mFirstLine.clear();
+        return retval;
+    }
+    mBuffer.mStart = mBuffer.mEnd;
+    mSearchFrom = mBuffer.mStart;
 
     // First, look for a newline in the already-existing buffer.  If found, return the line.
     if (tryReadLine(mBuffer, false)) {
         mBuffer.dropOldData();
-        mOdometer += mBuffer.selection - mBuffer.position;
+        mOdometer += mBuffer.size();
         return mBuffer;
     }
 
@@ -98,10 +105,10 @@
     while (!mDevice->atEnd()) {
         QByteArray temp = mDevice->read(mChunkSize);
         if (!temp.isEmpty()) {
-            mBuffer.data.append(temp);
+            mBuffer.mData.append(temp);
             if (tryReadLine(mBuffer, false)) {
                 mBuffer.dropOldData();
-                mOdometer += mBuffer.selection - mBuffer.position;
+                mOdometer += mBuffer.size();
                 return mBuffer;
             }
         } else {
@@ -112,12 +119,20 @@
     // We've reached the end of the stream.  Find a newline from the buffer (or return what's left).
     tryReadLine(mBuffer, true);
     mBuffer.dropOldData();
-    mOdometer += mBuffer.selection - mBuffer.position;
+    mOdometer += mBuffer.size();
     return mBuffer;
 }
 
 /*!
-  How many bytes have been returned in the VersitCursor in the lifetime of the LineReader.
+  Push a line onto the front of the line reader so it will be returned on the next call to readLine().
+  */
+void LineReader::pushLine(const QByteArray& line)
+{
+    mFirstLine = line;
+}
+
+/*!
+  How many bytes have been returned in the LByteArray in the lifetime of the LineReader.
  */
 int LineReader::odometer()
 {
@@ -127,11 +142,11 @@
 /*!
   Returns true if there are no more lines left for readLine() to return.  It is possible for atEnd()
   to return false and for there to be no more data left (eg. if there are trailing newlines at the
-  end of the input.  In this case, readLine() will return an empty line (ie. position == selection).
+  end of the input.  In this case, readLine() will return an empty line.
  */
 bool LineReader::atEnd()
 {
-    return mDevice->atEnd() && mBuffer.selection == mBuffer.data.size();
+    return mFirstLine.isEmpty() && mDevice->atEnd() && mBuffer.mEnd == mBuffer.mData.size();
 }
 
 /*!
@@ -147,9 +162,9 @@
  * sequences of newline-space from the retrieved line.  Skips over any newlines at the start of the
  * input.
  *
- * Returns a VersitCursor containing and selecting the line.
+ * Returns an LByteArray containing the line.
  */
-bool LineReader::tryReadLine(VersitCursor &cursor, bool atEnd)
+bool LineReader::tryReadLine(LByteArray &cursor, bool atEnd)
 {
     int crlfPos = -1;
 
@@ -160,21 +175,21 @@
     forever {
         foreach(const QByteArrayMatcher& crlf, mCrlfList) {
             int crlfLength = crlf.pattern().length();
-            crlfPos = crlf.indexIn(cursor.data, mSearchFrom);
-            if (crlfPos == cursor.position) {
-                // Newline at start of line.  Set position to directly after it.
-                cursor.position += crlfLength;
-                mSearchFrom = cursor.position;
+            crlfPos = crlf.indexIn(cursor.mData, mSearchFrom);
+            if (crlfPos == cursor.mStart) {
+                // Newline at start of line.  Set mStart to directly after it.
+                cursor.mStart += crlfLength;
+                mSearchFrom = cursor.mStart;
                 break;
-            } else if (crlfPos > cursor.position) {
+            } else if (crlfPos > cursor.mStart) {
                 // Found the CRLF.
-                if (QVersitReaderPrivate::containsAt(cursor.data, space, crlfPos + crlfLength)
-                    || QVersitReaderPrivate::containsAt(cursor.data, tab, crlfPos + crlfLength)) {
+                if (QVersitReaderPrivate::containsAt(cursor.mData, space, crlfPos + crlfLength)
+                    || QVersitReaderPrivate::containsAt(cursor.mData, tab, crlfPos + crlfLength)) {
                     // If it's followed by whitespace, collapse it.
-                    cursor.data.remove(crlfPos, crlfLength + spaceLength);
+                    cursor.mData.remove(crlfPos, crlfLength + spaceLength);
                     mSearchFrom = crlfPos;
                     break;
-                } else if (!atEnd && crlfPos + crlfLength + spaceLength >= cursor.data.size()) {
+                } else if (!atEnd && crlfPos + crlfLength + spaceLength >= cursor.mData.size()) {
                     // If our CRLF is at the end of the current buffer but there's more to read,
                     // it's possible that a space could be hiding on the next read from the device.
                     // Just pretend we didn't see the CRLF and pick it up the next time round.
@@ -182,14 +197,14 @@
                     return false;
                 } else {
                     // Found the CRLF.
-                    cursor.selection = crlfPos;
+                    cursor.mEnd = crlfPos;
                     return true;
                 }
             }
         }
         if (crlfPos == -1) {
             // No CRLF found.
-            cursor.selection = cursor.data.size();
+            cursor.mEnd = cursor.mData.size();
             return false;
         }
     }
@@ -214,42 +229,6 @@
     mError(QVersitReader::NoError),
     mIsCanceling(false)
 {
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("AGENT")),
-                         QVersitProperty::VersitDocumentType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("AGENT")),
-                         QVersitProperty::VersitDocumentType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("N")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("N")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("ADR")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("ADR")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("GEO")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("GEO")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("ORG")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("ORG")),
-                         QVersitProperty::CompoundType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("NICKNAME")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("NICKNAME")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("CATEGORIES")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("CATEGORIES")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("X-CHILDREN")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("X-CHILDREN")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("X-NICKNAME")),
-                         QVersitProperty::ListType);
-    mValueTypeMap.insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("X-NICKNAME")),
-                         QVersitProperty::ListType);
 }
 
 /*! Destroy a reader. */
@@ -257,6 +236,68 @@
 {
 }
 
+QHash<QPair<QVersitDocument::VersitType,QString>, QVersitProperty::ValueType>*
+QVersitReaderPrivate::valueTypeMap() {
+    if (mValueTypeMap == 0) {
+        mValueTypeMap = new QHash<QPair<QVersitDocument::VersitType,QString>, QVersitProperty::ValueType>();
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("AGENT")),
+                             QVersitProperty::VersitDocumentType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("AGENT")),
+                             QVersitProperty::VersitDocumentType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("AGENT")),
+                             QVersitProperty::VersitDocumentType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("N")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("N")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("N")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("ADR")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("ADR")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("ADR")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("GEO")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("GEO")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("GEO")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("ORG")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("ORG")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("ORG")),
+                             QVersitProperty::CompoundType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("NICKNAME")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("NICKNAME")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("NICKNAME")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("CATEGORIES")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("CATEGORIES")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("CATEGORIES")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("X-CHILDREN")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("X-CHILDREN")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("X-CHILDREN")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard21Type, QString::fromAscii("X-NICKNAME")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard30Type, QString::fromAscii("X-NICKNAME")),
+                             QVersitProperty::ListType);
+        mValueTypeMap->insert(qMakePair(QVersitDocument::VCard40Type, QString::fromAscii("X-NICKNAME")),
+                             QVersitProperty::ListType);
+    }
+    return mValueTypeMap;
+}
+
 /*!
  * Inherited from QThread, called by QThread when the thread has been started.
  */
@@ -347,67 +388,80 @@
 /*!
  * Parses a versit document. Returns true if the parsing was successful.
  */
-bool QVersitReaderPrivate::parseVersitDocument(LineReader& lineReader, QVersitDocument& document,
-                                               bool foundBegin)
+bool QVersitReaderPrivate::parseVersitDocument(LineReader& lineReader, QVersitDocument& document)
 {
     if (mDocumentNestingLevel >= MAX_VERSIT_DOCUMENT_NESTING_DEPTH)
         return false; // To prevent infinite recursion
 
-    bool parsingOk = true;
-    mDocumentNestingLevel++;
-
-    // TODO: Various readers should be made subclasses and eliminate assumptions like this.
-    // We don't know what type it is: just assume it's a vCard 3.0
-    document.setType(QVersitDocument::VCard30Type);
+    // If we don't know what type it is, just assume it's a vCard 3.0
+    if (document.type() == QVersitDocument::InvalidType)
+        document.setType(QVersitDocument::VCard30Type);
 
     QVersitProperty property;
 
-    if (!foundBegin) {
-        property = parseNextVersitProperty(document.type(), lineReader);
-        if (property.name() == QLatin1String("BEGIN")
-            && property.value().trimmed().toUpper() == QLatin1String("VCARD")) {
-            foundBegin = true;
-        } else if (property.isEmpty()) {
-            // A blank document (or end of file) was found.
+    property = parseNextVersitProperty(document.type(), lineReader);
+    QString propertyValue = property.value().trimmed().toUpper();
+    if (property.isEmpty()) {
+        // A blank document (or end of file) was found.
+        document = QVersitDocument();
+        return true;
+    } else if (property.name() == QLatin1String("BEGIN")) {
+        if (propertyValue == QLatin1String("VCARD")) {
+            document.setComponentType(propertyValue);
+        } else if (propertyValue == QLatin1String("VCALENDAR")) {
+            document.setType(QVersitDocument::ICalendar20Type);
+            document.setComponentType(propertyValue);
+        } else {
+            // Unknown document type
             document = QVersitDocument();
-        } else {
-            // Some property other than BEGIN was found.
-            parsingOk = false;
+            return false;
         }
+    } else {
+        // Some property other than BEGIN was found.
+        document = QVersitDocument();
+        return false;
     }
 
-    if (foundBegin) {
-        do {
-            /* Grab it */
-            property = parseNextVersitProperty(document.type(), lineReader);
+    return parseVersitDocumentBody(lineReader, document);
+}
+
+bool QVersitReaderPrivate::parseVersitDocumentBody(LineReader& lineReader, QVersitDocument& document)
+{
+    mDocumentNestingLevel++;
+    bool parsingOk = true;
+    while (true) {
+        /* Grab it */
+        QVersitProperty property = parseNextVersitProperty(document.type(), lineReader);
 
-            /* Discard embedded vcard documents - not supported yet.  Discard the entire vCard */
-            if (property.name() == QLatin1String("BEGIN") &&
-                QString::compare(property.value().trimmed(),
-                                 QLatin1String("VCARD"), Qt::CaseInsensitive) == 0) {
-                parsingOk = false;
-                QVersitDocument nestedDocument;
-                if (!parseVersitDocument(lineReader, nestedDocument, true))
-                    break;
-            }
-
-            // See if this is a version property and continue parsing under that version
+        if (property.name() == QLatin1String("BEGIN")) {
+            // Nested Versit document
+            QVersitDocument subDocument;
+            subDocument.setType(document.type());
+            subDocument.setComponentType(property.value().trimmed().toUpper());
+            if (!parseVersitDocumentBody(lineReader, subDocument))
+                break;
+            document.addSubDocument(subDocument);
+        } else if (property.name() == QLatin1String("VERSION")) {
+            // A version property
             if (!setVersionFromProperty(document, property)) {
                 parsingOk = false;
                 break;
             }
-
-            /* Nope, something else.. just add it */
-            if (property.name() != QLatin1String("VERSION") &&
-                property.name() != QLatin1String("END"))
-                document.addProperty(property);
-        } while (property.name().length() > 0 && property.name() != QLatin1String("END"));
-        if (property.name() != QLatin1String("END"))
+        } else if (property.name() == QLatin1String("END")) {
+            // End of document
+            break;
+        } else if (property.name().isEmpty()) {
+            // End of input or some other error
             parsingOk = false;
+            break;
+        } else {
+            // A normal property - just add it.
+            document.addProperty(property);
+        }
     }
-    mDocumentNestingLevel--;
     if (!parsingOk)
         document = QVersitDocument();
+    mDocumentNestingLevel--;
 
     return parsingOk;
 }
@@ -419,8 +473,8 @@
         QVersitDocument::VersitType versitType,
         LineReader& lineReader)
 {
-    VersitCursor cursor = lineReader.readLine();
-    if (cursor.position >= cursor.selection)
+    LByteArray cursor = lineReader.readLine();
+    if (cursor.isEmpty())
         return QVersitProperty();
 
     // Otherwise, do stuff.
@@ -433,13 +487,15 @@
     // set the propertyValueType
     QPair<QVersitDocument::VersitType, QString> key =
         qMakePair(versitType, property.name());
-    if (mValueTypeMap.contains(key))
-        property.setValueType(mValueTypeMap.value(key));
+    if (valueTypeMap()->contains(key))
+        property.setValueType(valueTypeMap()->value(key));
 
     if (versitType == QVersitDocument::VCard21Type)
         parseVCard21Property(cursor, property, lineReader);
-    else if (versitType == QVersitDocument::VCard30Type)
-        parseVCard30Property(cursor, property, lineReader);
+    else if (versitType == QVersitDocument::VCard30Type
+            || versitType == QVersitDocument::VCard40Type
+            || versitType == QVersitDocument::ICalendar20Type)
+        parseVCard30Property(versitType, cursor, property, lineReader);
 
     return property;
 }
@@ -447,31 +503,30 @@
 /*!
  * Parses the property according to vCard 2.1 syntax.
  */
-void QVersitReaderPrivate::parseVCard21Property(VersitCursor& cursor, QVersitProperty& property,
+void QVersitReaderPrivate::parseVCard21Property(LByteArray& cursor, QVersitProperty& property,
                                                 LineReader& lineReader)
 {
     property.setParameters(extractVCard21PropertyParams(cursor, lineReader.codec()));
 
-    QByteArray value = extractPropertyValue(cursor);
+    QByteArray value = cursor.toByteArray();
     if (property.valueType() == QVersitProperty::VersitDocumentType) {
         // Hack to handle cases where start of document is on the same or next line as "AGENT:"
-        bool foundBegin = false;
         if (value == "BEGIN:VCARD") {
-            foundBegin = true;
+            lineReader.pushLine(value);
         } else if (value.isEmpty()) {
         } else {
             property = QVersitProperty();
             return;
         }
-        QVersitDocument subDocument;
-        if (!parseVersitDocument(lineReader, subDocument, foundBegin)) {
+        QVersitDocument subDocument(QVersitDocument::VCard21Type);
+        if (!parseVersitDocument(lineReader, subDocument)) {
             property = QVersitProperty();
         } else {
             property.setValue(QVariant::fromValue(subDocument));
         }
     } else {
         QTextCodec* codec;
-        bool isBinary = unencode(value, cursor, property, lineReader);
+        bool isBinary = unencode(value, property, lineReader);
         if (isBinary) {
             property.setValue(value);
             property.setValueType(QVersitProperty::BinaryType);
@@ -484,14 +539,16 @@
 }
 
 /*!
- * Parses the property according to vCard 3.0 syntax.
+ * Parses the property according to vCard 3.0 syntax.  This function is called for both vCard 3.0
+ * and iCalendar properties.
  */
-void QVersitReaderPrivate::parseVCard30Property(VersitCursor& cursor, QVersitProperty& property,
+void QVersitReaderPrivate::parseVCard30Property(QVersitDocument::VersitType versitType,
+                                                LByteArray& cursor, QVersitProperty& property,
                                                 LineReader& lineReader)
 {
     property.setParameters(extractVCard30PropertyParams(cursor, lineReader.codec()));
 
-    QByteArray value = extractPropertyValue(cursor);
+    QByteArray value = cursor.toByteArray();
 
     QTextCodec* codec;
 
@@ -505,14 +562,14 @@
         subDocumentData.seek(0);
         LineReader subDocumentLineReader(&subDocumentData, codec);
 
-        QVersitDocument subDocument;
+        QVersitDocument subDocument(versitType);
         if (!parseVersitDocument(subDocumentLineReader, subDocument)) {
             property = QVersitProperty();
         } else {
             property.setValue(QVariant::fromValue(subDocument));
         }
     } else {
-        bool isBinary = unencode(value, cursor, property, lineReader);
+        bool isBinary = unencode(value, property, lineReader);
         if (isBinary) {
             property.setValue(value);
             property.setValueType(QVersitProperty::BinaryType);
@@ -540,32 +597,33 @@
  */
 bool QVersitReaderPrivate::setVersionFromProperty(QVersitDocument& document, const QVersitProperty& property) const
 {
-    bool valid = true;
-    if (property.name() == QLatin1String("VERSION")) {
-        QString value = property.value().trimmed();
-        QStringList encodingParameters = property.parameters().values(QLatin1String("ENCODING"));
-        QStringList typeParameters = property.parameters().values(QLatin1String("TYPE"));
-        if (encodingParameters.contains(QLatin1String("BASE64"), Qt::CaseInsensitive)
-            || typeParameters.contains(QLatin1String("BASE64"), Qt::CaseInsensitive))
-            value = QLatin1String(QByteArray::fromBase64(value.toAscii()));
-        if (value == QLatin1String("2.1")) {
-            document.setType(QVersitDocument::VCard21Type);
-        } else if (value == QLatin1String("3.0")) {
-            document.setType(QVersitDocument::VCard30Type);
-        } else {
-            valid = false;
-        }
+    QString value = property.value().trimmed();
+    if (document.componentType() == QLatin1String("VCARD")
+            && value == QLatin1String("2.1")) {
+        document.setType(QVersitDocument::VCard21Type);
+    } else if (document.componentType() == QLatin1String("VCARD")
+            && value == QLatin1String("3.0")) {
+        document.setType(QVersitDocument::VCard30Type);
+    } else if (document.componentType() == QLatin1String("VCARD")
+            && value == QLatin1String("4.0")) {
+        document.setType(QVersitDocument::VCard40Type);
+    } else if ((document.componentType() == QLatin1String("VCALENDAR")
+                || document.type() == QVersitDocument::ICalendar20Type) // covers VEVENT, etc. when nested inside a VCALENDAR
+            && value == QLatin1String("2.0")) {
+        document.setType(QVersitDocument::ICalendar20Type);
+    } else {
+        return false;
     }
-    return valid;
+    return true;
 }
 
 /*!
  * On entry, \a value should be the byte array to unencode.  It is modified to be the unencoded
- * version.  Returns true if and only if the value was base-64 encoded.  \a cursor and
- * \a lineReader are supplied in case more lines need to be read (for quoted-printable).  The
+ * version.  Returns true if and only if the value was base-64 encoded.
+ * \a lineReader is supplied in case more lines need to be read (for quoted-printable).  The
  * \a property is supplied so we know what kind of encoding was used.
  */
-bool QVersitReaderPrivate::unencode(QByteArray& value, VersitCursor& cursor,
+bool QVersitReaderPrivate::unencode(QByteArray& value,
                                     QVersitProperty& property,
                                     LineReader& lineReader) const
 {
@@ -577,9 +635,7 @@
         while (value.endsWith('=')) {
             value.chop(1); // Get rid of '='
             // We add each line (minus the escaped = and newline chars)
-            cursor = lineReader.readLine();
-            QByteArray line = cursor.data.mid(cursor.position, cursor.selection-cursor.position);
-            value.append(line);
+            value.append(lineReader.readLine().toByteArray());
         }
         decodeQuotedPrintable(value);
         // Remove the encoding parameter as the value is now decoded
@@ -655,31 +711,28 @@
 /*!
  * Extracts the groups and the name of the property using \a codec to determine the delimiters
  *
- * On entry, \a line should select a whole line.
- * On exit, \a line will be updated to point after the groups and name.
+ * On entry, \a line should contain a whole line
+ * On exit, \a line will be updated to remove the groups and name
  */
 QPair<QStringList,QString>QVersitReaderPrivate::extractPropertyGroupsAndName(
-        VersitCursor& line, QTextCodec *codec) const
+        LByteArray& line, QTextCodec *codec) const
 {
     const QByteArray semicolon = VersitUtils::encode(';', codec);
     const QByteArray colon = VersitUtils::encode(':', codec);
     const QByteArray backslash = VersitUtils::encode('\\', codec);
     QPair<QStringList,QString> groupsAndName;
     int length = 0;
-    Q_ASSERT(line.data.size() >= line.position);
 
     int separatorLength = semicolon.length();
-    for (int i = line.position; i < line.selection - separatorLength + 1; i++) {
-        if ((containsAt(line.data, semicolon, i)
-                && !containsAt(line.data, backslash, i-separatorLength))
-            || containsAt(line.data, colon, i)) {
-            length = i - line.position;
+    for (int i = 0; i < line.size() - separatorLength + 1; i++) {
+        if ((containsAt(line, semicolon, i) && !containsAt(line, backslash, i-separatorLength))
+            || containsAt(line, colon, i)) {
+            length = i;
             break;
         }
     }
     if (length > 0) {
-        QString trimmedGroupsAndName =
-                codec->toUnicode(line.data.mid(line.position, length)).trimmed();
+        QString trimmedGroupsAndName = codec->toUnicode(line.left(length)).trimmed();
         QStringList parts = trimmedGroupsAndName.split(QLatin1Char('.'));
         if (parts.count() > 1) {
             groupsAndName.second = parts.takeLast();
@@ -687,37 +740,21 @@
         } else {
             groupsAndName.second = trimmedGroupsAndName;
         }
-        line.setPosition(length + line.position);
+        line.chopLeft(length);
     }
 
     return groupsAndName;
 }
 
 /*!
- * Extracts the value of the property.
- * Returns an empty string if the value was not found.
- *
- * On entry \a line should point to the value anyway.
- * On exit \a line should point to newline after the value
- */
-QByteArray QVersitReaderPrivate::extractPropertyValue(VersitCursor& line) const
-{
-    QByteArray value = line.data.mid(line.position, line.selection - line.position);
-
-    /* Now advance the cursor in all cases. */
-    line.position = line.selection;
-    return value;
-}
-
-/*!
  * Extracts the property parameters as a QMultiHash using \a codec to determine the delimiters.
  * The parameters without names are added as "TYPE" parameters.
  *
- * On entry \a line should contain the entire line.
- * On exit, line will be updated to point to the start of the value.
+ * On entry \a line should contain the line sans the group and name
+ * On exit, line will be updated to have the parameters removed.
  */
 QMultiHash<QString,QString> QVersitReaderPrivate::extractVCard21PropertyParams(
-        VersitCursor& line, QTextCodec *codec) const
+        LByteArray& line, QTextCodec *codec) const
 {
     QMultiHash<QString,QString> result;
     QList<QByteArray> paramList = extractParams(line, codec);
@@ -734,9 +771,12 @@
 /*!
  * Extracts the property parameters as a QMultiHash using \a codec to determine the delimiters.
  * The parameters without names are added as "TYPE" parameters.
+ *
+ * On entry \a line should contain the line sans the group and name
+ * On exit, line will be updated to have the parameters removed.
  */
 QMultiHash<QString,QString> QVersitReaderPrivate::extractVCard30PropertyParams(
-        VersitCursor& line, QTextCodec *codec) const
+        LByteArray& line, QTextCodec *codec) const
 {
     QMultiHash<QString,QString> result;
     QList<QByteArray> paramList = extractParams(line, codec);
@@ -758,25 +798,25 @@
 /*!
  * Extracts the parameters as delimited by semicolons using \a codec to determine the delimiters.
  *
- * On entry \a line should point to the start of the parameter section (past the name).
- * On exit, \a line will be updated to point to the start of the value.
+ * On entry \a line should contain the content line sans the group and name
+ * On exit, \a line will be updated to only have the value remain
  */
-QList<QByteArray> QVersitReaderPrivate::extractParams(VersitCursor& line, QTextCodec *codec) const
+QList<QByteArray> QVersitReaderPrivate::extractParams(LByteArray& line, QTextCodec *codec) const
 {
     const QByteArray colon = VersitUtils::encode(':', codec);
     QList<QByteArray> params;
 
     /* find the end of the name&params */
-    int colonIndex = line.data.indexOf(colon, line.position);
-    if (colonIndex > line.position && colonIndex < line.selection) {
-        QByteArray nameAndParamsString = line.data.mid(line.position, colonIndex - line.position);
+    int colonIndex = line.indexOf(colon);
+    if (colonIndex > 0) {
+        QByteArray nameAndParamsString = line.left(colonIndex);
         params = extractParts(nameAndParamsString, VersitUtils::encode(';', codec), codec);
 
         /* Update line */
-        line.setPosition(colonIndex + colon.length());
-    } else if (colonIndex == line.position) {
+        line.chopLeft(colonIndex + colon.length());
+    } else if (colonIndex == 0) {
         // No parameters.. advance past it
-        line.setPosition(line.position + colon.length());
+        line.chopLeft(colon.length());
     }
 
     return params;
@@ -860,15 +900,17 @@
     return codec->toUnicode(value);
 }
 
-/*!
+/*
  * Returns true if and only if \a text contains \a ba at \a index
  *
  * On entry, index must be >= 0
+ *
+ * T is either a QByteArray or LByteArray
  */
-bool QVersitReaderPrivate::containsAt(const QByteArray& text, const QByteArray& match, int index)
+template <class T> bool QVersitReaderPrivate::containsAt(const T& text, const QByteArray& match, int index)
 {
     int n = match.length();
-    if (text.length() - index < n)
+    if (text.size() - index < n)
         return false;
     const char* textData = text.constData();
     const char* matchData = match.constData();
--- a/src/versit/qversitreader_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitreader_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -83,45 +83,93 @@
 // the more time spent moving bytes around.  The larger it is, the more memory is wasted.
 static const int MAX_OLD_BYTES_TO_KEEP = 8192;
 
-class Q_AUTOTEST_EXPORT VersitCursor
+/*
+ * An LByteArray has a subset of QByteArray's interface, plus an efficient chopLeft function
+ * 
+ * It stores a QByteArray internally, plus a marker of where it starts and where it ends.
+ */
+class Q_AUTOTEST_EXPORT LByteArray
 {
 public:
-    VersitCursor() : position(-1), selection(-1) {}
-    explicit VersitCursor(const QByteArray& d) :data(d), position(0), selection(0) {}
-    QByteArray data;
-    int position;
-    int selection;
+    LByteArray() : mStart(0), mEnd(0) {}
+    explicit LByteArray(const QByteArray& d) :mData(d), mStart(0), mEnd(d.size()) {}
+    bool isEmpty() const {
+        return mEnd <= mStart;
+    }
+    char at(int i) const {
+        return mData.at(mStart + i);
+    }
+    QByteArray toByteArray() const {
+        return mData.mid(mStart, mEnd-mStart);
+    }
+    /* Removes \a n bytes from the start of the QByteArray. */ 
+    void chopLeft(int n) {
+        Q_ASSERT(size() >= n && n >= 0);
+        mStart += n;
+    }
+    QByteArray left(int n) {
+        Q_ASSERT(size() >= n && n >= 0);
+        return mData.mid(mStart, n);
+    }
+    int indexOf(const QByteArray& needle) {
+        int index = mData.indexOf(needle, mStart) - mStart;
+        if (index < size())
+            return index;
+        return -1;
+    }
+    int size() const {
+        return mEnd - mStart;
+    }
+    const char* constData() const {
+        return mData.constData() + mStart;
+    }
+    LByteArray& operator=(const QByteArray& ba) {
+        mData = ba;
+        mStart = 0;
+        mEnd = mData.size();
+        return *this;
+    }
+    bool operator==(const QByteArray& ba) {
+        return toByteArray() == ba;
+    }
+    bool operator!=(const QByteArray& ba) {
+        return toByteArray() != ba;
+    }
 
-    void setData(const QByteArray& d) {data = d; position = selection = 0;}
-    void setPosition(int pos) {position = pos; selection = qMax(pos, selection);}
-    void setSelection(int pos) {selection = qMax(pos, position);}
-    void dropOldData()
-    {
-        if (position > MAX_OLD_BYTES_TO_KEEP && selection >= position) {
-            data.remove(0, position);
-            selection -= position;
-            position = 0;
+private:
+    /* Clears the memory of bytes before the start marker */
+    void dropOldData() {
+        if (mStart > MAX_OLD_BYTES_TO_KEEP && mEnd >= mStart) {
+            mData.remove(0, mStart);
+            mEnd -= mStart;
+            mStart = 0;
         }
     }
+    QByteArray mData;
+    int mStart;
+    int mEnd;
+    friend class LineReader;
 };
 
 class Q_AUTOTEST_EXPORT LineReader
 {
 public:
     LineReader(QIODevice* device, QTextCodec* codec, int chunkSize = 1000);
-    VersitCursor readLine();
+    LByteArray readLine();
+    void pushLine(const QByteArray& line);
     int odometer();
     bool atEnd();
     QTextCodec* codec();
 
 private:
-    bool tryReadLine(VersitCursor& cursor, bool atEnd);
+    bool tryReadLine(LByteArray& cursor, bool atEnd);
 
     QIODevice* mDevice;
     QTextCodec* mCodec;
     int mChunkSize; // How many bytes to read in one go.
     QList<QByteArrayMatcher> mCrlfList;
-    VersitCursor mBuffer;
+    QByteArray mFirstLine; // Stores a line that has been "pushed" in front by pushLine
+    LByteArray mBuffer;
     int mOdometer;
     int mSearchFrom;
 };
@@ -133,6 +181,9 @@
 public: // Constructors and destructor
     QVersitReaderPrivate();
     ~QVersitReaderPrivate();
+
+    static QHash<QPair<QVersitDocument::VersitType,QString>, QVersitProperty::ValueType>*
+        valueTypeMap();
     void init(QVersitReader* reader);
 
 signals:
@@ -153,21 +204,21 @@
     void setCanceling(bool cancelling);
     bool isCanceling();
 
-    bool parseVersitDocument(LineReader& device,
-                             QVersitDocument& document,
-                             bool foundBegin = false);
+    bool parseVersitDocument(LineReader& device, QVersitDocument& document);
+    bool parseVersitDocumentBody(LineReader& device, QVersitDocument& document);
 
     QVersitProperty parseNextVersitProperty(
         QVersitDocument::VersitType versitType,
         LineReader& lineReader);
 
     void parseVCard21Property(
-        VersitCursor& text,
+        LByteArray& text,
         QVersitProperty& property,
         LineReader& lineReader);
 
     void parseVCard30Property(
-        VersitCursor& text,
+        QVersitDocument::VersitType versitType,
+        LByteArray& text,
         QVersitProperty& property,
         LineReader& lineReader);
 
@@ -177,7 +228,6 @@
 
     bool unencode(
         QByteArray& value,
-        VersitCursor& cursor,
         QVersitProperty& property,
         LineReader& lineReader) const;
 
@@ -191,22 +241,21 @@
 
 
     /* These functions operate on a cursor describing a single line */
-    QPair<QStringList,QString> extractPropertyGroupsAndName(VersitCursor& line, QTextCodec* codec)
+    QPair<QStringList,QString> extractPropertyGroupsAndName(LByteArray& line, QTextCodec* codec)
             const;
-    QByteArray extractPropertyValue(VersitCursor& line) const;
-    QMultiHash<QString,QString> extractVCard21PropertyParams(VersitCursor& line, QTextCodec* codec)
+    QMultiHash<QString,QString> extractVCard21PropertyParams(LByteArray& line, QTextCodec* codec)
             const;
-    QMultiHash<QString,QString> extractVCard30PropertyParams(VersitCursor& line, QTextCodec* codec)
+    QMultiHash<QString,QString> extractVCard30PropertyParams(LByteArray& line, QTextCodec* codec)
             const;
 
     // "Private" functions
-    QList<QByteArray> extractParams(VersitCursor& line, QTextCodec *codec) const;
+    QList<QByteArray> extractParams(LByteArray& line, QTextCodec *codec) const;
     QList<QByteArray> extractParts(const QByteArray& text, const QByteArray& separator,
                                    QTextCodec *codec) const;
     QByteArray extractPart(const QByteArray& text, int startPosition, int length=-1) const;
     QString paramName(const QByteArray& parameter, QTextCodec* codec) const;
     QString paramValue(const QByteArray& parameter, QTextCodec* codec) const;
-    static bool containsAt(const QByteArray& text, const QByteArray& ba, int index);
+    template <class T> static bool containsAt(const T& text, const QByteArray& ba, int index);
     bool splitStructuredValue(QVersitProperty& property,
                               bool hasEscapedBackslashes) const;
     static QStringList splitValue(const QString& string,
@@ -215,10 +264,8 @@
                                   bool hasEscapedBackslashes);
     static void removeBackSlashEscaping(QString& text);
 
-public: // Data
-    /* key is the document type and property name, value is the type of property it is.
-       If there is no entry, assume it is a PlainType */
-    QHash<QPair<QVersitDocument::VersitType,QString>, QVersitProperty::ValueType> mValueTypeMap;
+// Data
+public:
     QPointer<QIODevice> mIoDevice;
     QScopedPointer<QBuffer> mInputBytes; // Holds the data set by setData()
     QList<QVersitDocument> mVersitDocuments;
@@ -228,6 +275,11 @@
     QVersitReader::Error mError;
     bool mIsCanceling;
     mutable QMutex mMutex;
+
+private:
+    /* key is the document type and property name, value is the type of property it is.
+       If there is no entry, assume it is a PlainType */
+    static QHash<QPair<QVersitDocument::VersitType,QString>, QVersitProperty::ValueType>* mValueTypeMap;
 };
 
 QTM_END_NAMESPACE
--- a/src/versit/qversitresourcehandler.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitresourcehandler.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -50,7 +50,8 @@
   \class QVersitResourceHandler
   \brief The QVersitResourceHandler class is an interface for clients wishing to implement custom
   behaviour for loading and saving files to disk when exporting and importing.
-  \ingroup versit
+  \ingroup versit-extension
+  \inmodule QtVersit
 
   \sa QVersitContactImporter
   \sa QVersitContactExporter
@@ -85,10 +86,10 @@
  
   \brief The QVersitDefaultResourceHandler class provides a default implementation of a Versit
   resource handler.
+  \ingroup versit-extension
  
   An example resource handler implementation:
   \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Resource handler
-  \ingroup versit
  
   \sa QVersitContactImporter, QVersitContactExporter, QVersitResourceHandler
  */
--- a/src/versit/qversitwriter.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitwriter.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -54,6 +54,7 @@
   \class QVersitWriter
   \brief The QVersitWriter class writes Versit documents such as vCards to a device.
   \ingroup versit
+  \inmodule QtVersit
 
   QVersitWriter converts a QVersitDocument into its textual representation.
   QVersitWriter supports writing to an abstract I/O device
@@ -228,6 +229,8 @@
 /*!
  * If the state is ActiveState, blocks until the writer has finished writing or \a msec milliseconds
  * has elapsed, returning true if it successfully finishes or is cancelled by the user.
+ * If \m msec is negative or zero, the function blocks until the writer has finished, regardless of
+ * how long it takes.
  * If the state is FinishedState, returns true immediately.
  * Otherwise, returns false immediately.
  */
@@ -235,7 +238,10 @@
 {
     State state = d->state();
     if (state == ActiveState) {
-        return d->wait(msec);
+        if (msec <= 0)
+            return d->wait(ULONG_MAX);
+        else
+            return d->wait(msec);
     } else if (state == FinishedState) {
         return true;
     } else {
--- a/src/versit/qversitwriter_p.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/qversitwriter_p.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -156,7 +156,7 @@
         case QVersitDocument::VCard30Type:
             return new QVCard30Writer;
         default:
-            return new QVCard21Writer;
+            return new QVCard30Writer;
     }
 }
 
--- a/src/versit/versit.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/versit.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -7,8 +7,7 @@
 
 DEFINES += QT_BUILD_VERSIT_LIB QT_MAKEDLL QT_ASCII_CAST_WARNINGS
 
-CONFIG += mobility
-MOBILITY = contacts
+qtAddLibrary(QtContacts)
 
 # Contacts Includepath
 INCLUDEPATH += . \
@@ -25,11 +24,11 @@
     qversitwriter.h \
     qversitcontactexporter.h \
     qversitcontactimporter.h \
-    qversitresourcehandler.h
+    qversitcontacthandler.h \
+    qversitresourcehandler.h \
 
 # Private Headers
 PRIVATE_HEADERS += \
-    qvcardbackuphandlers_p.h \
     qversitdocument_p.h \
     qversitdocumentwriter_p.h \
     qversitproperty_p.h \
@@ -40,10 +39,13 @@
     qversitcontactexporter_p.h \
     qversitcontactimporter_p.h \
     qversitdefs_p.h \
+    qversitcontactsdefs_p.h \
+    qversitcontactpluginloader_p.h \
     versitutils_p.h
 
 # Implementation
-SOURCES += qversitdocument.cpp \
+SOURCES += \
+    qversitdocument.cpp \
     qversitdocument_p.cpp \
     qversitdocumentwriter_p.cpp \
     qversitproperty.cpp \
@@ -57,8 +59,9 @@
     qversitcontactexporter_p.cpp \
     qversitcontactimporter.cpp \
     qversitcontactimporter_p.cpp \
-    qvcardbackuphandlers_p.cpp \
     qversitresourcehandler.cpp \
+    qversitcontacthandler.cpp \
+    qversitcontactpluginloader_p.cpp \
     versitutils.cpp
 
 HEADERS += \
@@ -68,16 +71,13 @@
 symbian { 
     TARGET.UID3 = 0x2002BFBF
     TARGET.EPOCALLOWDLLDATA = 1
-    TARGET.CAPABILITY = ALL \
-        -TCB
-        
-    defFiles = \
-        "$${LITERAL_HASH}ifdef WINSCW" \
-        "DEFFILE ../s60installs/bwins/$${TARGET}.def" \
-        "$${LITERAL_HASH}elif defined EABI" \
-        "DEFFILE ../s60installs/eabi/$${TARGET}.def" \
-        "$${LITERAL_HASH}endif "
-    MMP_RULES += defFiles
+    TARGET.CAPABILITY = ALL -TCB
+
+    LIBS += -lefsrv
+
+    VERSIT_DEPLOYMENT.sources = QtVersit.dll
+    VERSIT_DEPLOYMENT.path = /sys/bin
+    DEPLOYMENT += VERSIT_DEPLOYMENT
 }
 
 maemo5|maemo6 {
--- a/src/versit/versitutils.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/versitutils.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -40,6 +40,8 @@
 ****************************************************************************/
 
 #include "versitutils_p.h"
+#include "qversitdocument.h"
+#include "qversitproperty.h"
 #include "qmobilityglobal.h"
 
 #include <QMap>
@@ -106,3 +108,19 @@
 
     m_previousCodec = codec;
 }
+
+/*!
+ * Finds a property in the \a document with the given \a propertyName, adds it to \a toBeRemoved,
+ * and returns it.
+ */
+QVersitProperty VersitUtils::takeProperty(const QVersitDocument& document,
+                                          const QString& propertyName,
+                                          QList<QVersitProperty>* toBeRemoved) {
+    foreach (const QVersitProperty& currentProperty, document.properties()) {
+        if (currentProperty.name() == propertyName) {
+            *toBeRemoved << currentProperty;
+            return currentProperty;
+        }
+    }
+    return QVersitProperty();
+}
--- a/src/versit/versitutils_p.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/src/versit/versitutils_p.h	Mon Oct 04 01:37:06 2010 +0300
@@ -64,6 +64,8 @@
 #include <QMultiHash>
 
 QTM_BEGIN_NAMESPACE
+class QVersitDocument;
+class QVersitProperty;
 
 class Q_AUTOTEST_EXPORT VersitUtils
 {
@@ -72,6 +74,9 @@
     static QByteArray encode(char ch, QTextCodec* codec);
     static QList<QByteArrayMatcher>* newlineList(QTextCodec* codec);
     static void changeCodec(QTextCodec* codec);
+    static QVersitProperty takeProperty(const QVersitDocument& document,
+                                        const QString& propertyName,
+                                        QList<QVersitProperty>* toBeRemoved);
 
 private:
     // These are caches for performance:
--- a/tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -180,7 +180,7 @@
     content2 = QMediaContent(QUrl(QLatin1String("file:///2")));
     content3 = QMediaContent(QUrl(QLatin1String("file:///3")));
 
-    QMediaPluginLoader::setStaticPlugins(QLatin1String("/playlistformats"), QObjectList() << new QM3uPlaylistPlugin(this));
+    QMediaPluginLoader::setStaticPlugins(QLatin1String("playlistformats"), QObjectList() << new QM3uPlaylistPlugin(this));
 }
 
 void tst_QMediaPlaylist::cleanup()
--- a/tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -311,7 +311,7 @@
     plugins << new MockServicePlugin3;
     plugins << new MockServicePlugin4;
 
-    QMediaPluginLoader::setStaticPlugins(QLatin1String("/mediaservice"), plugins);
+    QMediaPluginLoader::setStaticPlugins(QLatin1String("mediaservice"), plugins);
 }
 
 void tst_QMediaServiceProvider::testDefaultProviderAvailable()
--- a/tests/auto/qmessageservice/tst_qmessageservice.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qmessageservice/tst_qmessageservice.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -461,7 +461,7 @@
             QTRY_VERIFY(sc.state == QMessageService::FinishedState);
 #else
             while(testService->state() == QMessageService::ActiveState)
-				QTest::qWait(1000);
+				QTest::qWait(50);
 #endif
             QCOMPARE(sc.ids.toSet().subtract(existingMessageIds),ids.toSet());
 
@@ -472,7 +472,7 @@
             QTRY_VERIFY(sc.state == QMessageService::FinishedState);
 #else
             while(testService->state() == QMessageService::ActiveState)
-                QTest::qWait(1000);
+                QTest::qWait(50);
 #endif
             QCOMPARE(sc.ids.toSet().subtract(existingMessageIds),negatedIds.toSet());
 
@@ -485,7 +485,7 @@
             QTRY_VERIFY(sc.state == QMessageService::FinishedState);
 #else
             while(testService->state() == QMessageService::ActiveState)
-                QTest::qWait(1000);
+                QTest::qWait(50);
 #endif
             QCOMPARE(sc.ids.toSet().subtract(existingMessageIds),ids.toSet());
 
@@ -496,7 +496,7 @@
             QTRY_VERIFY(sc.state == QMessageService::FinishedState);
 #else
             while(testService->state() == QMessageService::ActiveState)
-                QTest::qWait(1000);
+                QTest::qWait(50);
 #endif
             QCOMPARE(sc.ids.toSet().subtract(existingMessageIds),negatedIds.toSet());
         }
@@ -1955,7 +1955,7 @@
             QTRY_VERIFY(sc.state == QMessageService::FinishedState);
 #else
             while(testService->state() == QMessageService::ActiveState)
-				QTest::qWait(1000);
+				QTest::qWait(50);
 #endif
             QCOMPARE(sc.count-existingMessageIds.count(), ids.count());
 
@@ -1964,7 +1964,7 @@
             QTRY_VERIFY(sc.state == QMessageService::FinishedState);
 #else
             while(testService->state() == QMessageService::ActiveState)
-                QTest::qWait(1000);
+                QTest::qWait(50);
 #endif
             QCOMPARE(sc.count-existingMessageIds.count(), negatedIds.count());
         }
--- a/tests/auto/qsensor/qsensor.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qsensor/qsensor.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -11,6 +11,8 @@
 MOBILITY = sensors
 INCLUDEPATH += ../../../src/sensors
 
+#symbian:DEFINES += WAIT_AT_END
+
 SOURCES += \
     tst_qsensor.cpp
 
--- a/tests/auto/qsensor/tst_qsensor.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qsensor/tst_qsensor.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -42,6 +42,7 @@
 #include <QTest>
 #include <QDebug>
 #include <QSettings>
+#include <QFile>
 
 #include "qsensor.h"
 #include "test_sensor.h"
@@ -49,7 +50,7 @@
 
 QTM_USE_NAMESPACE
 
-        class MyFilter : public TestSensorFilter
+class MyFilter : public TestSensorFilter
 {
     bool filter(TestSensorReading *reading)
     {
@@ -80,6 +81,11 @@
     {
         QSettings settings(QLatin1String("Nokia"), QLatin1String("Sensors"));
         settings.clear();
+#ifdef WAIT_AT_END
+        QFile _stdin;
+        _stdin.open(1, QIODevice::ReadOnly);
+        _stdin.readLine();
+#endif
     }
 
 
--- a/tests/auto/qsystemdisplayinfo/tst_qsystemdisplayinfo.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qsystemdisplayinfo/tst_qsystemdisplayinfo.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -56,13 +56,13 @@
 {
     QSystemDisplayInfo di;
     QVERIFY(di.displayBrightness(0) > -2);
+    QVERIFY(di.displayBrightness(999) == -1);
 }
 
 void tst_QSystemDisplayInfo::tst_colorDepth()
 {
     QSystemDisplayInfo di;
     int depth = di.colorDepth(0);
-    qWarning() << __FUNCTION__ << depth;
 
     QVERIFY(depth == 0
             || depth == 8
@@ -70,6 +70,8 @@
             || depth == 24
             || depth == 32
             || depth == 64);
+
+    QVERIFY(di.colorDepth(999) == -1);
 }
 
 
--- a/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp	Mon Oct 04 01:37:06 2010 +0300
@@ -545,6 +545,23 @@
     QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
 }
 
+void tst_QValueSpaceSubscriber::testInvalidPath_data()
+{
+    QTest::addColumn<QString>("subscriber_path");
+    QTest::newRow("One char missing") << "/hom";
+    QTest::newRow("Two chars missing") << "/ho";
+    QTest::newRow("One char missing in subdir") << "/home/use";
+    QTest::newRow("Two chars missing in subdir") << "/home/us";
+}
+
+void tst_QValueSpaceSubscriber::testInvalidPath()
+{
+    QFETCH(QString, subscriber_path);
+
+    QValueSpaceSubscriber subscriber(subscriber_path);
+    QVERIFY(subscriber.subPaths().isEmpty());
+}
+
 void tst_QValueSpaceSubscriber::contentsChanged_data()
 {
     QTest::addColumn<QAbstractValueSpaceLayer *>("layer");
--- a/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.h	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.h	Mon Oct 04 01:37:06 2010 +0300
@@ -65,6 +65,9 @@
 
     void testPathChanges();
 
+    void testInvalidPath_data();
+    void testInvalidPath();
+
     void contentsChanged_data();
     void contentsChanged();
     void dataVersatility_data();
--- a/tests/messagingex/messagingex.pro	Fri Sep 17 08:34:34 2010 +0300
+++ b/tests/messagingex/messagingex.pro	Mon Oct 04 01:37:06 2010 +0300
@@ -28,12 +28,6 @@
     smsreceiveddialog.ui \
     accountdialog.ui
 
-symbian:TARGET.CAPABILITY = NetworkServices \
-    LocalServices \
-    ReadUserData \
-    WriteUserData \
-    UserEnvironment \
-    ReadDeviceData \
-    WriteDeviceData \
-    SwEvent
+symbian:TARGET.CAPABILITY = ALL  \
+	-TCB