Revision: 201023
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 23 Jun 2010 18:02:44 +0300
changeset 46 efe85016a067
parent 40 b46a585f6909
child 47 7cbcb2896f0e
Revision: 201023 Kit: 2010125
contacts_plat/contacts_ui_api/inc/cntcenrepkeys.h
contacts_plat/contacts_ui_api/inc/cntuids.h
contacts_plat/presence_cache_api/tsrc/mt_preseceqt/entitytests.cpp
contacts_plat/presence_cache_api/tsrc/mt_preseceqt/entitytests.h
contacts_plat/presence_cache_api/tsrc/mt_preseceqt/mt_preseceqt.pro
contacts_plat/presence_cache_api/tsrc/mt_preseceqt/start.cpp
inc/cntdebug.h
inc/cntglobal.h
phonebookengines/bwins/cntlistmodelu.def
phonebookengines/bwins/cntmaptileserviceu.def
phonebookengines/bwins/cntsimutilityu.def
phonebookengines/cntactions/tsrc/mt_cntactions/main.cpp
phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.cpp
phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.h
phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.pro
phonebookengines/cntactions/tsrc/mt_cntactions/testrunner.cpp
phonebookengines/cntactions/tsrc/mt_cntactions/testrunner.h
phonebookengines/cntimageutility/cntimageutility.pro
phonebookengines/cntlistmodel/cntlistmodel.pro
phonebookengines/cntlistmodel/inc/cntcache.h
phonebookengines/cntlistmodel/inc/cntcache_p.h
phonebookengines/cntlistmodel/inc/cntdefaultinfoprovider.h
phonebookengines/cntlistmodel/inc/cntlistmodel.h
phonebookengines/cntlistmodel/inc/cntlistmodel_p.h
phonebookengines/cntlistmodel/inc/cntpresenceinfoprovider.h
phonebookengines/cntlistmodel/src/cntcache.cpp
phonebookengines/cntlistmodel/src/cntcache_p.cpp
phonebookengines/cntlistmodel/src/cntdefaultinfoprovider.cpp
phonebookengines/cntlistmodel/src/cntlistmodel.cpp
phonebookengines/cntlistmodel/src/cntpresenceinfoprovider.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/image1.png
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/image2.png
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/testrunner.h
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntcache.h
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntdefaultinfoprovider.h
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntlistmodel.h
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntpresenceinfoprovider.h
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/runtest.cmd
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/main.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/testrunner.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntcache.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntdefaultinfoprovider.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntlistmodel.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntpresenceinfoprovider.cpp
phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/ut_cntlistmodel.pro
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/image1.png
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/image2.png
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/inc/testrunner.h
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/inc/ut_mobcntmodel.h
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/src/main.cpp
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/src/testrunner.cpp
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/src/ut_mobcntmodel.cpp
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/ut_mobcntmodel.pro
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/ut_mobcntmodel_template.sis
phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/ut_mobcntmodel_template.sisx
phonebookengines/cntmaptileservice/cntmaptileservice.pro
phonebookengines/cntmaptileservice/conf/cntmaptilepublisher.qcrml
phonebookengines/cntmaptileservice/inc/cntmaptiledblookuptable.h
phonebookengines/cntmaptileservice/inc/cntmaptileservice.h
phonebookengines/cntmaptileservice/src/cntmaptiledblookuptable.cpp
phonebookengines/cntmaptileservice/src/cntmaptileservice.cpp
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/data/homeaddressmap.png
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/data/preferredaddressmap.png
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/data/workaddressmap.png
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/homeaddressmap.png
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/inc/testrunner.h
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/inc/ut_cntmaptileservice.h
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/preferredaddressmap.png
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/src/main.cpp
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/src/testrunner.cpp
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/src/ut_cntmaptileservice.cpp
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/ut_cntmaptileservice.pro
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/ut_maptileservice.cpp
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/ut_maptileservice.pro
phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/workaddressmap.png
phonebookengines/cntsimutility/cntsimutility.pro
phonebookengines/cntsimutility/inc/cntsimutility.h
phonebookengines/cntsimutility/src/cntsimutility.cpp
phonebookengines/contactsmodel/bwins/cntplsqlU.def
phonebookengines/contactsmodel/cntmodel/src/ccontactdatabase.cpp
phonebookengines/contactsmodel/cntplsql/inc/c12keykeymap.h
phonebookengines/contactsmodel/cntplsql/inc/c12keypredictivesearchtable.h
phonebookengines/contactsmodel/cntplsql/inc/cntsqlsearch.h
phonebookengines/contactsmodel/cntplsql/inc/cpcskeymap.h
phonebookengines/contactsmodel/cntplsql/inc/cpredictivesearchsettingstable.h
phonebookengines/contactsmodel/cntplsql/inc/cpredictivesearchsynchronizer.h
phonebookengines/contactsmodel/cntplsql/inc/cqwertykeymap.h
phonebookengines/contactsmodel/cntplsql/inc/cqwertypredictivesearchtable.h
phonebookengines/contactsmodel/cntplsql/inc/dbsqlconstants.h
phonebookengines/contactsmodel/cntplsql/inc/pltables.h
phonebookengines/contactsmodel/cntplsql/inc/pplcontactitemmanager.h
phonebookengines/contactsmodel/cntplsql/inc/predictivesearchlog.h
phonebookengines/contactsmodel/cntplsql/src/c12keykeymap.cpp
phonebookengines/contactsmodel/cntplsql/src/c12keypredictivesearchtable.cpp
phonebookengines/contactsmodel/cntplsql/src/cntpredictivesearch.cpp
phonebookengines/contactsmodel/cntplsql/src/cntsqlsearch.cpp
phonebookengines/contactsmodel/cntplsql/src/cpcskeymap.cpp
phonebookengines/contactsmodel/cntplsql/src/cpplcontacttable.cpp
phonebookengines/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp
phonebookengines/contactsmodel/cntplsql/src/cpredictivesearchsettingstable.cpp
phonebookengines/contactsmodel/cntplsql/src/cpredictivesearchsynchronizer.cpp
phonebookengines/contactsmodel/cntplsql/src/cqwertykeymap.cpp
phonebookengines/contactsmodel/cntplsql/src/cqwertypredictivesearchtable.cpp
phonebookengines/contactsmodel/cntplsql/src/csqlitelocalview.cpp
phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp
phonebookengines/contactsmodel/cntsrv/inc/CCntFileManagerMsgHandler.h
phonebookengines/contactsmodel/cntsrv/inc/CCntIpcCodes.h
phonebookengines/contactsmodel/cntsrv/src/CCntFileManagerMsgHandler.cpp
phonebookengines/contactsmodel/cntsrv/src/CCntServer.cpp
phonebookengines/contactsmodel/cntsrv/src/CCntStateMachine.cpp
phonebookengines/contactsmodel/contactsmodel.pro
phonebookengines/contactsmodel/eabi/cntplsqlU.def
phonebookengines/contactsmodel/group/CNTSRV.MMP
phonebookengines/contactsmodel/group/COMMON.INF
phonebookengines/contactsmodel/groupsql/cntplsql.mmp
phonebookengines/contactsmodel/inc/cntpredictivesearch.h
phonebookengines/contactsmodel/tsrc/cntplsql/group/t_cntplsql.mmp
phonebookengines/contactsmodel/tsrc/cntplsql/src/dllmain.cpp
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.cpp
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.h
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.cpp
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.h
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpredictivesearchsettingstable.cpp
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpredictivesearchsettingstable.h
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.cpp
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.h
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.cpp
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.h
phonebookengines/contactsmodel/tsrc/cntplsql/src/t_predictivesearchtabledefs.h
phonebookengines/contactsmodel/tsrc/cntplsql_qt/main.cpp
phonebookengines/contactsmodel/tsrc/cntplsql_qt/runtest.cmd
phonebookengines/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.cpp
phonebookengines/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.h
phonebookengines/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.pro
phonebookengines/eabi/cntlistmodelu.def
phonebookengines/eabi/cntmaptileserviceu.def
phonebookengines/eabi/cntsimutilityu.def
phonebookengines/phonebookengines.pro
phonebookui/bwins/cnthistorymodelu.def
phonebookui/bwins/pbkcommonuiu.def
phonebookui/cnthistorymodel/cnthistorymodel.pro
phonebookui/cnthistorymodel/inc/cnthistorymodel.h
phonebookui/cnthistorymodel/inc/cnthistorymodel_p.h
phonebookui/cnthistorymodel/src/cnthistorymodel.cpp
phonebookui/cnthistorymodel/tsrc/mt_cnthistorymodel/mt_cnthistorymodel.pro
phonebookui/conf/contacts.confml
phonebookui/conf/contacts_2002FF54.crml
phonebookui/conf/contacts_200315A8.crml
phonebookui/eabi/cnthistorymodelu.def
phonebookui/eabi/pbkcommonuiu.def
phonebookui/inc/cntdebug.h
phonebookui/inc/cntglobal.h
phonebookui/pbkcommonui/inc/cntaddressmodel.h
phonebookui/pbkcommonui/inc/cntaddressviewitem.h
phonebookui/pbkcommonui/inc/cntbaseselectionview.h
phonebookui/pbkcommonui/inc/cntcollectionlistmodel.h
phonebookui/pbkcommonui/inc/cntcommondetailviewitem.h
phonebookui/pbkcommonui/inc/cntcontactcarddatacontainer.h
phonebookui/pbkcommonui/inc/cntcontactcarddataitem.h
phonebookui/pbkcommonui/inc/cntcontactcarddetailitem.h
phonebookui/pbkcommonui/inc/cntcontactcardheadingitem.h
phonebookui/pbkcommonui/inc/cntcontactcardview_p.h
phonebookui/pbkcommonui/inc/cntdateeditorviewitem.h
phonebookui/pbkcommonui/inc/cntdefaultviewmanager.h
phonebookui/pbkcommonui/inc/cntdetaileditor.h
phonebookui/pbkcommonui/inc/cntdetaileditormodel.h
phonebookui/pbkcommonui/inc/cntdetailorderinghelper.h
phonebookui/pbkcommonui/inc/cnteditview_p.h
phonebookui/pbkcommonui/inc/cnteditviewheadingitem.h
phonebookui/pbkcommonui/inc/cnteditviewlistmodel.h
phonebookui/pbkcommonui/inc/cntemaileditormodel.h
phonebookui/pbkcommonui/inc/cntemaileditorviewitem.h
phonebookui/pbkcommonui/inc/cntfetchcontactsview.h
phonebookui/pbkcommonui/inc/cntgroupdeletepopup.h
phonebookui/pbkcommonui/inc/cntgroupeditormodel.h
phonebookui/pbkcommonui/inc/cntgroupmemberview.h
phonebookui/pbkcommonui/inc/cntimageeditorview.h
phonebookui/pbkcommonui/inc/cntimportsview.h
phonebookui/pbkcommonui/inc/cntmycardview.h
phonebookui/pbkcommonui/inc/cntnamesview_p.h
phonebookui/pbkcommonui/inc/cntnoteeditormodel.h
phonebookui/pbkcommonui/inc/cntnoteeditorviewitem.h
phonebookui/pbkcommonui/inc/cntphonenumbermodel.h
phonebookui/pbkcommonui/inc/cntphonenumberviewitem.h
phonebookui/pbkcommonui/inc/cntpresencelistener.h
phonebookui/pbkcommonui/inc/cntsettingsmodel.h
phonebookui/pbkcommonui/inc/cntsettingsview.h
phonebookui/pbkcommonui/inc/cntstringmapper.h
phonebookui/pbkcommonui/inc/cnturleditormodel.h
phonebookui/pbkcommonui/inc/cnturleditorviewitem.h
phonebookui/pbkcommonui/inc/qlocationpickeritem_temp.h
phonebookui/pbkcommonui/pbkcommonui.pro
phonebookui/pbkcommonui/resources/contacts_detail_editor.docml
phonebookui/pbkcommonui/resources/contacts_groupmembers.docml
phonebookui/pbkcommonui/resources/contacts_mc.docml
phonebookui/pbkcommonui/resources/contacts_namelist.docml
phonebookui/pbkcommonui/resources/pbkcommonui.qrc
phonebookui/pbkcommonui/resources/phonebook.svg
phonebookui/pbkcommonui/resources/style/cntcommondetailviewitem.css
phonebookui/pbkcommonui/resources/style/cntcommondetailviewitem.widgetml
phonebookui/pbkcommonui/src/cntaddressmodel.cpp
phonebookui/pbkcommonui/src/cntbaseselectionview.cpp
phonebookui/pbkcommonui/src/cntcollectionlistmodel.cpp
phonebookui/pbkcommonui/src/cntcollectionview.cpp
phonebookui/pbkcommonui/src/cntcommondetailviewitem.cpp
phonebookui/pbkcommonui/src/cntcompanyeditormodel.cpp
phonebookui/pbkcommonui/src/cntcontactcarddatacontainer.cpp
phonebookui/pbkcommonui/src/cntcontactcarddetailitem.cpp
phonebookui/pbkcommonui/src/cntcontactcardheadingitem.cpp
phonebookui/pbkcommonui/src/cntcontactcardview_p.cpp
phonebookui/pbkcommonui/src/cntdefaultviewmanager.cpp
phonebookui/pbkcommonui/src/cntdetaileditor.cpp
phonebookui/pbkcommonui/src/cntdetailorderinghelper.cpp
phonebookui/pbkcommonui/src/cnteditview_p.cpp
phonebookui/pbkcommonui/src/cnteditviewheadingitem.cpp
phonebookui/pbkcommonui/src/cnteditviewitembuilder.cpp
phonebookui/pbkcommonui/src/cnteditviewlistmodel.cpp
phonebookui/pbkcommonui/src/cntemaileditormodel.cpp
phonebookui/pbkcommonui/src/cntemaileditorviewitem.cpp
phonebookui/pbkcommonui/src/cntextensionmanager.cpp
phonebookui/pbkcommonui/src/cntfamilyeditormodel.cpp
phonebookui/pbkcommonui/src/cntfavoritesmemberview.cpp
phonebookui/pbkcommonui/src/cntfetchcontactsview.cpp
phonebookui/pbkcommonui/src/cntgroupdeletepopup.cpp
phonebookui/pbkcommonui/src/cntgroupdeletepopupmodel.cpp
phonebookui/pbkcommonui/src/cntgroupeditormodel.cpp
phonebookui/pbkcommonui/src/cntgroupmemberview.cpp
phonebookui/pbkcommonui/src/cnthistoryview.cpp
phonebookui/pbkcommonui/src/cntimageeditorview.cpp
phonebookui/pbkcommonui/src/cntimagelabel.cpp
phonebookui/pbkcommonui/src/cntimportsview.cpp
phonebookui/pbkcommonui/src/cntmainwindow.cpp
phonebookui/pbkcommonui/src/cntmycardview.cpp
phonebookui/pbkcommonui/src/cntnameeditormodel.cpp
phonebookui/pbkcommonui/src/cntnamesview_p.cpp
phonebookui/pbkcommonui/src/cntnoteeditormodel.cpp
phonebookui/pbkcommonui/src/cntnoteeditorviewitem.cpp
phonebookui/pbkcommonui/src/cntphonenumbermodel.cpp
phonebookui/pbkcommonui/src/cntphonenumberviewitem.cpp
phonebookui/pbkcommonui/src/cntpresencelistener.cpp
phonebookui/pbkcommonui/src/cntsettingsmodel.cpp
phonebookui/pbkcommonui/src/cntsettingsview.cpp
phonebookui/pbkcommonui/src/cnturleditormodel.cpp
phonebookui/pbkcommonui/src/cnturleditorviewitem.cpp
phonebookui/phonebookapp/phonebookapp.pro
phonebookui/phonebookapp/resources/phonebook.svg
phonebookui/phonebookservices/inc/cntservicecontactfetchview.h
phonebookui/phonebookservices/inc/cntserviceviewmanager.h
phonebookui/phonebookservices/phonebookservices.pro
phonebookui/phonebookservices/src/cntserviceassigncontactcardview.cpp
phonebookui/phonebookservices/src/cntservicecontactfetchview.cpp
phonebookui/phonebookservices/src/cntservicecontactselectionview.cpp
phonebookui/phonebookservices/src/cntservicehandler.cpp
phonebookui/phonebookservices/src/cntserviceviewmanager.cpp
phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/main.cpp
phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/qtpbkservicestestapp.pro
phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/testpbkservices.cpp
phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/testpbkservices.h
phonebookui/phonebookui.pro
phonebookui/rom/phonebook.iby
phonebookui/rom/phonebookresources.iby
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/feedview.docml
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/inc/feedview.h
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/presencefeeddemo.qrc
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/presencefeeddemo.sisx
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/presencefeeddemo_qt.pro
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/src/feedview.cpp
presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/src/main.cpp
qtcontactsmobility/config.tests/occ/occ.pro
qtcontactsmobility/config.tests/sensors_s60_31/sensors_s60_31.pro
qtcontactsmobility/plugins/contacts/symbian/inc/cntdisplaylabel.h
qtcontactsmobility/plugins/contacts/symbian/inc/filtering/cntsymbiansrvconnection.h
qtcontactsmobility/plugins/contacts/symbian/src/cntdisplaylabel.cpp
qtcontactsmobility/plugins/contacts/symbian/src/cntsymbianengine.cpp
qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntdbinfo.cpp
qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntfilterdetail.cpp
qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsqlsearch.cpp
qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsymbianfiltersql.cpp
qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsymbiansrvconnection.cpp
qtcontactsmobility/plugins/contacts/symbian/symbian.pro
qtcontactsmobility/src/versit/qversitresourcehandler.cpp
--- a/contacts_plat/contacts_ui_api/inc/cntcenrepkeys.h	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * 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:
- *
- */
-
-#ifndef CNTCENREPKEYS_H
-#define CNTCENREPKEYS_H
-
-#include <e32def.h>
-
-const TUid KCRUiContacts = {0x2002FF54};
-
-const TUint32 KNameOrdering = 0x00000001;
-
-#endif // CNTCENREPKEYS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contacts_plat/contacts_ui_api/inc/cntuids.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,42 @@
+/*
+ * 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:
+ *
+ */
+
+#ifndef CNTUIDS_H
+#define CNTUIDS_H
+
+#include <e32def.h>
+#include <e32cmn.h>
+
+/*
+*   Contacts application's central repository Uid used for global settings
+*/
+const TUid KCRUiContacts = {0x2002FF54};
+
+/*
+*   Key value used to store the name ordering setting i.e
+*   FirstName LastName, LastName FirstName etc
+*/
+const TUint32 KCntNameOrdering = 0x00000001;
+
+// name order enumerations
+enum CntNameOrder {
+    CntOrderLastFirst = 0x0,
+    CntOrderLastCommaFirst = 0x1,
+    CntOrderFirstLast = 0x2
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contacts_plat/presence_cache_api/tsrc/mt_preseceqt/entitytests.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,644 @@
+/*
+* Copyright (c) 2007, 2008 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:  Implementation for presence cache reader and writer.
+*
+*/
+
+#include "entitytests.h"
+#include <stdio.h>
+#include <qtest.h>
+#include <QObject>
+#include <prcpresencebuddyinfo_qt.h>
+#include <prcpresencereader_qt.h>
+#include <prcpresencewriter_qt.h>
+
+    QString EntityTests::K_Buddy = "Buddy";
+    QString EntityTests::K_Atext = "Atext";
+    QString EntityTests::K_Avalue = "Avalue";
+    QString EntityTests::K_Newkey = "Newkey";
+    QString EntityTests::K_Newvalue = "Newvalue";
+    QString EntityTests::K_Avatar = "Avatar";
+    QString EntityTests::K_Statustext =  "Statustext";
+    
+const int waitTime = 500;
+EntityTests::EntityTests(QObject *parent) :
+    QObject(parent)
+{
+   
+}
+
+void EntityTests::initTestCase()
+{
+    iWriter = NULL;
+    iReader = NULL;
+ 
+}
+
+void EntityTests::cleanupTestCase()
+{
+  delete iReader;
+  delete iWriter;
+}
+
+// -----------------------------------------------------------------------------
+// ClientSrvTester::SaveBuddyL
+// 
+// -----------------------------------------------------------------------------
+//
+void EntityTests::saveBuddy(QMap<QString,QString>& map)
+    {
+    PrcPresenceBuddyInfoQt* buddy = createBuddyForWriting(map);
+    iWriter->writePresence( *buddy ); 
+    }
+
+
+PrcPresenceBuddyInfoQt* EntityTests::createBuddyForWriting(QMap<QString,QString>& map)
+{
+    QString buddyId = map.value(K_Buddy);
+    QString AText = map.value(K_Atext);
+    QString AValue = map.value(K_Avalue); 
+    QString avatar = map.value(K_Avatar);
+    QString statusText = map.value(K_Statustext);
+      
+    QString newKey = map.value(K_Newkey);
+    QString newValue = map.value(K_Newvalue);
+     
+    // TInt avValue = TesterAtoi( AValue );
+    PrcPresenceBuddyInfoQt::AvailabilityValues intAval = getAvailbility(AText)     ;
+    
+    if ( !iWriter )
+        {
+        iWriter = PrcPresenceWriter::createWriter();
+        }
+        
+    PrcPresenceBuddyInfoQt* buddy = PrcPresenceBuddyInfoQt::createInstance();
+    
+    // Another way to initiate buddy info
+    // -------------------------------------
+    PrcPresenceBuddyInfoQt* buddy2 = iWriter->newBuddyPresenceInfo();
+    delete buddy2;
+    buddy2 = NULL;    
+    // -------------------------------------
+    buddy->setIdentity( buddyId );
+    buddy->setAvailability( intAval, AText);
+
+    if ( statusText.length() )
+        {
+        buddy->setStatusMessage( statusText);
+        }
+    if ( newKey.length() || newValue.length())
+        {
+        buddy->setAnyField( newKey, newValue );
+        } 
+    if(avatar.length())
+        {
+        buddy->setAvatar(avatar);
+        }
+    return buddy;
+}
+PrcPresenceBuddyInfoQt::AvailabilityValues EntityTests::getAvailbility(QString aval)
+    {
+    if(aval == "available")
+        return PrcPresenceBuddyInfoQt::PrcAvailable;
+    else if(aval == "busy")
+        return PrcPresenceBuddyInfoQt::PrcBusy;
+    else if(aval == "notavailable")
+           return PrcPresenceBuddyInfoQt::PrcNotAvailable;
+      
+    else return PrcPresenceBuddyInfoQt::PrcUnknownAvailability;
+    
+    }
+void EntityTests::fetchAndVerifyBuddy( QMap<QString,QString>& map )
+    {
+   
+    QString buddyId = map.value(K_Buddy);
+    QString AText = map.value(K_Atext);
+    QString AValue = map.value(K_Avalue);;
+    QString avatar = map.value(K_Avatar);
+    QString statusText = map.value(K_Statustext);
+  QString newKey = map.value(K_Newkey);
+    QString newValue = map.value(K_Newvalue);
+
+    PrcPresenceBuddyInfoQt::AvailabilityValues intAval = getAvailbility (AText)    ;   
+  
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+    
+    PrcPresenceBuddyInfoQt* buddy = iReader->presenceInfo(buddyId);   
+    QString testbuddyId = buddy->buddyId();
+    QVERIFY(testbuddyId == buddyId);
+    
+    PrcPresenceBuddyInfoQt::AvailabilityValues testavalibility = buddy->availability();
+    QVERIFY (testavalibility == intAval );
+    QString testAvalText =  buddy->availabilityText();
+    QVERIFY( testAvalText ==AText );
+    if ( statusText.length())
+        {
+        QString testStatusMsg = buddy->statusMessage();
+        QVERIFY (testStatusMsg== statusText );
+            
+        }  
+    if ( newKey.length() || newValue.length())
+        {
+        QString testnewVal = buddy->getAnyField( newKey );
+        QVERIFY ( testnewVal== newValue );
+        }
+    
+    if(avatar.length())
+    {
+    QString atr = buddy->avatar();
+    }
+    
+   }
+
+void  EntityTests::subscribeBuddy( QString& buddyId)
+{
+    
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+           
+    int error = iReader->subscribePresenceBuddyChange(buddyId);
+}
+void  EntityTests::unSubscribeBuddy( QString& buddyId)
+{
+    
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+           
+    iReader->unSubscribePresenceBuddyChange(buddyId);
+}
+void EntityTests::CheckServices(int nbrServices,int nbrBuddies)
+    {
+    int  val = 0;    
+    
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+    
+    val = iReader->servicesCount();
+    QVERIFY ( val == nbrServices );
+            
+    val = iReader->buddyCountInAllServices();
+    QVERIFY( val == nbrBuddies );
+            
+    }
+void  EntityTests::CheckOneService(QString service,int buddiesInService)
+    {
+    // Services: x Buddies: 0 BuddiesInService: 0 Service: sip
+
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+    
+    int val = iReader->buddyCountInService( service );
+    QVERIFY( val == buddiesInService );
+    
+    }
+
+void EntityTests::fetchAllBuddiesInService(QString service, int numberofbuddies  )
+{
+
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+    iNumberOfBuddiesInService = numberofbuddies;
+    TInt ret = iReader->allBuddiesPresenceInService(service);
+}
+// Save and Fetch
+void EntityTests::test1()
+    {
+    QMap<QString,QString> map;
+    map.insert(K_Buddy,"sip:tester1@test.com");
+    map.insert(K_Atext,"avaifsslable");
+    map.insert(K_Avalue,"ONLIsfsNE");
+    map.insert(K_Newkey,"x-locfsdfation");
+    map.insert(K_Avatar,"caland");
+    map.insert(K_Newvalue,"kitfsdschen");
+    saveBuddy(map);
+    fetchAndVerifyBuddy(map);
+    
+    
+    
+    //Some other tests
+    PrcPresenceBuddyInfoQt* buddy = iReader->presenceInfo("sip:tester1@test.com"); 
+    
+    //Equals identity test 
+    PrcPresenceBuddyInfoQt* buddy2 = iReader->presenceInfo("sip:tester1@test.com"); 
+    bool ret = buddy->equalsIdentity(*buddy2);
+    QVERIFY(true == ret);
+    QList<QString> qtKeyList;
+    buddy->getFieldKeys(qtKeyList);
+    int cnt = qtKeyList.count();
+    if(cnt > 0)
+        {
+        QString keyval = qtKeyList.at(0);
+        buddy->removeField(keyval);
+        }
+        
+    qtKeyList.clear();
+    buddy->getFieldKeys(qtKeyList);
+    if(cnt > 0)
+        {
+        QVERIFY((qtKeyList.count() )== (cnt - 1  )  );
+        }
+    
+
+ 
+    delete buddy;
+    delete buddy2;
+    
+    }
+// Save and Subscribe
+void EntityTests::test2()
+    {
+    connect(iReader, SIGNAL(signalPresenceNotification(bool , PrcPresenceBuddyInfoQt* )), 
+                       this, SLOT(handlePresenceNotificationInClient(bool , PrcPresenceBuddyInfoQt* )));
+      connect(iReader, SIGNAL(signalPresenceRead(bool , QList<PrcPresenceBuddyInfoQt*> )), 
+                      this, SLOT( handlePresenceReadInClient(bool,QList<PrcPresenceBuddyInfoQt*>)));
+
+    QString testBuddyID = "sip:tester1@test.com";
+    iMapDataForAsyncTest.clear();
+    iMapDataForAsyncTest.insert(K_Buddy,testBuddyID);
+    iMapDataForAsyncTest.insert(K_Atext,"available");
+    iMapDataForAsyncTest.insert(K_Avalue,"OFFLINE");
+    iMapDataForAsyncTest.insert(K_Newkey,"x-location");
+    iMapDataForAsyncTest.insert(K_Newvalue,"garden");
+    saveBuddy(iMapDataForAsyncTest);
+    
+    subscribeBuddy(testBuddyID);
+    //change some data
+    iMapDataForAsyncTest.remove(K_Avalue);
+    iMapDataForAsyncTest.remove(K_Newvalue);
+    iMapDataForAsyncTest.insert(K_Avalue,"ON_THE_LINE");
+    iMapDataForAsyncTest.insert(K_Newvalue,"atdoor");
+    saveBuddy(iMapDataForAsyncTest);
+    QTest::qWait(waitTime);
+
+    
+    }
+
+//Subscribe and Update partly
+void EntityTests::test3()
+    {
+    connect(iReader, SIGNAL(signalPresenceNotification(bool , PrcPresenceBuddyInfoQt* )), 
+                           this, SLOT(handlePresenceNotificationInClient(bool , PrcPresenceBuddyInfoQt* )));
+    connect(iReader, SIGNAL(signalPresenceRead(bool , QList<PrcPresenceBuddyInfoQt*> )), 
+                           this, SLOT( handlePresenceReadInClient(bool,QList<PrcPresenceBuddyInfoQt*>)));
+    QString testBuddyID = "sip:tester1@test.com";
+     iNotificationReceived = false;
+    //Subscribe
+    subscribeBuddy(testBuddyID);
+    //Now save and check if notification is received
+    iMapDataForAsyncTest.clear();
+    iMapDataForAsyncTest.insert(K_Buddy,testBuddyID);
+    iMapDataForAsyncTest.insert(K_Atext,"available");
+    iMapDataForAsyncTest.insert(K_Avalue,"In Transit");
+    iMapDataForAsyncTest.insert(K_Newkey,"Y-location");
+    iMapDataForAsyncTest.insert(K_Newvalue,"Gate");
+    iMapDataForAsyncTest.insert(K_Statustext,"engaged");
+    saveBuddy(iMapDataForAsyncTest);
+    QTest::qWait(waitTime);
+    QVERIFY(true == iNotificationReceived);
+    
+    }
+
+// Subscribe , save, and Unsubscribe ,save
+void EntityTests::test4()
+    {
+
+    connect(iReader, SIGNAL(signalPresenceNotification(bool , PrcPresenceBuddyInfoQt* )), 
+                           this, SLOT(handlePresenceNotificationInClient(bool , PrcPresenceBuddyInfoQt* )));
+    connect(iReader, SIGNAL(signalPresenceRead(bool , QList<PrcPresenceBuddyInfoQt*> )), 
+                          this, SLOT( handlePresenceReadInClient(bool,QList<PrcPresenceBuddyInfoQt*>)));
+    QString testBuddyID = "sip:tester1@test.com";
+     iNotificationReceived = false;
+    //Subscribe
+    subscribeBuddy(testBuddyID);
+    //Now save and check if notification is received
+    iMapDataForAsyncTest.clear();
+    iMapDataForAsyncTest.insert(K_Buddy,testBuddyID);
+    iMapDataForAsyncTest.insert(K_Atext,"available");
+    iMapDataForAsyncTest.insert(K_Avalue,"In Transit");
+    iMapDataForAsyncTest.insert(K_Newkey,"Y-location");
+    iMapDataForAsyncTest.insert(K_Newvalue,"Gate");
+    iMapDataForAsyncTest.insert(K_Statustext,"engaged");
+    //Save the data to cache
+    saveBuddy(iMapDataForAsyncTest);
+    //We should recive notification after save
+    QTest::qWait(waitTime);
+    QVERIFY(true == iNotificationReceived);
+    
+    //Unsubscribe 
+    unSubscribeBuddy(testBuddyID);
+    //change some data and re-save
+    iNotificationReceived = false;
+    iMapDataForAsyncTest.remove(K_Atext);
+    iMapDataForAsyncTest.insert(K_Atext,"UN_available");
+    saveBuddy(iMapDataForAsyncTest);
+    
+    //We should not recive notification since we have unsubscribed
+    QTest::qWait(waitTime);
+    QVERIFY(false == iNotificationReceived);
+    
+    
+    }
+//title Subscribe and delete reader
+void EntityTests::test5()
+    {
+
+    connect(iReader, SIGNAL(signalPresenceNotification(bool , PrcPresenceBuddyInfoQt* )), 
+                           this, SLOT(handlePresenceNotificationInClient(bool , PrcPresenceBuddyInfoQt* )));
+    connect(iReader, SIGNAL(signalPresenceRead(bool , QList<PrcPresenceBuddyInfoQt*> )), 
+                          this, SLOT( handlePresenceReadInClient(bool,QList<PrcPresenceBuddyInfoQt*>)));
+    QString testBuddyID = "sip:tester1@test.com";
+     iNotificationReceived = false;
+    //Subscribe
+    subscribeBuddy(testBuddyID);
+    //Now save and check if notification is received
+    iMapDataForAsyncTest.clear();
+    iMapDataForAsyncTest.insert(K_Buddy,testBuddyID);
+    iMapDataForAsyncTest.insert(K_Atext,"available");
+    iMapDataForAsyncTest.insert(K_Avalue,"In Home ");
+    iMapDataForAsyncTest.insert(K_Newkey,"x-location");
+    iMapDataForAsyncTest.insert(K_Newvalue,"Restaurant");
+    iMapDataForAsyncTest.insert(K_Statustext,"Working hard");
+    //Save the data to cache
+    saveBuddy(iMapDataForAsyncTest);
+    //We should recive notification after save
+    QTest::qWait(waitTime);
+    QVERIFY(true == iNotificationReceived);
+    
+    //Unsubscribe 
+    if(iReader)
+        {
+        delete iReader;
+        iReader = NULL;
+        }
+    
+    //change some data and re-save
+    iNotificationReceived = false;
+    iMapDataForAsyncTest.remove(K_Atext);
+    iMapDataForAsyncTest.insert(K_Atext,"UN_available");
+    saveBuddy(iMapDataForAsyncTest);
+    
+    //We should not recive notification since we have unsubscribed
+    QTest::qWait(waitTime);
+    QVERIFY(false == iNotificationReceived);
+    
+    
+    }
+
+// Write multiple presence
+
+void EntityTests::test6()
+    {
+    connect(iWriter, SIGNAL(signalPresenceWrite(bool)), 
+            this, SLOT(handlePresencewriteInclient(bool)));
+    QMap<QString,QString> map1;
+    map1.insert(K_Buddy,"sip:tester1@test.com");
+    map1.insert(K_Atext,"available");
+    map1.insert(K_Avalue,"ONLINE");
+    map1.insert(K_Newkey,"x-location");
+    map1.insert(K_Newvalue,"kitchen");
+    
+    QMap<QString,QString> map2;
+    map2.insert(K_Buddy,"sip:tester2@test.com");
+    map2.insert(K_Atext,"huh");
+    map2.insert(K_Avalue,"BUSY");
+    map2.insert(K_Newkey,"x-location");
+    map2.insert(K_Newvalue,"outdoor");
+        
+    PrcPresenceBuddyInfoQt* buddy1 = createBuddyForWriting(map1);
+    PrcPresenceBuddyInfoQt* buddy2 = createBuddyForWriting(map2);
+    iNotificationReceived = false;
+    QList<PrcPresenceBuddyInfoQt*> multipleBuddy;
+    multipleBuddy.append(buddy1);
+    multipleBuddy.append(buddy2);
+    if ( !iWriter )
+        {
+        iWriter = PrcPresenceWriter::createWriter();
+        }
+      
+    iWriter->writeMultiplePresence(multipleBuddy);
+    QTest::qWait(waitTime);
+    QVERIFY(true == iNotificationReceived);
+        
+    //write and cancel by deleting the writer
+    iNotificationReceived = false;
+    iWriter->writeMultiplePresence(multipleBuddy);
+    iWriter->cancelWrite();
+    QTest::qWait(waitTime);
+    QVERIFY(false == iNotificationReceived);
+        
+    }
+
+//Check services count
+void EntityTests::test7()
+    {
+    //Delete previously created services
+    if ( !iWriter )
+      {
+      iWriter = PrcPresenceWriter::createWriter();
+      }
+    iWriter->deleteService("sip");
+    QMap<QString,QString> map1;
+    map1.insert(K_Buddy,"sip:tester1@test.com");
+    map1.insert(K_Atext,"available");
+    map1.insert(K_Avalue,"ONLINE");
+    map1.insert(K_Newkey,"x-location");
+    map1.insert(K_Newvalue,"kitchen");
+    
+    QMap<QString,QString> map2;
+    map2.insert(K_Buddy,"msn:tester2@test.com");
+    map2.insert(K_Atext,"huh");
+    map2.insert(K_Avalue,"BUSY");
+    map2.insert(K_Newkey,"x-location");
+    map2.insert(K_Newvalue,"outdoor");
+    
+    QMap<QString,QString> map3;
+    map3.insert(K_Buddy,"msn:t2@test.com");
+    map3.insert(K_Atext,"huh");
+    map3.insert(K_Avalue,"BUSY");
+    map3.insert(K_Newkey,"x-location");
+    map3.insert(K_Newvalue,"outdoor");
+    saveBuddy(map1);
+    saveBuddy(map2);
+    saveBuddy(map3);
+    
+    CheckServices(2,3);
+    CheckOneService( "sip",1);
+    CheckOneService("msn",2);
+    if ( !iWriter )
+          {
+          iWriter = PrcPresenceWriter::createWriter();
+          }
+    bool ret = iWriter->deletePresence("msn:t2@test.com");
+    QVERIFY(true == ret);
+    ret = iWriter->deletePresence("msn:tester2@test.com");
+    QVERIFY(true == ret);
+    ret = iWriter->deletePresence("sip:tester1@test.com");
+    QVERIFY(true == ret);
+    }
+void EntityTests::test8()
+    {
+    connect(iReader, SIGNAL(signalPresenceRead(bool , QList<PrcPresenceBuddyInfoQt*> )), 
+               this, SLOT(handlePresenceReadInClient(bool , QList<PrcPresenceBuddyInfoQt*> )));
+
+    //Delete previously created services
+    if ( !iWriter )
+      {
+      iWriter = PrcPresenceWriter::createWriter();
+      }
+    iWriter->deleteService("sip");
+    iWriter->deleteService("msn");
+
+    QMap<QString,QString> map1;
+    map1.insert(K_Buddy,"yahoo:tester123@test.com");
+    map1.insert(K_Atext,"available");
+    map1.insert(K_Avalue,"ONLINE");
+    map1.insert(K_Newkey,"x-location");
+    map1.insert(K_Newvalue,"kitchen");
+    
+    QMap<QString,QString> map2;
+    map2.insert(K_Buddy,"msn:tester232@test.com");
+    map2.insert(K_Atext,"huh");
+    map2.insert(K_Avalue,"BUSY");
+    map2.insert(K_Newkey,"x-location");
+    map2.insert(K_Newvalue,"outdoor");
+    
+    QMap<QString,QString> map3;
+    map3.insert(K_Buddy,"yahoo:tester2@test.com");
+    map3.insert(K_Atext,"huh");
+    map3.insert(K_Avalue,"BUSY");
+    map3.insert(K_Newkey,"x-location");
+    map3.insert(K_Newvalue,"outdoor");
+
+    QMap<QString,QString> map4;
+    map4.insert(K_Buddy,"yahoo:tester322@test.com");
+    map4.insert(K_Atext,"huh");
+    map4.insert(K_Avalue,"FREE");
+    map4.insert(K_Newkey,"x-location");
+    map4.insert(K_Newvalue,"kitchen");
+    
+    saveBuddy(map1);
+    saveBuddy(map2);
+    saveBuddy(map3);
+    saveBuddy(map4);
+    iNumberOfBuddiesInService = -1;
+    
+    iBuddiesInService.append("yahoo:tester123@test.com");
+    iBuddiesInService.append("yahoo:tester2@test.com");
+    iBuddiesInService.append("yahoo:tester322@test.com");
+    iNotificationReceived = false;
+    fetchAllBuddiesInService("yahoo",3);
+    QTest::qWait(waitTime);
+    QVERIFY(true == iNotificationReceived);
+    
+    //Fetch and cancel by deleting the object
+    iNotificationReceived = false;
+    fetchAllBuddiesInService("yahoo",3);
+    bool ret = iReader->cancelRead();
+    QVERIFY(true == ret);
+    QTest::qWait(waitTime);
+    QVERIFY(false == iNotificationReceived);
+    
+    //Delete reader and writer
+    delete iReader;
+    iReader = NULL;
+    delete iWriter;
+    iWriter = NULL;
+    
+    
+    }
+void EntityTests::handlePresenceNotificationInClient(bool success, PrcPresenceBuddyInfoQt* aPresenceBuddyInfo)
+    {
+
+    if(true == success)
+        {
+        iNotificationReceived = true;
+        }
+    QString buddyId = iMapDataForAsyncTest.value(K_Buddy);
+    QString AText = iMapDataForAsyncTest.value(K_Atext);
+    QString AValue = iMapDataForAsyncTest.value(K_Avalue);;
+    QString avatar = iMapDataForAsyncTest.value(K_Avatar);
+    QString statusText = iMapDataForAsyncTest.value(K_Statustext);
+  QString newKey = iMapDataForAsyncTest.value(K_Newkey);
+    QString newValue = iMapDataForAsyncTest.value(K_Newvalue);
+
+    PrcPresenceBuddyInfoQt::AvailabilityValues intAval = getAvailbility (AText);   
+  
+    if ( !iReader )
+        {
+        iReader = PrcPresenceReader::createReader();
+        }
+    
+    
+    QString testbuddyId = aPresenceBuddyInfo->buddyId();
+    QVERIFY(testbuddyId == buddyId);
+    
+    PrcPresenceBuddyInfoQt::AvailabilityValues testavalibility = aPresenceBuddyInfo->availability();
+    QVERIFY (testavalibility == intAval );
+    QString testAvalText =  aPresenceBuddyInfo->availabilityText();
+    QVERIFY( testAvalText ==AText );
+    if ( statusText.length())
+        {
+        QString testStatusMsg = aPresenceBuddyInfo->statusMessage();
+        QVERIFY (testStatusMsg== statusText );
+            
+        }  
+    if ( newKey.length() || newValue.length())
+        {
+        QString testnewVal = aPresenceBuddyInfo->getAnyField( newKey );
+        QVERIFY ( testnewVal== newValue );
+        }
+    
+
+   
+    }
+void EntityTests::handlePresenceReadInClient(bool success, QList<PrcPresenceBuddyInfoQt*> buddyInfoList)
+{
+   int cnt = buddyInfoList.count(); 
+   QVERIFY(iNumberOfBuddiesInService == cnt );
+   if(true == success)
+       {
+       iNotificationReceived = true;
+       }
+   for(int i = 0 ; i< cnt ; i++)
+       {
+       PrcPresenceBuddyInfoQt* tempbuddy = buddyInfoList.at(i);
+       QString identity = tempbuddy->buddyId();
+       bool isPresent = iBuddiesInService.contains(identity);
+       QVERIFY(true == isPresent);
+       iBuddiesInService.removeOne(identity);
+       }
+    
+}
+void EntityTests::handlePresencewriteInclient(bool success)
+    
+    {
+    if(success == true)
+        {
+        iNotificationReceived = true;
+        }
+    
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contacts_plat/presence_cache_api/tsrc/mt_preseceqt/entitytests.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2007, 2008 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:  Implementation for presence cache reader and writer.
+*
+*/
+
+#ifndef __ENTITY_TESTS_H__
+#define __ENTITY_TESTS_H__
+
+#include <QObject>
+#include <QMap>
+#include <prcpresencebuddyinfo_qt.h>
+
+
+class PrcPresenceReader;
+class PrcPresenceWriter;
+class EntityTests : public QObject
+{
+Q_OBJECT
+public:
+    explicit EntityTests(QObject *parent = 0);
+
+    
+
+private slots:  // Init & cleanup
+        void initTestCase();
+        void cleanupTestCase();
+        void test1();
+        void test2();
+        void test3();
+        void test4();
+        void test5();
+        void test6();
+        void test7();
+        void test8();
+
+private:
+        void saveBuddy(QMap<QString,QString>& map);
+        void fetchAndVerifyBuddy( QMap<QString,QString>& map );
+        void  subscribeBuddy( QString &buddyId);
+        void  unSubscribeBuddy( QString &buddyId);
+        PrcPresenceBuddyInfoQt* createBuddyForWriting(QMap<QString,QString>& map);
+        void CheckServices(int nbrServices,int nbrBuddies);
+        void CheckOneService(QString service,int buddiesInService);
+
+        PrcPresenceBuddyInfoQt::AvailabilityValues getAvailbility(QString aval);
+        void fetchAllBuddiesInService(QString service, int numberofbuddies  );
+
+public slots:
+void handlePresenceNotificationInClient(bool succcess, PrcPresenceBuddyInfoQt* aPresenceBuddyInfo);
+void handlePresenceReadInClient(bool success, QList<PrcPresenceBuddyInfoQt*> buddyInfoList);
+void handlePresencewriteInclient(bool success);
+
+private: //data
+        PrcPresenceWriter* iWriter;
+        PrcPresenceReader* iReader;
+private:
+
+   static QString K_Buddy ;
+   static QString K_Atext ;
+   static QString K_Avalue ;
+   static QString K_Newkey ;
+   static QString K_Newvalue ;
+   static QString K_Avatar ;
+   static  QString K_Statustext ;
+   QMap<QString,QString> iMapDataForAsyncTest;
+   bool iNotificationReceived ;
+   int iNumberOfBuddiesInService;
+   QList <QString> iBuddiesInService;
+};
+
+#endif // __ENTITY_TESTS_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contacts_plat/presence_cache_api/tsrc/mt_preseceqt/mt_preseceqt.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,45 @@
+#
+# 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:
+#
+#
+
+
+TEMPLATE = app
+TARGET = mt_preseceqt
+QT += testlib network webkit xmlpatterns
+CONFIG += mobility
+DEFINES += CNT_SOC_ENG_UNIT_TEST
+
+TARGET.CAPABILITY = ALL -TCB
+
+DEPENDPATH += .
+INCLUDEPATH += .
+load(data_caging_paths)
+
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
+INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+INCLUDEPATH +=   ..\..\..\\presence_cache_api\inc
+INCLUDEPATH +=   ..\..\inc
+
+HEADERS +=    entitytests.h
+    
+SOURCES +=  start.cpp \ 
+            entitytests.cpp 
+    
+QT += sql
+ 
+LIBS += -lpresencecacheqt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contacts_plat/presence_cache_api/tsrc/mt_preseceqt/start.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2007, 2008 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:  Implementation for presence cache reader and writer.
+*
+*/
+#include "entitytests.h"
+#include <qtest.h>
+#include <stdio.h>
+
+#include <qdebug.h>
+#include <qsqldatabase.h>
+#include <qfile.h>
+
+
+//QTEST_MAIN(TestOfTest);
+int main(int argc, char *argv[])
+{
+    bool promptOnExit(0);
+    for (int i=0; i<argc; i++) {
+        if (QString(argv[i]) == "-noprompt")
+            promptOnExit = false;
+    }
+    printf("Running tests...\n");
+
+    QApplication app(argc, argv);
+
+    QString entityTestsFileName = "c:/testPresence_qt.xml";
+   
+    QStringList args( "entitytests");
+    args << "-xml" << "-o" << entityTestsFileName;
+    EntityTests et;
+    QTest::qExec(&et, args);
+
+    if (promptOnExit) {
+        printf("Press any key...\n");
+        getchar();
+    }
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/cntdebug.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,409 @@
+/*
+* 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:  Trace macro declarations.
+*
+*/
+
+
+#ifndef CNTDEBUG_H
+#define CNTDEBUG_H
+
+#include <QDebug>   // QDebug
+#include <QtGlobal> // qDebug()
+
+// #define TRACK_MEMORY_LEAKS
+
+/*!
+    \def CNT_UNUSED(name)
+    \brief Declares a single variable as unused when tracing is disabled.
+
+    CNT_UNUSED allows variables (usually method parameters) to be declared as used only if
+    tracing is enabled. Without this variables that are included in trace macros, but not otherwise
+    used, would cause unused variable warnings on compilation. If tracing is enabled, CNT_UNUSED
+    has no effect.
+
+    Consider the following class method where the parameter number is not used at all, except for
+    tracing its value on entry:
+
+    \code
+    #include <cntdebug.h>
+
+    void MyClass::myMethod(int number)
+    {
+        CNT_UNUSED(number)
+        CNT_ENTRY("number =" << number)
+
+        // ...some more code where the parameter number is not used.
+
+        CNT_EXIT
+    }
+    \endcode
+
+    Compiling this method with tracing completely disabled at compile time would cause an unused
+    variable warning to be issued unless the CNT_UNUSED macro is used to declare the variable as
+    trace-only.
+
+    \param name The name of the variable to declare as unused if tracing is disabled. To mark
+    several variables as trace-only, add a separate CNT_UNUSED statement for each.
+    \sa CNT_STATIC_ENTRY_ARGS(args), CNT_ENTRY_ARGS(args).
+*/
+
+/*!
+    \def CNT_STATIC_ENTRY
+    \brief A method entry trace macro for static class methods or global functions.
+
+    Invoking CNT_STATIC_ENTRY outputs a timestamp followed by the scope in which the macro
+    was invoked and the word "entry".
+
+    CNT_STATIC_ENTRY is intended to be used as the first line of static class methods or
+    global functions. There is a corresponding exit macro, CNT_EXIT.
+
+    The following example shows proper usage of the CNT_STATIC_ENTRY macro. Assuming a class
+    has been declared with a static method that is implemented like this:
+
+    \code
+    #include <cntdebug.h>
+
+    void MyClass::myStaticMethod()
+    {
+        CNT_STATIC_ENTRY
+
+        int i = 1;
+        i++;
+
+        CNT_EXIT
+    }
+    \endcode
+
+    calling MyClass::myStaticMethod() generates output lines of the following format:
+
+    \code
+    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() entry
+    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() exit
+    \endcode
+
+    \sa CNT_STATIC_ENTRY_ARGS(args), CNT_EXIT.
+*/
+
+/*!
+    \def CNT_STATIC_ENTRY_ARGS(args)
+    \brief A method entry trace macro with arguments for static class methods or global functions.
+
+    CNT_STATIC_ENTRY_ARGS(args) is similar to CNT_STATIC_ENTRY but it allows arguments to be
+    output on the same line without needing to resort to a separate CNT_LOG_ARGS call. This is
+    especially handy for outputting the parameters of the method call.
+
+    The following example shows proper usage of the CNT_STATIC_ENTRY_ARGS(args) macro. Assuming
+    a class has been declared with a static method that is implemented like this:
+
+    \code
+    #include <QString>
+    #include <cntdebug.h>
+
+    void MyClass::myStaticMethod(const QString &text, int number)
+    {
+        CNT_STATIC_ENTRY_ARGS("text =" << text << "number =" << number);
+
+        int i = 1;
+        i++;
+
+        CNT_EXIT
+    }
+    \endcode
+
+    calling MyClass::myStaticMethod(QString("foo"), 74) generates output lines of the following
+    format:
+
+    \code
+    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) entry, text = "foo" number = 74
+    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) exit
+    \endcode
+
+    \param args Any number of arguments that can be streamed into a QTextStream, joined together
+    by the streaming operator <<.
+    \sa CNT_STATIC_ENTRY.
+*/
+
+/*!
+    \def CNT_ENTRY
+    \brief A method entry trace macro for class methods.
+
+    Invoking CNT_ENTRY outputs a timestamp followed by the scope in which the macro
+    was invoked, the word "entry" and the this pointer value of the instance invoking the
+    macro.
+
+    The this pointer value included in the debug output can help make the output more readable, as
+    it allows different instances of the same class to be distinguished from each other.
+
+    CNT_ENTRY is intended to be used as the first line of class methods. There is a corresponding
+    exit macro, CNT_EXIT.
+
+    The following example shows proper usage of the CNT_ENTRY macro. Assuming a class has been
+    declared with a non-static method that is implemented like this:
+
+    \code
+    #include <cntdebug.h>
+
+    void MyClass::myMethod()
+    {
+        CNT_ENTRY
+
+        int i = 1;
+        i++;
+
+        CNT_EXIT
+    }
+    \endcode
+
+    calling myMethod() on an instance of MyClass generates output lines of the following format:
+
+    \code
+    2009-03-25 11:00:50.171 : void MyClass::myMethod() this 0x6cdab90 entry
+    2009-03-25 11:00:50.171 : void MyClass::myMethod() exit
+    \endcode
+
+    \sa CNT_ENTRY_ARGS(args), CNT_EXIT.
+*/
+
+/*!
+    \def CNT_ENTRY_ARGS(args)
+    \brief A method entry trace macro with arguments for class methods.
+
+    CNT_ENTRY_ARGS(args) is similar to CNT_ENTRY but it allows arguments to be output on the
+    same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially
+    handy for outputting the parameters of the method call.
+
+    The following example shows proper usage of the CNT_ENTRY_ARGS(args)) macro. Assuming a
+    class has been declared with a non-static method that is implemented like this:
+
+    \code
+    #include <QString>
+    #include <cntdebug.h>
+
+    void MyClass::myMethod(const QString &text, int number)
+    {
+        CNT_ENTRY_ARGS("text =" << text << "number =" << number);
+
+        int i = 1;
+        i++;
+
+        CNT_EXIT
+    }
+    \endcode
+
+    calling myMethod(QString("foo"), 74) on an instance of MyClass generates output lines of the
+    following format:
+
+    \code
+    2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) this 0x6cdab90 entry, text = "foo" number = 74
+    2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) exit
+    \endcode
+
+    \param args Any number of arguments that can be streamed into a QTextStream, joined together
+    by the streaming operator <<.
+    \sa CNT_ENTRY, CNT_EXIT.
+*/
+
+/*!
+    \def CNT_EXIT
+    \brief A method exit trace macro for class methods or global functions.
+
+    Invoking CNT_EXIT outputs a timestamp followed by the scope in which the macro
+    was invoked and the word "exit".
+
+    CNT_EXIT is intended to be used as the last line of class methods and global functions,
+    just before the return statement, if any. There are two corresponding entry macros,
+    CNT_ENTRY and CNT_STATIC_ENTRY, depending on whether the method being traced is a
+    non-static or a static class method. CNT_EXIT makes no distinction between these two types
+    of methods and is to be used for both.
+
+    See CNT_ENTRY or CNT_STATIC_ENTRY for an example of how to use CNT_EXIT.
+
+    \sa CNT_EXIT_ARGS(args), CNT_ENTRY, CNT_STATIC_ENTRY.
+*/
+
+/*!
+    \def CNT_EXIT_ARGS(args)
+    \brief A method exit trace macro with arguments for class methods or global functions.
+
+    CNT_EXIT_ARGS(args) is similar to CNT_EXIT but it allows arguments to be output on the
+    same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially
+    handy for outputting the return value of the method call.
+
+    The following example shows proper usage of the CNT_EXIT_ARGS(args) macro. Assuming a
+    class has been declared with a static method that is implemented like this:
+
+    \code
+    #include <QString>
+    #include <cntdebug.h>
+
+    int MyClass::myStaticMethod(const QString &text)
+    {
+        CNT_STATIC_ENTRY_ARGS("text =" << text);
+
+        int length = text.length();
+
+        CNT_EXIT_ARGS("length" << length);
+
+        return length;
+    }
+    \endcode
+
+    calling MyClass::myStaticMethod(QString("foo")) generates output lines of the following format:
+
+    \code
+    2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) entry, text = "foo"
+    2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) exit, length 3
+    \endcode
+
+    Although the example above is a static method, CNT_EXIT_ARGS(args) works identically for
+    non-static class methods and global functions.
+
+    \param args Any number of arguments that can be streamed into a QTextStream, joined together
+    by the streaming operator <<.
+    \sa CNT_EXIT
+*/
+
+/*!
+    \def CNT_LOG
+    \brief A trace macro for class methods or global functions.
+
+    Invoking CNT_LOG outputs a timestamp followed by the scope in which the macro
+    was invoked and the this pointer value of the instance invoking the
+    macro.
+
+    CNT_LOG is similar to CNT_ENTRY but it is especially handy for marking calls to methods that
+    cannot fail, such as an empty constructor, without needing to resort to a separate CNT_EXIT call.
+
+    The following example shows proper usage of the CNT_LOG(args) macro. Assuming a
+    class has been declared with a static method that is implemented like this:
+
+    \code
+    #include <QString>
+    #include <cntdebug.h>
+
+    MyClass::MyClass()
+    {
+        CNT_LOG
+    }
+    \endcode
+
+    calling new MyClass() generates output lines of the following format:
+
+    \code
+    2009-03-25 13:20:36.448 : MyClass::MyClass() this 0x6cdab90
+    \endcode
+
+    \sa CNT_LOG_ARGS
+*/
+
+/*!
+    \def CNT_LOG_ARGS(args)
+    \brief A generic trace macro with arguments for class methods or global functions.
+
+    The following example shows how to produce arbitrary debug output:
+
+    \code
+    #include <QString>
+    #include <cntdebug.h>
+
+    void MyClass::myMethod()
+    {
+        CNT_ENTRY
+
+        QString myString("This is a string.");
+        int myValue = 109;
+
+        CNT_LOG_ARGS("this is a debug message, myString =" << myString << "myValue =" << myValue)
+
+        CNT_EXIT
+    }
+    \endcode
+
+    calling myMethod() on an instance of MyClass generates output lines of the following format:
+
+    \code
+    2009-03-25 13:45:22.083 : void MyClass::myMethod() this 0x6cdab90 entry
+    2009-03-25 13:45:22.083 : void MyClass::myMethod() this is a debug message, myString = "This is a string." myValue = 109
+    2009-03-25 13:45:22.083 : void MyClass::myMethod() exit
+    \endcode
+
+    Any number of arguments may be printed by chaining them together with the streaming operator
+    <<. Notice that a single space character is automatically added between each streamed
+    argument, hence the hardcoded strings in the example above, such as "myValue =", do not have
+    a space at the beginning and end of the string. This automatic space addition is a feature
+    of qDebug() streaming and cannot be disabled.
+
+    \param args Any number of arguments that can be streamed into a QTextStream, joined together
+    by the streaming operator <<.
+*/
+
+
+#ifdef _DEBUG
+    #define CNT_UNUSED(name)
+    #define CNT_STATIC_ENTRY qDebug() << __PRETTY_FUNCTION__ << "entry";
+    #define CNT_STATIC_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "entry," << args;
+    #define CNT_ENTRY qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry";
+    #define CNT_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry," << args;
+    #define CNT_EXIT qDebug() << __PRETTY_FUNCTION__ << "exit";
+    #define CNT_EXIT_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "exit," << args;
+    #define CNT_LOG qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this;
+    #define CNT_LOG_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << args;
+#else
+    #define CNT_UNUSED(name) Q_UNUSED(name)
+    #define CNT_STATIC_ENTRY
+    #define CNT_STATIC_ENTRY_ARGS(args)
+    #define CNT_ENTRY
+    #define CNT_ENTRY_ARGS(args)
+    #define CNT_EXIT
+    #define CNT_EXIT_ARGS(args)
+    #define CNT_LOG
+    #define CNT_LOG_ARGS(args)
+#endif // _DEBUG
+
+// for tracing memory leaks
+#ifdef TRACK_MEMORY_LEAKS
+    #include <hbapplication.h>
+
+    #define CNT_TRACK_QOBJECTLIFE(obj) { new CntQObjectTracker(obj, __FILE__, __LINE__); }
+    #define CNT_TRACK_QOBJECTLIVES(objects) { foreach (QObject* object, objects) new CntQObjectTracker(object, __FILE__, __LINE__); }
+
+    class CntQObjectTracker : public QObject
+    {
+        Q_OBJECT
+        public:
+            CntQObjectTracker(QObject *obj, QString fileName, int fileLine) {
+                objectName = obj->metaObject()->className();
+                createdInFile = fileName;
+                createdAtLine = fileLine;
+                connect(obj, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));
+                connect(HbApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(reportMemoryLeak()));
+            }
+        public slots:
+            void objectDestroyed() { delete this; }
+        private slots:
+            void reportMemoryLeak() { qDebug() << "MEMORY LEAK: The" << objectName << "object in" << createdInFile << "at line" << createdAtLine << "was never destroyed."; delete this; }
+        private: // functions
+            ~CntQObjectTracker() {}
+        private: // data
+            QString  objectName;
+            QString  createdInFile;
+            int      createdAtLine;
+    };
+#else
+    #define CNT_TRACK_QOBJECTLIFE(obj)
+    #define CNT_TRACK_QOBJECTLIVES(obj)
+#endif
+
+#endif // CNTDEBUG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/cntglobal.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2008-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:
+*
+*/
+
+
+#ifndef CNTGLOBAL_H
+#define CNTGLOBAL_H
+
+#include <QtGlobal>
+
+#ifdef PBK_UNIT_TEST
+#define QTPBK_EXPORT
+#else
+#ifdef BUILD_QTPBK
+#define QTPBK_EXPORT Q_DECL_EXPORT
+#else
+#define QTPBK_EXPORT Q_DECL_IMPORT
+#endif
+#endif
+
+
+// Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value>
+const QString SYMBIAN_BACKEND     = "qtcontacts:symbian:";
+const QString SIM_BACKEND         = "qtcontacts:symbiansim:";
+const QString SIM_BACKEND_ADN     = "qtcontacts:symbiansim:store=ADN";
+const QString SIM_BACKEND_SDN     = "qtcontacts:symbiansim:store=SDN";
+
+
+#endif // CNTGLOBAL_H
--- a/phonebookengines/bwins/cntlistmodelu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/bwins/cntlistmodelu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -1,8 +1,8 @@
 EXPORTS
-	?updateContactIdsArray@CntListModel@@AAEXXZ @ 1 NONAME ; void CntListModel::updateContactIdsArray(void)
-	?qt_metacall@CntListModel@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 2 NONAME ; int CntListModel::qt_metacall(enum QMetaObject::Call, int, void * *)
-	??0CntListModel@@QAE@PAVQContactManager@QtMobility@@ABVQContactFilter@2@ABV?$QList@VQContactSortOrder@QtMobility@@@@_NPAVQObject@@@Z @ 3 NONAME ; CntListModel::CntListModel(class QtMobility::QContactManager *, class QtMobility::QContactFilter const &, class QList<class QtMobility::QContactSortOrder> const &, bool, class QObject *)
-	??0CntListModel@@QAE@ABVQContactFilter@QtMobility@@ABV?$QList@VQContactSortOrder@QtMobility@@@@_NPAVQObject@@@Z @ 4 NONAME ; CntListModel::CntListModel(class QtMobility::QContactFilter const &, class QList<class QtMobility::QContactSortOrder> const &, bool, class QObject *)
+	?refreshModel@CntListModel@@AAEXXZ @ 1 NONAME ; void CntListModel::refreshModel(void)
+	?updateContactIdsArray@CntListModel@@AAEXXZ @ 2 NONAME ; void CntListModel::updateContactIdsArray(void)
+	?qt_metacall@CntListModel@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 3 NONAME ; int CntListModel::qt_metacall(enum QMetaObject::Call, int, void * *)
+	?setFilter@CntListModel@@QAEXABVQContactFilter@QtMobility@@@Z @ 4 NONAME ; void CntListModel::setFilter(class QtMobility::QContactFilter const &)
 	?indexOfContact@CntListModel@@QBE?AVQModelIndex@@ABVQContact@QtMobility@@@Z @ 5 NONAME ; class QModelIndex CntListModel::indexOfContact(class QtMobility::QContact const &) const
 	?staticMetaObject@CntListModel@@2UQMetaObject@@B @ 6 NONAME ; struct QMetaObject const CntListModel::staticMetaObject
 	?rowId@CntListModel@@ABEHABI@Z @ 7 NONAME ; int CntListModel::rowId(unsigned int const &) const
@@ -10,27 +10,29 @@
 	?rowCount@CntListModel@@UBEHABVQModelIndex@@@Z @ 9 NONAME ; int CntListModel::rowCount(class QModelIndex const &) const
 	?trUtf8@CntListModel@@SA?AVQString@@PBD0H@Z @ 10 NONAME ; class QString CntListModel::trUtf8(char const *, char const *, int)
 	?doConstruct@CntListModel@@AAEHXZ @ 11 NONAME ; int CntListModel::doConstruct(void)
-	?handleMyCardChanged@CntListModel@@IAEXABI0@Z @ 12 NONAME ; void CntListModel::handleMyCardChanged(unsigned int const &, unsigned int const &)
-	?handleRemoved@CntListModel@@IAEXABV?$QList@I@@@Z @ 13 NONAME ; void CntListModel::handleRemoved(class QList<unsigned int> const &)
+	??0CntListModel@@QAE@PAVQContactManager@QtMobility@@ABVQContactFilter@2@_NPAVQObject@@@Z @ 12 NONAME ; CntListModel::CntListModel(class QtMobility::QContactManager *, class QtMobility::QContactFilter const &, bool, class QObject *)
+	?handleChanged@CntListModel@@AAEXABV?$QList@I@@@Z @ 13 NONAME ; void CntListModel::handleChanged(class QList<unsigned int> const &)
 	?myCardStatus@CntListModel@@QBE_NXZ @ 14 NONAME ; bool CntListModel::myCardStatus(void) const
-	?initializeData@CntListModel@@AAEHXZ @ 15 NONAME ; int CntListModel::initializeData(void)
-	?data@CntListModel@@UBE?AVQVariant@@ABVQModelIndex@@H@Z @ 16 NONAME ; class QVariant CntListModel::data(class QModelIndex const &, int) const
-	?handleAdded@CntListModel@@IAEXABV?$QList@I@@@Z @ 17 NONAME ; void CntListModel::handleAdded(class QList<unsigned int> const &)
-	?dataForDisplayRole@CntListModel@@ABE?AVQVariant@@H@Z @ 18 NONAME ; class QVariant CntListModel::dataForDisplayRole(int) const
-	?handleContactInfoUpdated@CntListModel@@IAEXI@Z @ 19 NONAME ; void CntListModel::handleContactInfoUpdated(unsigned int)
-	?qt_metacast@CntListModel@@UAEPAXPBD@Z @ 20 NONAME ; void * CntListModel::qt_metacast(char const *)
-	?contact@CntListModel@@QBE?AVQContact@QtMobility@@ABVQModelIndex@@@Z @ 21 NONAME ; class QtMobility::QContact CntListModel::contact(class QModelIndex const &) const
+	?data@CntListModel@@UBE?AVQVariant@@ABVQModelIndex@@H@Z @ 15 NONAME ; class QVariant CntListModel::data(class QModelIndex const &, int) const
+	?initializeData@CntListModel@@AAEHXZ @ 16 NONAME ; int CntListModel::initializeData(void)
+	?dataForDisplayRole@CntListModel@@ABE?AVQVariant@@H@Z @ 17 NONAME ; class QVariant CntListModel::dataForDisplayRole(int) const
+	?setSortOrder@CntListModel@@AAEXXZ @ 18 NONAME ; void CntListModel::setSortOrder(void)
+	?qt_metacast@CntListModel@@UAEPAXPBD@Z @ 19 NONAME ; void * CntListModel::qt_metacast(char const *)
+	?contact@CntListModel@@QBE?AVQContact@QtMobility@@ABVQModelIndex@@@Z @ 20 NONAME ; class QtMobility::QContact CntListModel::contact(class QModelIndex const &) const
+	?handleContactInfoUpdated@CntListModel@@AAEXI@Z @ 21 NONAME ; void CntListModel::handleContactInfoUpdated(unsigned int)
 	?showMyCard@CntListModel@@QAEX_N@Z @ 22 NONAME ; void CntListModel::showMyCard(bool)
 	??_ECntListModel@@UAE@I@Z @ 23 NONAME ; CntListModel::~CntListModel(unsigned int)
 	?contactManager@CntListModel@@QBEAAVQContactManager@QtMobility@@XZ @ 24 NONAME ; class QtMobility::QContactManager & CntListModel::contactManager(void) const
-	?setFilterAndSortOrder@CntListModel@@QAEXABVQContactFilter@QtMobility@@ABV?$QList@VQContactSortOrder@QtMobility@@@@@Z @ 25 NONAME ; void CntListModel::setFilterAndSortOrder(class QtMobility::QContactFilter const &, class QList<class QtMobility::QContactSortOrder> const &)
-	?metaObject@CntListModel@@UBEPBUQMetaObject@@XZ @ 26 NONAME ; struct QMetaObject const * CntListModel::metaObject(void) const
-	?myCardId@CntListModel@@QBEIXZ @ 27 NONAME ; unsigned int CntListModel::myCardId(void) const
-	?validRowId@CntListModel@@ABE_NH@Z @ 28 NONAME ; bool CntListModel::validRowId(int) const
-	?handleChanged@CntListModel@@IAEXABV?$QList@I@@@Z @ 29 NONAME ; void CntListModel::handleChanged(class QList<unsigned int> const &)
-	?tr@CntListModel@@SA?AVQString@@PBD0@Z @ 30 NONAME ; class QString CntListModel::tr(char const *, char const *)
-	?getStaticMetaObject@CntListModel@@SAABUQMetaObject@@XZ @ 31 NONAME ; struct QMetaObject const & CntListModel::getStaticMetaObject(void)
-	??1CntListModel@@UAE@XZ @ 32 NONAME ; CntListModel::~CntListModel(void)
-	?trUtf8@CntListModel@@SA?AVQString@@PBD0@Z @ 33 NONAME ; class QString CntListModel::trUtf8(char const *, char const *)
-	?tr@CntListModel@@SA?AVQString@@PBD0H@Z @ 34 NONAME ; class QString CntListModel::tr(char const *, char const *, int)
+	?metaObject@CntListModel@@UBEPBUQMetaObject@@XZ @ 25 NONAME ; struct QMetaObject const * CntListModel::metaObject(void) const
+	?myCardId@CntListModel@@QBEIXZ @ 26 NONAME ; unsigned int CntListModel::myCardId(void) const
+	?validRowId@CntListModel@@ABE_NH@Z @ 27 NONAME ; bool CntListModel::validRowId(int) const
+	?handleRemoved@CntListModel@@AAEXABV?$QList@I@@@Z @ 28 NONAME ; void CntListModel::handleRemoved(class QList<unsigned int> const &)
+	?tr@CntListModel@@SA?AVQString@@PBD0@Z @ 29 NONAME ; class QString CntListModel::tr(char const *, char const *)
+	?getStaticMetaObject@CntListModel@@SAABUQMetaObject@@XZ @ 30 NONAME ; struct QMetaObject const & CntListModel::getStaticMetaObject(void)
+	?handleAdded@CntListModel@@AAEXABV?$QList@I@@@Z @ 31 NONAME ; void CntListModel::handleAdded(class QList<unsigned int> const &)
+	?trUtf8@CntListModel@@SA?AVQString@@PBD0@Z @ 32 NONAME ; class QString CntListModel::trUtf8(char const *, char const *)
+	??0CntListModel@@QAE@ABVQContactFilter@QtMobility@@_NPAVQObject@@@Z @ 33 NONAME ; CntListModel::CntListModel(class QtMobility::QContactFilter const &, bool, class QObject *)
+	??1CntListModel@@UAE@XZ @ 34 NONAME ; CntListModel::~CntListModel(void)
+	?tr@CntListModel@@SA?AVQString@@PBD0H@Z @ 35 NONAME ; class QString CntListModel::tr(char const *, char const *, int)
+	?handleMyCardChanged@CntListModel@@AAEXABI0@Z @ 36 NONAME ; void CntListModel::handleMyCardChanged(unsigned int const &, unsigned int const &)
 
--- a/phonebookengines/bwins/cntmaptileserviceu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/bwins/cntmaptileserviceu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -1,4 +1,20 @@
 EXPORTS
-	?getMapTileImage@CntMapTileService@@SA?AVQString@@HW4ContactAddressType@1@@Z @ 1 NONAME ; class QString CntMapTileService::getMapTileImage(int, enum CntMapTileService::ContactAddressType)
-	?isLocationFeatureEnabled@CntMapTileService@@SA_NXZ @ 2 NONAME ; bool CntMapTileService::isLocationFeatureEnabled(void)
+	?qt_metacall@CntMapTileService@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1 NONAME ; int CntMapTileService::qt_metacall(enum QMetaObject::Call, int, void * *)
+	??_ECntMapTileService@@UAE@I@Z @ 2 NONAME ; CntMapTileService::~CntMapTileService(unsigned int)
+	??0CntMapTileService@@QAE@XZ @ 3 NONAME ; CntMapTileService::CntMapTileService(void)
+	?tr@CntMapTileService@@SA?AVQString@@PBD0H@Z @ 4 NONAME ; class QString CntMapTileService::tr(char const *, char const *, int)
+	??1CntMapTileService@@UAE@XZ @ 5 NONAME ; CntMapTileService::~CntMapTileService(void)
+	?publishValue@CntMapTileService@@AAEXHW4ContactAddressType@1@H@Z @ 6 NONAME ; void CntMapTileService::publishValue(int, enum CntMapTileService::ContactAddressType, int)
+	?trUtf8@CntMapTileService@@SA?AVQString@@PBD0H@Z @ 7 NONAME ; class QString CntMapTileService::trUtf8(char const *, char const *, int)
+	?trUtf8@CntMapTileService@@SA?AVQString@@PBD0@Z @ 8 NONAME ; class QString CntMapTileService::trUtf8(char const *, char const *)
+	?qt_metacast@CntMapTileService@@UAEPAXPBD@Z @ 9 NONAME ; void * CntMapTileService::qt_metacast(char const *)
+	?isLocationFeatureEnabled@CntMapTileService@@QAE_NXZ @ 10 NONAME ; bool CntMapTileService::isLocationFeatureEnabled(void)
+	?setMaptileStatus@CntMapTileService@@QAEXXZ @ 11 NONAME ; void CntMapTileService::setMaptileStatus(void)
+	?maptileFetchingStatusUpdate@CntMapTileService@@IAEXHHH@Z @ 12 NONAME ; void CntMapTileService::maptileFetchingStatusUpdate(int, int, int)
+	?tr@CntMapTileService@@SA?AVQString@@PBD0@Z @ 13 NONAME ; class QString CntMapTileService::tr(char const *, char const *)
+	?readEntryFromMaptileDataBase@CntMapTileService@@AAEHHW4ContactAddressType@1@AAVTLookupItem@@AAH@Z @ 14 NONAME ; int CntMapTileService::readEntryFromMaptileDataBase(int, enum CntMapTileService::ContactAddressType, class TLookupItem &, int &)
+	?getMapTileImage@CntMapTileService@@QAEHHW4ContactAddressType@1@AAVQString@@@Z @ 15 NONAME ; int CntMapTileService::getMapTileImage(int, enum CntMapTileService::ContactAddressType, class QString &)
+	?getStaticMetaObject@CntMapTileService@@SAABUQMetaObject@@XZ @ 16 NONAME ; struct QMetaObject const & CntMapTileService::getStaticMetaObject(void)
+	?metaObject@CntMapTileService@@UBEPBUQMetaObject@@XZ @ 17 NONAME ; struct QMetaObject const * CntMapTileService::metaObject(void) const
+	?staticMetaObject@CntMapTileService@@2UQMetaObject@@B @ 18 NONAME ; struct QMetaObject const CntMapTileService::staticMetaObject
 
--- a/phonebookengines/bwins/cntsimutilityu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/bwins/cntsimutilityu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -25,4 +25,6 @@
 	?staticMetaObject@CntSimUtility@@2UQMetaObject@@B @ 24 NONAME ; struct QMetaObject const CntSimUtility::staticMetaObject
 	?RequestCompleted@CntSimUtility@@QAEXH@Z @ 25 NONAME ; void CntSimUtility::RequestCompleted(int)
 	??1CntSimUtility@@UAE@XZ @ 26 NONAME ; CntSimUtility::~CntSimUtility(void)
+	?getLastImportTime@CntSimUtility@@QAE?AVQDateTime@@AAH@Z @ 27 NONAME ; class QDateTime CntSimUtility::getLastImportTime(int &)
+	?setLastImportTime@CntSimUtility@@QAEXAAH@Z @ 28 NONAME ; void CntSimUtility::setLastImportTime(int &)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntactions/tsrc/mt_cntactions/main.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,36 @@
+/*
+* 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:
+*
+*/
+
+#include "testrunner.h"
+
+#include "mt_cntactions.h"
+
+#include <QtTest/QtTest>
+
+int main(int argc, char *argv[]) 
+{ 
+    QApplication app(argc, argv);
+    
+    TestRunner testRunner("mt_cntactions");
+    
+    TestCntActions cntActionsTest;
+    testRunner.runTests( cntActionsTest );
+    
+    testRunner.printResults();
+    return 0;   
+}
+
--- a/phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -32,7 +32,7 @@
     } while(0)
 
 
-void TestMobCntActions::initTestCase()
+void TestCntActions::initTestCase()
 {
     int error = qRegisterMetaType<QContactAction::State>();
 	//create manager
@@ -40,12 +40,12 @@
 	    
 }
 
-void TestMobCntActions::cleanupTestCase()
+void TestCntActions::cleanupTestCase()
 {
     delete m_manager;
 }
 
-void TestMobCntActions::init()
+void TestCntActions::init()
 {
     //delete all contacts from the database
     QList<QContactLocalId> contacts = m_manager->contactIds();
@@ -53,10 +53,10 @@
     m_manager->removeContacts(contacts, &errorMap);
 }
 
-void TestMobCntActions::cleanup()
+void TestCntActions::cleanup()
 {}
 
-void TestMobCntActions::emptyContactNoActionSupport()
+void TestCntActions::emptyContactNoActionSupport()
 {
     QContact contact;
     m_manager->saveContact(&contact);
@@ -66,7 +66,7 @@
     QVERIFY(actions.count() == 0);
 }
 
-void TestMobCntActions::phonenumberCallSupport()
+void TestCntActions::phonenumberCallSupport()
 {
     QContact contact;
     
@@ -110,7 +110,7 @@
     delete callAction;
 }
 
-void TestMobCntActions::phonenumberNoCallSupport()
+void TestCntActions::phonenumberNoCallSupport()
 {
     QContact contact;
     m_manager->saveContact(&contact);
@@ -127,7 +127,7 @@
     QVERIFY(actions.contains("call", Qt::CaseInsensitive) == false);
 }
 
-void TestMobCntActions::phonenumberMessageSupport()
+void TestCntActions::phonenumberMessageSupport()
 {
     QContact contact;
     
@@ -170,7 +170,7 @@
     delete messageAction;
 }
 
-void TestMobCntActions::phonenumberNoMessageSupport()
+void TestCntActions::phonenumberNoMessageSupport()
 {
     QContactPhoneNumber faxNumber;
     faxNumber.setNumber("555111222");
@@ -186,7 +186,7 @@
     QVERIFY(isSupportDetail == false);
 }
 
-void TestMobCntActions::phonenumberVideoCallSupport()
+void TestCntActions::phonenumberVideoCallSupport()
 {
     QContact contact;
     
@@ -230,7 +230,7 @@
     delete videoCallAction;
 }
 
-void TestMobCntActions::phonenumberNoVideoCallSupport()
+void TestCntActions::phonenumberNoVideoCallSupport()
 {
     QContact contact;
     m_manager->saveContact(&contact);
@@ -246,7 +246,7 @@
     QVERIFY(actions.contains("videocall", Qt::CaseInsensitive) == false);
 }
 
-void TestMobCntActions::emailSupport()
+void TestCntActions::emailSupport()
 {
     QContact contact;
     QContactEmailAddress email;
@@ -289,7 +289,7 @@
     delete emailAction;
 }
 
-void TestMobCntActions::noEmailSupport()
+void TestCntActions::noEmailSupport()
 {
     QContact contact;
     m_manager->saveContact(&contact);
@@ -305,7 +305,7 @@
     QVERIFY(actions.contains("email", Qt::CaseInsensitive) == false);
 }
 
-void TestMobCntActions::urlSupport()
+void TestCntActions::urlSupport()
 {
     QContact contact;
     QContactUrl url;
@@ -348,7 +348,7 @@
     delete urlAction;
 }
 
-void TestMobCntActions::noUrlSupport()
+void TestCntActions::noUrlSupport()
 {
     QContact contact;
     m_manager->saveContact(&contact);
@@ -364,4 +364,4 @@
     QVERIFY(actions.contains("url", Qt::CaseInsensitive) == false);
 }
 
-QTEST_MAIN(TestMobCntActions);
+//QTEST_MAIN(TestCntActions);
--- a/phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.h	Wed Jun 23 18:02:44 2010 +0300
@@ -23,7 +23,7 @@
 
 Q_DECLARE_METATYPE(QContactAction::State)
 
-class TestMobCntActions : public QObject
+class TestCntActions : public QObject
 {
     Q_OBJECT
 
--- a/phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntactions/tsrc/mt_cntactions/mt_cntactions.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -17,7 +17,7 @@
 TEMPLATE = app
 TARGET = 
 
-QT += testlib
+QT += testlib sql xml
 CONFIG  += qtestlib
 #DEFINES += PBK_UNIT_TEST
 
@@ -26,14 +26,19 @@
 
 symbian:
 {
-	INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+	INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 	
 	# Input
-	HEADERS += mt_cntactions.h 
+	HEADERS += testrunner.h
+	HEADERS += mt_cntactions.h
+	
+	SOURCES += main.cpp
+	SOURCES += testrunner.cpp
 	SOURCES += mt_cntactions.cpp
 	
 	TARGET.CAPABILITY = ALL -TCB
   
   LIBS += -lQtContacts 
+  
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntactions/tsrc/mt_cntactions/testrunner.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,176 @@
+/*
+* 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:
+*
+*/
+
+#include "testrunner.h"
+#include <QtTest/QtTest>
+#include <QDir>
+#include <stdio.h>
+
+const char testFunctionElement[] = "TestFunction";
+const char incidentElement[] = "Incident";
+const char descriptionElement[] = "Description";
+const char nameAttr[] = "name";
+const char typeAttr[] = "type";
+const char fileAttr[] = "file";
+const char lineAttr[] = "line";
+const char attrValueFail[] = "fail";
+
+
+TestRunner::TestRunner(const QString& name)
+: mTestCount(0),
+  mParsingIncidentElement(false),
+  mParsingDescriptionElement(false),
+  mCurrentTestFailed(false),
+  mCurrentTestFailureLine(0)
+{
+    mTestRunParams.append(name);
+    mTestRunParams.append("-xml");
+    mTestRunParams.append("-o");
+    mHomeDir = QDir::homePath();
+    mTestRunParams.append(QString()); // Initial result file name
+
+    if (!mHomeDir.endsWith(QString::fromAscii("/")))
+        mHomeDir += QString::fromAscii("/");
+}
+
+TestRunner::~TestRunner()
+{
+}
+
+int TestRunner::runTests(QObject& testObject)
+{
+    QString className(testObject.metaObject()->className());
+    printf("Running tests for %s ... ", className.toUtf8().data());
+    QString resultFileName = mHomeDir + className + ".xml";
+    mTestRunParams.replace(mTestRunParams.count()-1,resultFileName);
+    int errorsBefore = mErrors.count();
+    int error = QTest::qExec(&testObject, mTestRunParams);
+    parse(resultFileName);
+    printf("Failures: %d\n",mErrors.count()-errorsBefore);
+    fflush(stdout);
+    return error;
+}
+
+void TestRunner::printResults()
+{
+    printf("\nTests executed: %d\n",mTestCount);
+    if (mErrors.count() > 0) {
+        printf("Failures (%d):\n", mErrors.count());
+        foreach(QString error, mErrors) {
+            printf("\n%s", error.toUtf8().data());
+        }
+        printf("\n");
+    } else {
+        printf("All passed.\n\n");
+    }
+    fflush(stdout);
+    
+    //To write in file
+    QFile file("C:\\TestResult.txt");
+    if(file.open(QIODevice::WriteOnly)) 
+    {
+        QTextStream ts( &file );
+        ts << "Tests executed: " << mTestCount << "\n";
+        if (mErrors.count() > 0)
+        {
+            ts <<"Failures : " << mErrors.count() << "\n";
+            foreach(QString error, mErrors)
+                {
+                    ts << error.toUtf8().data();
+                }
+            ts << "\n";
+        }
+        else
+        {
+            ts<< "All passed.\n\n";
+        }
+        
+        ts << endl;
+        file.close();
+    } 
+}
+
+void TestRunner::parse(const QString& fileName)
+{
+    QFile file(fileName);
+    QXmlInputSource inputSource(&file);
+    QXmlSimpleReader reader;
+    reader.setContentHandler(this);
+    reader.parse(inputSource);
+}
+
+bool TestRunner::startElement(
+    const QString& /*namespaceURI*/, 
+    const QString& /*localName*/, 
+    const QString& qName, 
+    const QXmlAttributes& atts)
+{
+    if (qName == QString::fromAscii(testFunctionElement)) {
+        mTestCount++;
+        mCurrentTestName = atts.value(QString::fromAscii(nameAttr));
+        return true;
+    }
+    if (qName == QString::fromAscii(incidentElement)) {
+        mParsingIncidentElement = true;
+        if (atts.value(QString::fromAscii(typeAttr)) == QString::fromAscii(attrValueFail)) {
+            mCurrentTestFailed = true;
+            mCurrentTestFile = atts.value(QString::fromAscii(fileAttr));
+            mCurrentTestFailureLine = atts.value(QString::fromAscii(lineAttr)).toInt();
+        }
+        return true;
+    }
+    mParsingDescriptionElement =
+        (qName == QString::fromAscii(descriptionElement));
+    return true;
+}
+
+bool TestRunner::endElement(
+    const QString& /*namespaceURI*/,
+    const QString& /*localName*/,
+    const QString& qName)
+{
+    if (qName == QString::fromAscii(incidentElement)) {
+        mParsingIncidentElement = false;
+        mCurrentTestFailed = false;
+        return true;
+    }
+    if (qName == QString::fromAscii(descriptionElement)) {
+        mParsingDescriptionElement = false;
+    }    
+    return true;
+}
+
+bool TestRunner::characters(const QString& ch)
+{
+    if (mParsingIncidentElement && 
+        mParsingDescriptionElement &&
+        mCurrentTestFailed) {
+        QByteArray testResult = mCurrentTestName.toAscii() + " failed:\n";
+        testResult += "File: ";
+        testResult += mCurrentTestFile.toAscii();
+        testResult += "\n";
+        testResult += "Line: ";
+        testResult += QByteArray::number(mCurrentTestFailureLine);
+        testResult += "\n";
+        testResult += "Reason: ";
+        testResult += ch.toAscii();
+        testResult += "\n";
+        mErrors.append(QString::fromAscii(testResult.data()));
+    }
+    return true;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntactions/tsrc/mt_cntactions/testrunner.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* 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:
+*
+*/
+
+#ifndef TESTRUNNER_H
+#define TESTRUNNER_H
+
+#include <QXmlDefaultHandler>
+
+
+class TestRunner : public QXmlDefaultHandler
+{
+public: // Constructors and destructor
+    TestRunner(const QString& name);
+    ~TestRunner();
+       
+public: // New functions
+    
+    int runTests(QObject& testObject);
+    void printResults();
+    
+protected: // From QXmlContentHandler 
+    bool startElement(
+        const QString& namespaceURI,
+        const QString& localName,
+        const QString& qName,
+        const QXmlAttributes& atts);
+    
+    bool endElement(
+        const QString& namespaceURI,
+        const QString& localName,
+        const QString& qName);
+    
+    bool characters(const QString& ch);
+
+private: // New functions
+
+    void parse(const QString& fileName);
+
+private: // Data
+    QStringList mTestRunParams;
+    QString mHomeDir;
+    int mTestCount;
+    QStringList mErrors;
+    bool mParsingIncidentElement;
+    bool mParsingDescriptionElement;
+    bool mCurrentTestFailed;
+    QString mCurrentTestName;
+    QString mCurrentTestFile;
+    int mCurrentTestFailureLine;
+};
+
+
+#endif // TESTRUNNER_H
--- a/phonebookengines/cntimageutility/cntimageutility.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntimageutility/cntimageutility.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -37,4 +37,11 @@
 
 SOURCES += src/cntimageutility.cpp
 
-LIBS += -lplatformenv
+LIBS += -lplatformenv -lefsrv
+defBlock = \      
+	"$${LITERAL_HASH}if defined(EABI)" \
+		"DEFFILE  ../eabi/cntimageutility.def" \
+    "$${LITERAL_HASH}else" \
+        "DEFFILE  ../bwins/cntimageutility.def" \
+	"$${LITERAL_HASH}endif"
+MMP_RULES += defBlock
--- a/phonebookengines/cntlistmodel/cntlistmodel.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/cntlistmodel.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -35,7 +35,7 @@
 
 INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
 INCLUDEPATH += inc
-INCLUDEPATH += ../inc
+INCLUDEPATH += ../../inc
 
 
 INTERNAL_PUBLIC_HEADERS += \
@@ -47,24 +47,36 @@
            inc/cntcache.h \
            inc/cntcache_p.h \
            inc/cntinfoprovider.h \
-           inc/cntdefaultinfoprovider.h
+           inc/cntdefaultinfoprovider.h \
+           inc/cntpresenceinfoprovider.h \
+           ../../inc/cntdebug.h
 
 SOURCES += src/cntlistmodel.cpp \
            src/cntcache.cpp \
            src/cntcache_p.cpp \
-           src/cntdefaultinfoprovider.cpp
+           src/cntdefaultinfoprovider.cpp \
+           src/cntpresenceinfoprovider.cpp
     
 LIBS += -lQtContacts \
         -lhbcore \
-        -lthumbnailmanagerqt
-
+        -lthumbnailmanagerqt \
+        -lpresencecacheqt \
+        -lxqsettingsmanager
+        
 deploy.path = /
 headers.sources = $$INTERNAL_PUBLIC_HEADERS
-headers.path = epoc32/include/app #change this to internal folder
+headers.path = /epoc32/include/app #change this to internal folder
 DEPLOYMENT += exportheaders
 
 # This is for new exporting system coming in garden
 for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
 
+defBlock = \      
+	"$${LITERAL_HASH}if defined(EABI)" \
+		"DEFFILE  ../eabi/cntlistmodel.def" \
+    "$${LITERAL_HASH}else" \
+        "DEFFILE  ../bwins/cntlistmodel.def" \
+	"$${LITERAL_HASH}endif"
+MMP_RULES += defBlock
 
 
--- a/phonebookengines/cntlistmodel/inc/cntcache.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/inc/cntcache.h	Wed Jun 23 18:02:44 2010 +0300
@@ -75,6 +75,8 @@
  */
 class CntCache : public QObject
 {
+    friend class TestCntCache;
+    friend class TestCntListModel;
     Q_OBJECT
 public:
     static CntCache* instance();
@@ -101,6 +103,7 @@
     void onNewIcon(const QString& iconName, const HbIcon& icon);
     void onIconCancelled(const QString& iconName);
     void onShutdown();
+    void updateContactsInCache(const QList<QContactLocalId>& contactIds);
     void removeContactsFromCache(const QList<QContactLocalId>& contactIds);
     void scheduleOneReadAheadItem();
 
--- a/phonebookengines/cntlistmodel/inc/cntcache_p.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/inc/cntcache_p.h	Wed Jun 23 18:02:44 2010 +0300
@@ -26,10 +26,6 @@
 #include <qcontactmanager.h>
 #include "cntinfoprovider.h"
 
-#define DP( s );
-#define DP_IN( s );
-#define DP_OUT( s );
-
 class ThumbnailManager;
 
 QTM_USE_NAMESPACE
@@ -94,6 +90,7 @@
  */
 class CntCacheThread : public QThread
 {
+    friend class TestCntCache;
     Q_OBJECT
 public:
     CntCacheThread();
@@ -126,6 +123,7 @@
     QMap<CntInfoProvider*, ContactInfoFields> mDataProviders;
 
     QMutex mJobMutex;                       // guards access to the job lists
+    bool mStarted;                          // true when thread has been started
     bool mJobLoopRunning;                   // true from when job loop event has been posted until job loop exits
     int mPostponeJobs;                      // set to true by client if it needs the CPU
     QList<int> mInfoJobs;                   // list of all info jobs
--- a/phonebookengines/cntlistmodel/inc/cntdefaultinfoprovider.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/inc/cntdefaultinfoprovider.h	Wed Jun 23 18:02:44 2010 +0300
@@ -31,7 +31,9 @@
  */
 class CntDefaultInfoProvider : public CntInfoProvider
 {
+    friend class TestCntDefaultInfoProvider;
     Q_OBJECT
+    
 public:
     QString id() const { return "default"; };
     ContactInfoFields supportedFields() const;
--- a/phonebookengines/cntlistmodel/inc/cntlistmodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/inc/cntlistmodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -29,10 +29,9 @@
 QTM_USE_NAMESPACE
 
 class CntListModelData;
-class CntListModel;
 
 /*!
- * MobCntModel is a list model view for contacts database
+ * CntListModel is a list model view for contacts database
  * content. It will cache contacts database entries to be
  * displayed on the screen.
  *
@@ -43,16 +42,14 @@
 class CNTLISTMODEL_EXPORT CntListModel : public QAbstractListModel
 {
     Q_OBJECT
-    friend class TestMobCntModel;
+    friend class TestCntListModel;
 
 public:
     CntListModel(const QContactFilter& contactFilter = QContactFilter(),
-                const QList<QContactSortOrder>& contactSortOrders = QList<QContactSortOrder>(),
                 bool showMyCard = true,
                 QObject *parent = 0);
     CntListModel(QContactManager* manager,
                 const QContactFilter& contactFilter = QContactFilter(),
-                const QList<QContactSortOrder>& contactSortOrders = QList<QContactSortOrder>(),
                 bool showMyCard = true,
                 QObject *parent = 0);
     ~CntListModel();
@@ -62,20 +59,20 @@
     int rowCount(const QModelIndex &parent = QModelIndex()) const;
 
 public:
-    QContact contact(const QModelIndex &index) const;
-    QModelIndex indexOfContact(const QContact &contact) const;
-    QContactManager& contactManager() const;
-    void setFilterAndSortOrder(const QContactFilter& contactFilter = QContactFilter(),
-                               const QList<QContactSortOrder>& contactSortOrders = QList<QContactSortOrder>());
-    void showMyCard(bool enabled);
-    bool myCardStatus() const;
-    QContactLocalId myCardId() const;
+	QContact contact(const QModelIndex &index) const;
+	QModelIndex indexOfContact(const QContact &contact) const;
+	QContactManager& contactManager() const;
+	void setFilter(const QContactFilter& contactFilter = QContactFilter());
+	void showMyCard(bool enabled);
+	bool myCardStatus() const;
+	QContactLocalId myCardId() const;
 	
 private:
     // Construction helpers
     int doConstruct();
     int initializeData();
     void updateContactIdsArray();
+    void setSortOrder();
 
     // Data manipulation
     QContact contact(int row) const;
@@ -85,17 +82,18 @@
     int rowId(const QContactLocalId &contactId) const;
     QVariant dataForDisplayRole(int row) const;
 
-protected slots:
+private slots:
     void handleAdded(const QList<QContactLocalId>& contactIds);
     void handleChanged(const QList<QContactLocalId>& contactIds);
     void handleRemoved(const QList<QContactLocalId>& contactIds);
     void handleMyCardChanged(const QContactLocalId& oldId, const QContactLocalId& newId);
     void handleContactInfoUpdated(QContactLocalId contactId);
+    void refreshModel();
 
 private:
     QSharedDataPointer<CntListModelData>  d;
-    HbIcon                               mDefaultIcon;
-    HbIcon                               mDefaultMyCardIcon;
+    HbIcon                               m_defaultIcon;
+    HbIcon                               m_defaultMyCardIcon;
 };
 
 #endif
--- a/phonebookengines/cntlistmodel/inc/cntlistmodel_p.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/inc/cntlistmodel_p.h	Wed Jun 23 18:02:44 2010 +0300
@@ -24,6 +24,7 @@
 #include <qcontactmanager.h>
 #include <qcontactfilter.h>
 #include <qcontactsortorder.h>
+#include <cntuids.h>
 #include "cntcache.h"
 
 QTM_USE_NAMESPACE
@@ -32,29 +33,29 @@
 {
 public:
     CntListModelData( const QContactFilter& contactFilter = QContactFilter(),
-                     const QList<QContactSortOrder>& contactSortOrders = QList<QContactSortOrder>(),
                      bool showMyCard = true) :
-                         m_contactManager(0),
-                         ownedContactManager(false),
-                         currentRow(-1),
-                         filter(contactFilter),
-                         sortOrders(contactSortOrders),
-                         showMyCard(showMyCard)
-                      { }
-    ~CntListModelData() { if (ownedContactManager) {delete m_contactManager;}}
+                         m_contactManager(NULL),
+                         m_ownedContactManager(false),
+                         m_currentRow(-1),
+                         m_filter(contactFilter),
+                         m_showMyCard(showMyCard)
+                      { 
+                      }
+    ~CntListModelData() {if (m_ownedContactManager) delete m_contactManager;}
 
 public:
     QContactManager* m_contactManager;
     CntCache* m_cache;
-    bool ownedContactManager;
-    mutable CntContactInfo currentContact;
-    mutable int currentRow;
+    bool m_ownedContactManager;
+    mutable CntContactInfo m_currentContact;
+    mutable int m_currentRow;
 	
-    QList<QContactLocalId> contactIds;
-    QContactFilter filter;
-    QList<QContactSortOrder> sortOrders;
-    bool showMyCard;
-	QContactLocalId mMyCardId;
+    QList<QContactLocalId> m_contactIds;
+    QContactFilter m_filter;
+    QList<QContactSortOrder> m_sortOrders;
+    bool m_showMyCard;
+	QContactLocalId m_myCardId;
+	int nameOrder;
 };
 
 #endif // QCONTACTMODELPRIVATE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/inc/cntpresenceinfoprovider.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* 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: Presence info provider plugin for CntListModel. It can provide
+*              the presence information of a contact (icon2 field).
+*
+*/
+
+#ifndef CNTPRESENCEINFOPROVIDER_H
+#define CNTPRESENCEINFOPROVIDER_H
+
+#include "cntinfoprovider.h"
+#include <qcontact.h>
+
+class PrcPresenceReader;
+class PrcPresenceBuddyInfoQt;
+
+QTM_BEGIN_NAMESPACE
+class QContactManager;
+QTM_END_NAMESPACE
+
+QTM_USE_NAMESPACE
+
+/**
+    Presence info provider plugin for CntListModel. It can provide
+    the presence information of a contact (icon2 field).
+ */
+class CntPresenceInfoProvider : public CntInfoProvider
+{
+    friend class TestCntPresenceInfoProvider;
+    Q_OBJECT
+    
+public:
+    CntPresenceInfoProvider();
+    ~CntPresenceInfoProvider();
+    
+	// From CntInfoProvider
+    QString id() const { return "presence"; };
+    ContactInfoFields supportedFields() const;
+    void requestInfo(const QContact& contact, ContactInfoFields requestedInfo);
+    
+private slots:
+    void handlePresenceUpdate(bool aSuccess, PrcPresenceBuddyInfoQt* aPresenceBuddyInfo);
+    
+private:
+    QString parsePresence(const QList<PrcPresenceBuddyInfoQt*>& buddyList);
+    
+private:
+    PrcPresenceReader*              iReader; // owned
+    QContactManager*                mManager; // owned
+    QMap<QString, QContactLocalId>  mBuddyMap;
+};
+
+#endif
--- a/phonebookengines/cntlistmodel/src/cntcache.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/src/cntcache.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -19,6 +19,7 @@
 #include <hbapplication.h>
 #include <qtcontacts.h>
 #include <qcontactmanager.h>
+#include <cntdebug.h>
 #include "cntcache.h"
 #include "cntcache_p.h"
 #include "cntinfoprovider.h"
@@ -64,7 +65,7 @@
       mNextIconCacheOrder(CacheOrderStartValue),
       mEmittedContactId(-1)
 {
-    DP_IN("CntCache::CntCache()");
+    CNT_ENTRY
 
     // listen to worker updates
     connect(mWorker, SIGNAL(infoFieldUpdated(int, const ContactInfoField&, const QString&)),
@@ -76,13 +77,13 @@
     connect(mWorker, SIGNAL(allJobsDone()), this, SLOT(scheduleOneReadAheadItem()));
 
     // listen to the database for changes to contacts
-    connect(mContactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(removeContactsFromCache(const QList<QContactLocalId>&)));
+    connect(mContactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(updateContactsInCache(const QList<QContactLocalId>&)));
     connect(mContactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(removeContactsFromCache(const QList<QContactLocalId>&)));
 
     // shutdown only when the whole application shuts down
     connect(HbApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(onShutdown()));
 
-    DP_OUT("CntCache::CntCache()");
+    CNT_EXIT
 }
 
 /*!
@@ -90,12 +91,19 @@
  */
 CntCache::~CntCache()
 {
-    DP_IN("CntCache::~CntCache()");
+    CNT_ENTRY
 
     delete mWorker;
     delete mContactManager;
+    
+    qDeleteAll(mInfoCache);
+    mInfoCache.clear();
+    qDeleteAll(mIconCache);
+    mIconCache.clear();
 
-    DP_OUT("CntCache::~CntCache()");
+    mInstance = NULL;
+
+    CNT_EXIT
 }
 
 /*! 
@@ -115,7 +123,7 @@
  */
 CntContactInfo CntCache::fetchContactInfo(int row, const QList<QContactLocalId>& idList)
 {
-    DP_IN("CntCache::fetchContactInfo(" << row << ", idlist[" << idList.count() << "])");
+    CNT_ENTRY_ARGS(row << "/" << idList.count())
 
     Q_ASSERT(row >= 0 && row < idList.count());
 
@@ -180,38 +188,25 @@
         }
     }
 
-    // cache read-ahead -- items near this fetched item should also be in cache
-    // updateReadAhead(row, idList);
-
-    DP_OUT("CntCache::fetchContactInfo(" << row << ", idlist[" << idList.count() << "]) : name =" << name);
+    CNT_EXIT_ARGS("name:" << name << "sec:" << text)
 
     return CntContactInfo(contactId, name, text, icons[0], icons[1]);
 }
 
 /*! 
-    Clears the cache - both names and icons. This function can be useful
-    for example if application goes to the background and memory needs to
-    be freed, or if the format of contact names change.
+    Clears the cache of names (not icons). This function can be useful
+    for example when the format of contact names changes.
  */
 void CntCache::clearCache()
 {
-    DP_IN("CntCache::clearCache()");
+    CNT_ENTRY
 
     // clear info cache
-    foreach (CntInfoCacheItem* item, mInfoCache) {
-        delete item;
-    }
+    qDeleteAll(mInfoCache);
     mInfoCache.clear();
     mNextInfoCacheOrder = CacheOrderStartValue;
 
-    // clear icon cache
-    foreach (CntIconCacheItem* item, mIconCache) {
-        delete item;
-    }
-    mIconCache.clear();
-    mNextIconCacheOrder = CacheOrderStartValue;
-
-    DP_OUT("CntCache::clearCache()");
+    CNT_EXIT
 }
 
 /*! 
@@ -225,7 +220,7 @@
  */
 void CntCache::onNewInfo(int contactId, const ContactInfoField& infoField, const QString& infoValue)
 {
-    DP_IN("CntCache::onNewInfo(" << contactId << "," << infoField << "," << infoValue << ")");
+    CNT_ENTRY_ARGS( "id:" << contactId   << "infotype:" << infoField   << "infovalue:" << infoValue )
 
     Q_ASSERT(infoField == ContactInfoTextField || infoField == ContactInfoIcon1Field || infoField == ContactInfoIcon2Field);
 
@@ -266,11 +261,16 @@
                     hasNewInfo = true;
                 }
             }
+            else if (iconName.startsWith("qtg_", Qt::CaseInsensitive)) {
+                CntIconCacheItem* iconItem = createIconCacheItem(iconName);
+                onNewIcon(iconName, HbIcon(iconName)); 
+                hasNewInfo = true;
+            }
             else {
-               CntIconCacheItem* iconItem = createIconCacheItem(iconName);
-               iconItem->contactIds.insert(contactId);
-               mWorker->scheduleIconJob(iconName);
-               hasNewInfo = false;
+                CntIconCacheItem* iconItem = createIconCacheItem(iconName);
+                iconItem->contactIds.insert(contactId);
+                mWorker->scheduleIconJob(iconName);
+                hasNewInfo = false;
             }
         }
         else {
@@ -279,11 +279,10 @@
     }
 
     if (hasNewInfo) {
-        DP("CntCache::onNewInfo() : new info => emitting contactInfoUpdated(" << contactId << ")");
         emitContactInfoUpdated(contactId);
     }
 
-    DP_OUT("CntCache::onNewInfo(" << contactId << "," << infoField << "," << infoValue << ")");
+    CNT_EXIT
 }
 
 /*! 
@@ -292,17 +291,16 @@
  */
 void CntCache::onInfoCancelled(int contactId)
 {
-    DP_IN("CntCache::onInfoCancelled(" << contactId << ")");
+    CNT_ENTRY_ARGS( "id:" << contactId )
 
     if (mInfoCache.contains(contactId)) {
         CntInfoCacheItem* item = mInfoCache.take(contactId);
         delete item;
     }
 
-    DP("CntCache::onInfoCancelled() : info cancelled => emitting contactInfoUpdated(" << contactId << ")");
     emitContactInfoUpdated(contactId);
 
-    DP_OUT("CntCache::onInfoCancelled(" << contactId << ")");
+    CNT_EXIT
 }
 
 /*! 
@@ -312,7 +310,7 @@
  */
 void CntCache::onNewIcon(const QString& iconName, const HbIcon& icon)
 {
-    DP_IN("CntCache::onNewIcon(" << iconName << ", HbIcon)");
+    CNT_ENTRY_ARGS( iconName )
 
     QSet<int> contactsToNotify;
 
@@ -325,11 +323,10 @@
     }
 
     foreach (int contactId, contactsToNotify) {
-        DP("CntCache::onNewIcon() : new icon => emitting contactInfoUpdated(" << contactId << ")");
         emitContactInfoUpdated(contactId);
     }
 
-    DP_OUT("CntCache::onNewIcon(" << iconName << ", HbIcon)");
+    CNT_EXIT
 }
 
 /*! 
@@ -338,7 +335,7 @@
  */
 void CntCache::onIconCancelled(const QString& iconName)
 {
-    DP_IN("CntCache::onIconCancelled(" << iconName << ")");
+    CNT_ENTRY_ARGS( iconName )
 
     QSet<int> contactsToNotify;
 
@@ -350,11 +347,36 @@
     }
 
     foreach (int contactId, contactsToNotify) {
-        DP("CntCache::onIconCancelled() : icon cancelled => emitting contactInfoUpdated(" << contactId << ")");
         emitContactInfoUpdated(contactId);
     }
 
-    DP_OUT("CntCache::onIconCancelled(" << iconName << ")");
+    CNT_EXIT
+}
+
+/*! 
+    Update contacts in cache.
+    
+    /param contactIds ids of the contact that will be updated
+ */
+void CntCache::updateContactsInCache(const QList<QContactLocalId>& contactIds)
+{
+    CNT_ENTRY
+
+    QString name;
+
+    foreach (QContactLocalId contactId, contactIds) {
+        if (mInfoCache.contains(contactId) && fetchContactName(contactId, name)) {
+            CntInfoCacheItem* infoItem = mInfoCache.value(contactId);
+            infoItem->name = name;
+            mWorker->scheduleInfoJob(contactId);
+        }
+    }
+
+    foreach (QContactLocalId contactId, contactIds) {
+        emitContactInfoUpdated(contactId);
+    }
+
+    CNT_EXIT
 }
 
 /*! 
@@ -364,7 +386,7 @@
  */
 void CntCache::removeContactsFromCache(const QList<QContactLocalId>& contactIds)
 {
-    DP_IN("CntCache::removeContactsFromCache(idList[" << contactIds.count() << "])");
+    CNT_ENTRY
 
     foreach (QContactLocalId contactId, contactIds) {
         if (mInfoCache.contains(contactId)) {
@@ -377,7 +399,7 @@
         emitContactInfoUpdated(contactId);
     }
 
-    DP_OUT("CntCache::removeContactsFromCache(idList[" << contactIds.count() << "])");
+    CNT_EXIT
 }
 
 /*! 
@@ -390,8 +412,9 @@
  */
 bool CntCache::fetchContactName(int contactId, QString& contactName)
 {
+    CNT_ENTRY_ARGS( contactId )
+
     bool foundContact = false;
-    DP_IN("CntCache::fetchContactName(" << contactId << "," << contactName << ")");
 
     QContactFetchHint nameOnlyFetchHint;
     QStringList details;
@@ -402,13 +425,9 @@
     if (mContactManager->error() == QContactManager::NoError) {
         contactName = contact.displayLabel();
         foundContact = true;
-        // TODO: this can be removed once qt mobility is updated (~wk20/10)
-        if (contactName == "Unnamed") {
-            contactName = "";
-        }
     }
     
-    DP_OUT("CntCache::fetchContactName(" << contactId << "," << contactName << ") : " << foundContact);
+    CNT_EXIT_ARGS( foundContact )
     
     return foundContact;
 }
@@ -422,7 +441,8 @@
  */
 void CntCache::updateReadAheadCache(int mostRecentRow, const QList<QContactLocalId>& idList)
 {
-    DP_IN("CntCache::updateReadAheadCache(" << mostRecentRow << ", idList[" << idList.count() << "] )");
+    CNT_ENTRY_ARGS( mostRecentRow )
+
     int row;
 
     mReadAheadCache.clear();
@@ -456,7 +476,7 @@
         }
     }
 
-    DP_OUT("CntCache::updateReadAheadCache(" << mostRecentRow << ", idList[" << idList.count() << "] )");
+   CNT_EXIT
 }
 
 /*! 
@@ -464,7 +484,7 @@
  */
 void CntCache::scheduleOneReadAheadItem()
 {
-    DP_IN("CntCache::scheduleOneReadAheadItem()");
+    CNT_ENTRY
 
     QString name;
     
@@ -485,7 +505,7 @@
         }
     }
 
-    DP_OUT("CntCache::scheduleOneReadAheadItem()");
+    CNT_EXIT
 }
 
 /*! 
@@ -497,7 +517,7 @@
  */
 CntInfoCacheItem* CntCache::createInfoCacheItem(int contactId)
 {
-    DP_IN("CntCache::createInfoCacheItem(" << contactId << ")");
+    CNT_ENTRY_ARGS( contactId )
 
     if (mInfoCache.count() >= InfoCacheSize) {
         // cache is full, so remove the oldest contact
@@ -528,7 +548,7 @@
     item->contactId = contactId;
     mInfoCache.insert(contactId, item);
     
-    DP_OUT("CntCache::createInfoCacheItem(" << contactId << ")");
+    CNT_EXIT
 
     return item;
 }
@@ -542,7 +562,7 @@
  */
 CntIconCacheItem* CntCache::createIconCacheItem(const QString& iconName)
 {
-    DP_IN("CntCache::createIconCacheItem(" << iconName << ")");
+    CNT_ENTRY_ARGS( iconName )
 
     if (mIconCache.count() >= IconCacheSize) {
         // cache is full, so remove the oldest icon
@@ -574,7 +594,7 @@
     item->isFetched = false;
     mIconCache.insert(iconName, item);
 
-    DP_OUT("CntCache::createIconCacheItem(" << iconName << ")");
+    CNT_EXIT
 
     return item;
 }
@@ -586,9 +606,13 @@
  */
 void CntCache::emitContactInfoUpdated(int contactId)
 {
+	CNT_ENTRY_ARGS( contactId )
+
     mEmittedContactId = contactId;
     emit contactInfoUpdated(contactId);
     mEmittedContactId = -1;
+
+	CNT_EXIT
 }
 
 /*! 
@@ -596,7 +620,11 @@
  */
 void CntCache::onShutdown()
 {
+	CNT_ENTRY
+
     delete this;
+
+	CNT_EXIT
 }
 
 
--- a/phonebookengines/cntlistmodel/src/cntcache_p.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/src/cntcache_p.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -25,6 +25,8 @@
 #include "cntcache_p.h"
 #include "cntinfoprovider.h"
 #include "cntdefaultinfoprovider.h"
+#include "cntpresenceinfoprovider.h"
+#include <cntdebug.h>
 
 // maximum amount of info and icon jobs respectively -- if there are more jobs,
 // then the oldest job is skipped and the client informed that this happened
@@ -46,14 +48,16 @@
  */
 CntCacheThread::CntCacheThread()
     : mContactManager(new QContactManager()),
+      mStarted(false),
       mJobLoopRunning(false),
       mPostponeJobs(false),
       mIconRequestId(NoIconRequest)
 {
-    DP_IN("CntCacheThread::CntCacheThread()");
+    CNT_ENTRY
 
     // create static provider plugins
     mDataProviders.insert(new CntDefaultInfoProvider(), ContactInfoAllFields);
+    mDataProviders.insert(new CntPresenceInfoProvider(), ContactInfoIcon2Field);
     // TODO: create more static provider plugins
 
     // TODO: load dynamic provider plugins using QPluginLoader
@@ -76,11 +80,7 @@
     connect(mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)),
              this, SLOT(onIconReady(QPixmap, void *, int, int)));
 
-    // this thread should interfere as little as possible with more time-critical tasks,
-    // like updating the UI during scrolling
-    start(QThread::IdlePriority);
-
-    DP_OUT("CntCacheThread::CntCacheThread()");
+    CNT_EXIT
 }
 
 /*!
@@ -88,8 +88,9 @@
  */
 CntCacheThread::~CntCacheThread()
 {
-    DP_IN("CntCacheThread::~CntCacheThread()");
-
+    CNT_ENTRY
+    
+    delete mContactManager;
     disconnect(this);
 
     mJobMutex.lock();
@@ -103,11 +104,10 @@
         mIconRequestId = NoIconRequest;
     }
 
-    QMapIterator<CntInfoProvider*, ContactInfoFields> i(mDataProviders);
-    while (i.hasNext()) {
-        i.next();
-        delete i.key();
-    }
+    delete mThumbnailManager;
+    mThumbnailManager = NULL;
+
+    qDeleteAll(mDataProviders.keys());
     mDataProviders.clear();
 
     mJobMutex.unlock();
@@ -115,7 +115,7 @@
     exit();
     wait();
 
-    DP_OUT("CntCacheThread::~CntCacheThread()");
+    CNT_EXIT
 }
 
 /*!
@@ -123,9 +123,11 @@
  */
 void CntCacheThread::run()
 {
-    DP_IN("CntCacheThread::run()");
+    CNT_ENTRY
+
     exec();
-    DP_OUT("CntCacheThread::run()");
+
+    CNT_EXIT
 }
 
 /*!
@@ -136,12 +138,19 @@
  */
 void CntCacheThread::scheduleInfoJob(int contactId)
 {
-    DP_IN("CntCacheThread::scheduleInfoJob(" << contactId << ")");
+    CNT_ENTRY_ARGS( contactId )
 
     Q_ASSERT(contactId > 0 && !mInfoJobs.contains(contactId));
 
     mJobMutex.lock();
 
+    if (!mStarted) {
+        // this thread should interfere as little as possible with more time-critical tasks,
+        // like updating the UI during scrolling
+        start(QThread::IdlePriority);
+        mStarted = true;
+    }
+
     if (!mJobLoopRunning) {
         // new job => restart job loop
         mJobLoopRunning = true;
@@ -151,11 +160,11 @@
     if (mInfoJobs.count() >= CntMaxInfoJobs) {
         // the queue of jobs is full, so remove the oldest job
         mCancelledInfoJobs.append(mInfoJobs.takeFirst());
-        DP("CntCacheThread::scheduleInfoJob() :" << mCancelledInfoJobs.last() << "removed from joblist");
+        CNT_LOG_ARGS( mCancelledInfoJobs.last() << "removed from joblist" )
     }
 
     mInfoJobs.append(contactId);
-    DP("CntCacheThread::scheduleInfoJob() :" << contactId << "appended @" << mInfoJobs.indexOf(contactId));
+    CNT_LOG_ARGS( contactId << "appended @" << mInfoJobs.indexOf(contactId) );
 
     // since this job has now been scheduled, remove it from the list of
     // cancelled jobs in case it is there
@@ -163,7 +172,7 @@
 
     mJobMutex.unlock();
 
-    DP_OUT("CntCacheThread::scheduleInfoJob(" << contactId << ")");
+    CNT_EXIT
 }
 
 /*!
@@ -174,7 +183,7 @@
  */
 void CntCacheThread::scheduleIconJob(const QString& iconName)
 {
-    DP_IN("CntCacheThread::scheduleIconJob(" << iconName << ")");
+    CNT_ENTRY_ARGS( iconName )
 
     mJobMutex.lock();
 
@@ -189,11 +198,11 @@
     if (mIconJobs.count() >= CntMaxIconJobs) {
         // the queue of jobs is full, so remove the oldest job
         mCancelledIconJobs.append(mIconJobs.takeLast());
-        DP("CntCacheThread::scheduleIconJob() :" << mCancelledIconJobs.last() << "removed from joblist");
+        CNT_LOG_ARGS( mCancelledIconJobs.last() << "removed from joblist" );
     }
 
     mIconJobs.append(iconName);
-    DP("CntCacheThread::scheduleIconJob() :" << iconName << "appended @" << mIconJobs.indexOf(iconName));
+    CNT_LOG_ARGS( iconName << "appended @" << mIconJobs.indexOf(iconName) );
 
     // since this job has now been rescheduled, remove it from the list of
     // cancelled jobs in case it is there
@@ -201,7 +210,7 @@
 
     mJobMutex.unlock();
 
-    DP_OUT("CntCacheThread::scheduleIconJob(" << iconName << ")");
+    CNT_EXIT
 }
 
 /*!
@@ -210,11 +219,11 @@
  */
 void CntCacheThread::postponeJobs()
 {
-    DP_IN("CntCacheThread::postponeJobs()");
+    CNT_ENTRY
     
     mPostponeJobs = true;
     
-    DP_OUT("CntCacheThread::postponeJobs()");
+    CNT_EXIT
 }
 
 /*!
@@ -239,14 +248,13 @@
  */
 void CntCacheThread::doAllJobs()
 {
-    DP_IN("CntCacheThread::doAllJobs()");
+    CNT_ENTRY
 
     forever {
         mJobMutex.lock();
         int infoJobs = mInfoJobs.count();
         int iconJobs = mIconJobs.count();
         int totalJobs = infoJobs + iconJobs + mCancelledInfoJobs.count() + mCancelledIconJobs.count();
-        DP_IN("CntCacheThread::doAllJobs() : infojobs=" << infoJobs << ", iconjobs=" << iconJobs << ",icon_request=" << mIconRequestId << ", cancelledinfojobs=" << mCancelledInfoJobs.count() << ", cancellediconjobs=" << mCancelledIconJobs.count());
 
         if (totalJobs == 0 || totalJobs == iconJobs && mIconRequestId != NoIconRequest || mPostponeJobs) {
             if (mPostponeJobs) {
@@ -254,7 +262,6 @@
                 mPostponeJobs = false;
                 if (totalJobs > 0) {
                     QTimer::singleShot(PostponeJobsMilliSeconds, this, SLOT(doAllJobs()));
-                    DP("CntCacheThread::doAllJobs() : postponing for" << PostponeJobsMilliSeconds << "ms");
                 }
                 else {
                     mJobLoopRunning = false;
@@ -267,7 +274,6 @@
             mJobMutex.unlock();
 
             if (totalJobs == 0) {
-                DP("CntCacheThread::doAllJobs() : emitting all jobs done");
                 emit allJobsDone();
             }
 
@@ -282,18 +288,11 @@
             mJobMutex.unlock();
     
             // fetch qcontact
-            QStringList definitionRestrictions;
-            definitionRestrictions.append(QContactName::DefinitionName);
-            definitionRestrictions.append(QContactAvatar::DefinitionName);
-            definitionRestrictions.append(QContactPhoneNumber::DefinitionName);
-            definitionRestrictions.append(QContactOrganization::DefinitionName);
             QContactFetchHint restrictions;
-            restrictions.setDetailDefinitionsHint(definitionRestrictions);
             restrictions.setOptimizationHints(QContactFetchHint::NoRelationships);
 			QContact contact = mContactManager->contact(contactId, restrictions);
 
             // request contact info from providers
-            DP("CntCacheThread::doAllJobs() : fetching info for" << contact.displayLabel() << " (id=" << contactId << ")");
             QMapIterator<CntInfoProvider*, ContactInfoFields> i(mDataProviders);
             while (i.hasNext()) {
                 i.next();
@@ -305,7 +304,6 @@
         else if (iconJobs > 0 && mIconRequestId == NoIconRequest) {
             // request icon from thumbnail manager
             QString iconName = mIconJobs.takeFirst();
-            DP("CntCacheThread::doAllJobs() : fetching icon" << iconName);
             mIconRequestId = mThumbnailManager->getThumbnail(iconName, NULL, 0);
             mIconRequestName = iconName;
             mJobMutex.unlock();
@@ -314,13 +312,11 @@
             if (mCancelledInfoJobs.count() > 0) {
                 int contactId = mCancelledInfoJobs.takeLast();
                 mJobMutex.unlock();
-                DP("CntCacheThread::doAllJobs() : emitting cancelled info job" << contactId);
                 emit infoCancelled(contactId);
             }
             else if (mCancelledIconJobs.count() > 0) {
                 QString iconName = mCancelledIconJobs.takeFirst();
                 mJobMutex.unlock();
-                DP("CntCacheThread::doAllJobs() : emitting cancelled icon job" << iconName);
                 emit iconCancelled(iconName);
             }
         }
@@ -329,7 +325,7 @@
         HbApplication::processEvents();
     }
 
-    DP_OUT("CntCacheThread::doAllJobs()");
+    CNT_EXIT
 }
 
 /*!
@@ -339,7 +335,7 @@
 void CntCacheThread::onInfoFieldReady(CntInfoProvider* sender, int contactId,
                                       ContactInfoField field, const QString& text)
 {
-    DP_IN("CntCacheThread::onInfoFieldReady( CntInfoProvider*," << contactId << "," << field << "," << text << ")");
+    CNT_ENTRY
 
     // there can be 3rd party providers, so we cannot blindly trust them;
     // info is emitted only if:
@@ -349,11 +345,10 @@
     if (mDataProviders.contains(sender)
         && ((field & (field - 1)) == 0)
         && ((field & mDataProviders.value(sender)) != 0)) {
-        DP("CntCacheThread::onInfoFieldReady(" << contactId << "," << field << "," << text << ") : emitting infoFieldUpdated()");
         emit infoFieldUpdated(contactId, field, text);
     }
 
-    DP_OUT("CntCacheThread::onInfoFieldReady(" << contactId << "," << field << "," << text << ")");
+    CNT_EXIT
 }
 
 /*!
@@ -362,7 +357,9 @@
  */
 void CntCacheThread::onIconReady(const QPixmap& pixmap, void *data, int id, int error)
 {
-    DP_IN("CntCacheThread::onIconReady( QPixMap, void*, " << id << "," << error << ")");
+    CNT_ENTRY
+
+    Q_UNUSED(id);
     Q_UNUSED(data);
 
     mJobMutex.lock();
@@ -376,9 +373,8 @@
     mJobMutex.unlock();
 
     if (error == 0) {
-        DP("CntCacheThread::onIconReady() : emitting iconUpdated(" << mIconRequestName << ")");
         emit iconUpdated(mIconRequestName, HbIcon(pixmap));
     }
 
-    DP_OUT("CntCacheThread::onIconReady( QPixMap, void*, " << id << "," << error << ")");
+    CNT_EXIT
 }
--- a/phonebookengines/cntlistmodel/src/cntdefaultinfoprovider.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/src/cntdefaultinfoprovider.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -19,6 +19,7 @@
 
 #include <qtcontacts.h>
 #include "cntdefaultinfoprovider.h"
+#include <hbglobal.h>
 
 /*!
     /return the info fields supported by this provider
@@ -48,7 +49,11 @@
         }
         else
         {
-            number = contact.detail<QContactPhoneNumber>().number();
+            QList<QContactPhoneNumber> numbers = contact.details<QContactPhoneNumber>();
+            if (numbers.count() > 1)
+                number = hbTrId("txt_phob_dblist_val_ln_numbers", numbers.count());
+            else if (numbers.count() == 1)
+                number = numbers.at(0).number();
         }
 
         if (!number.isEmpty()) {
--- a/phonebookengines/cntlistmodel/src/cntlistmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntlistmodel/src/cntlistmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,6 +17,7 @@
 #include "cntlistmodel_p.h"
 #include "cntlistmodel.h"
 #include "cntcache.h"
+#include "cntdebug.h"
 
 #include <qtcontacts.h>
 #include <QSet>
@@ -25,6 +26,8 @@
 #include <hbindexfeedback.h>
 #include <hbframebackground.h>
 #include <hbframedrawer.h>
+#include <xqsettingsmanager.h> // for reading cenrep keys
+#include <xqsettingskey.h>
 
 const uint dummyMyCardId = 0;
 
@@ -33,27 +36,28 @@
  * to the default persisted store.
  */
 CntListModel::CntListModel(const QContactFilter& contactFilter,
-                         const QList<QContactSortOrder>& contactSortOrders,
                          bool showMyCard,
                          QObject *parent)
     : QAbstractListModel(parent)
 {
-    mDefaultIcon = HbIcon("qtg_large_avatar");
-    mDefaultMyCardIcon = HbIcon("qtg_large_mycard");
+    CNT_ENTRY
+    m_defaultIcon = HbIcon("qtg_large_avatar");
+    m_defaultMyCardIcon = HbIcon("qtg_large_mycard");
 
-    d = new CntListModelData(contactFilter, contactSortOrders, showMyCard);
+    d = new CntListModelData(contactFilter, showMyCard);
     d->m_contactManager = new QContactManager;
-    d->ownedContactManager = true;
+    d->m_ownedContactManager = true;
     d->m_cache = CntCache::instance();
     connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
-    d->mMyCardId = d->m_contactManager->selfContactId();
+    d->m_myCardId = d->m_contactManager->selfContactId();
     if (doConstruct() != QContactManager::NoError) {
         throw("exception");
     }
+    CNT_EXIT
 }
 
 /*!
- * Construct a new MobCntModel object using manager as the QContactManager
+ * Construct a new CntListModel object using manager as the QContactManager
  * instance to communicate with the contacts database.
  *
  * \param manager A QContactManager instance to be used for
@@ -61,22 +65,24 @@
  */
 CntListModel::CntListModel(QContactManager* manager,
                          const QContactFilter& contactFilter,
-                         const QList<QContactSortOrder>& contactSortOrders,
                          bool showMyCard,
                          QObject *parent)
     : QAbstractListModel(parent)
 {
-    mDefaultIcon = HbIcon("qtg_large_avatar");
-    mDefaultMyCardIcon = HbIcon("qtg_large_mycard");
+    CNT_ENTRY
+    m_defaultIcon = HbIcon("qtg_large_avatar");
+    m_defaultMyCardIcon = HbIcon("qtg_large_mycard");
+    m_defaultMyCardIcon = HbIcon("qtg_large_mycard");
 
-    d = new CntListModelData(contactFilter, contactSortOrders, showMyCard);
+    d = new CntListModelData(contactFilter, showMyCard);
     d->m_contactManager = manager;
     d->m_cache = CntCache::instance();
     connect(d->m_cache, SIGNAL(contactInfoUpdated(QContactLocalId)), this, SLOT(handleContactInfoUpdated(QContactLocalId)));
-    d->mMyCardId = d->m_contactManager->selfContactId();
+    d->m_myCardId = d->m_contactManager->selfContactId();     
     if (doConstruct() != QContactManager::NoError) {
         throw("exception");
     }
+    CNT_EXIT
 }
 
 CntListModel::~CntListModel()
@@ -93,6 +99,7 @@
  */
 QVariant CntListModel::data(const QModelIndex &index, int role) const
 {
+    CNT_ENTRY
     int row = index.row();
 
     // check that row is ok
@@ -102,22 +109,22 @@
     }
     
     // update current contact if needed
-    if (row != d->currentRow ) {
-        if (d->contactIds[row] == dummyMyCardId) {
+    if (row != d->m_currentRow ) {
+        if (d->m_contactIds[row] == dummyMyCardId) {
             // row contains dummy MyCard, so create dummy CntContactInfo
-            d->currentContact = CntContactInfo();
+            d->m_currentContact = CntContactInfo();
         }
         else {
-            d->currentContact = d->m_cache->fetchContactInfo(row, d->contactIds);
+            d->m_currentContact = d->m_cache->fetchContactInfo(row, d->m_contactIds);
         }
-        d->currentRow = row;
+        d->m_currentRow = row;
     }
     
     if (role == Qt::DisplayRole) {
         return dataForDisplayRole(row);
     }
     else if (role == Hb::IndexFeedbackRole) {
-        if (row == 0 && (d->mMyCardId == d->contactIds[0] || dummyMyCardId == d->contactIds[0])) {
+        if (row == 0 && (d->m_myCardId == d->m_contactIds[0] || dummyMyCardId == d->m_contactIds[0])) {
             // do not include MyCard in index feedback
             return QVariant();
         }
@@ -126,23 +133,23 @@
         }
     }
     else if (role == Qt::BackgroundRole) {
-        if (d->mMyCardId == d->contactIds[row] || dummyMyCardId == d->contactIds[row]) {
+        if (d->m_myCardId == d->m_contactIds[row] || dummyMyCardId == d->m_contactIds[row]) {
             return HbFrameBackground("qtg_fr_list_parent_normal", HbFrameDrawer::NinePieces);
         }
     }
     else if (role == Qt::DecorationRole) {
         QList<QVariant> icons;
-        HbIcon avatar = d->currentContact.icon1();
-        HbIcon statusIcon = d->currentContact.icon2();
+        HbIcon avatar = d->m_currentContact.icon1();
+        HbIcon statusIcon = d->m_currentContact.icon2();
     
         if (!avatar.isNull()) {
             icons.append(avatar);
         }
-        else if (d->mMyCardId == d->contactIds[row] || dummyMyCardId == d->contactIds[row]) {
-            icons.append(mDefaultMyCardIcon);
+        else if (d->m_myCardId == d->m_contactIds[row] || dummyMyCardId == d->m_contactIds[row]) {
+            icons.append(m_defaultMyCardIcon);
         }
         else {
-            icons.append(mDefaultIcon);
+            icons.append(m_defaultIcon);
         }
 
         if (!statusIcon.isNull()) {
@@ -151,7 +158,7 @@
 
         return icons;
     }
-
+    CNT_EXIT
     return QVariant();
 }
 
@@ -163,15 +170,15 @@
  */
 int CntListModel::rowCount(const QModelIndex& /*parent*/) const
 {
-    return d->contactIds.count();
+    return d->m_contactIds.count();
 }
 
 /*!
  * Read a full contact entry from the database for the given model
  * index value. Only the row part of the index information will be
- * read. This is just an overload of MobCntModel::contact() that
+ * read. This is just an overload of CntListModel::contact() that
  * supports old behaviour and calls:
- *      MobCntModel::contact(int row);
+ *      CntListModel::contact(int row);
  *
  * The entry at the requested row will have its full contact information
  * (all fields) read from the database and returned as a QContact instance.
@@ -216,15 +223,12 @@
  * \param contactFilter New contact filter.
  * \param contactSortOrders New sort order.
  */
-void CntListModel::setFilterAndSortOrder(const QContactFilter& contactFilter,
-                           const QList<QContactSortOrder>& contactSortOrders)
+void CntListModel::setFilter(const QContactFilter& contactFilter)
 {
-    d->filter = contactFilter;
-    // keep current sort order if new one isn't given
-    if (contactSortOrders.count()) {
-        d->sortOrders = contactSortOrders;
-    }
-    d->currentRow = -1;
+    CNT_ENTRY
+    
+    d->m_filter = contactFilter;
+    d->m_currentRow = -1;
     
     //refresh model
     updateContactIdsArray();
@@ -232,6 +236,61 @@
     beginResetModel();
     reset();
     endResetModel();
+    
+    CNT_EXIT
+}
+
+void CntListModel::setSortOrder()
+{
+    XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
+                         KCRUiContacts.iUid,
+                         KCntNameOrdering);
+    XQSettingsManager settingsMng;
+    int order = settingsMng.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
+
+    QContactSortOrder sortOrderFirstName;
+    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,
+        QContactName::FieldFirstName);
+    sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
+
+    QContactSortOrder sortOrderLastName;
+    sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,
+        QContactName::FieldLastName);
+    sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
+
+    QList<QContactSortOrder> sortOrders;
+    if (order == CntOrderLastFirst || order == CntOrderLastCommaFirst) {
+        sortOrders.append(sortOrderLastName);
+        sortOrders.append(sortOrderFirstName);
+    } else {
+        sortOrders.append(sortOrderFirstName);
+        sortOrders.append(sortOrderLastName);
+    }
+    
+    QContactSortOrder sortOrderOrg;
+    sortOrderOrg.setDetailDefinitionName(QContactOrganization::DefinitionName,
+        QContactOrganization::FieldName);
+    sortOrders.append(sortOrderOrg);
+    
+    d->m_sortOrders = sortOrders;
+}
+
+void CntListModel::refreshModel()
+{
+    CNT_ENTRY
+    
+    setSortOrder();
+    d->m_cache->clearCache();
+    d->m_currentRow = -1;
+    
+    //refresh model
+    updateContactIdsArray();
+
+    beginResetModel();
+    reset();
+    endResetModel();
+    
+    CNT_EXIT
 }
 
 /*!
@@ -241,36 +300,38 @@
  */
 void CntListModel::showMyCard(bool enabled)
 {
-    if (d->showMyCard == enabled) {
+    CNT_ENTRY
+    if (d->m_showMyCard == enabled) {
         return;
     }
     
-    QContactLocalId myCardId = d->mMyCardId;
+    QContactLocalId myCardId = d->m_myCardId;
     if (enabled) {
         //add MyCard to the list
         if (myCardId <= 0) {
             // create a placeholder for MyCard
-            d->contactIds.insert(0, dummyMyCardId);
+            d->m_contactIds.insert(0, dummyMyCardId);
         }
         else {
-            d->contactIds.insert(0, myCardId);
+            d->m_contactIds.insert(0, myCardId);
         }
     }
     else {
         // remove MyCard from the list
         if (myCardId <= 0) {
-            d->contactIds.removeOne(dummyMyCardId);
+            d->m_contactIds.removeOne(dummyMyCardId);
         }
         else {
-            d->contactIds.removeOne(myCardId);
+            d->m_contactIds.removeOne(myCardId);
         }
     }
-    d->showMyCard = enabled;
-    d->currentRow = -1;
+    d->m_showMyCard = enabled;
+    d->m_currentRow = -1;
 
     beginResetModel();
     reset();
     endResetModel();
+    CNT_EXIT
 }
 
 /*!
@@ -280,7 +341,7 @@
  */
 bool CntListModel::myCardStatus() const
 {
-    return d->showMyCard;
+    return d->m_showMyCard;
 }
 
 /*!
@@ -290,7 +351,7 @@
  */
 QContactLocalId CntListModel::myCardId() const
 {
-    return d->mMyCardId;
+    return d->m_myCardId;
 }
 
 /*!
@@ -300,6 +361,8 @@
  */
 int CntListModel::doConstruct()
 {
+    CNT_ENTRY
+    
     int error = initializeData();
     
     // Attach database notifications to handlers.
@@ -307,22 +370,28 @@
     connect(d->m_contactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)), this, SLOT(handleChanged(const QList<QContactLocalId>&)));
     connect(d->m_contactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), this, SLOT(handleRemoved(const QList<QContactLocalId>&)));
     connect(d->m_contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), this, SLOT(handleMyCardChanged(const QContactLocalId&, const QContactLocalId&)));
-
+    connect(d->m_contactManager, SIGNAL(dataChanged()), this, SLOT(refreshModel()));
+    
+    CNT_EXIT
     return error;
 }
 
 /*!
- * Initializes d->contactIds to contain contact Ids from the database.
+ * Initializes d->m_contactIds to contain contact Ids from the database.
  * 
  * \return Error status
  */
 int CntListModel::initializeData()
 {
+    CNT_ENTRY
     int error(QContactManager::NoError);
+    
+    setSortOrder();
 
     // Get a list of all contact IDs in the database.
     updateContactIdsArray();
 
+    CNT_EXIT
     return error;
 }
 
@@ -333,22 +402,24 @@
  */
 void CntListModel::updateContactIdsArray()
 {
-    d->contactIds = d->m_contactManager->contactIds(d->filter,
-            d->sortOrders);
+    CNT_ENTRY
+    d->m_contactIds = d->m_contactManager->contactIds(d->m_filter,
+            d->m_sortOrders);
                       
     //find MyCard contact and move it to the first position
-    QContactLocalId myCardId = d->mMyCardId;
+    QContactLocalId myCardId = d->m_myCardId;
     if (myCardId > 0) {
         // MyCard exists
-        d->contactIds.removeOne(myCardId);
-        if (d->showMyCard) {
-            d->contactIds.insert(0, myCardId);
+        d->m_contactIds.removeOne(myCardId);
+        if (d->m_showMyCard) {
+            d->m_contactIds.insert(0, myCardId);
         }
     } 
-    else if (d->showMyCard) {
+    else if (d->m_showMyCard) {
         // create a placeholder for MyCard
-        d->contactIds.insert(0, dummyMyCardId);
+        d->m_contactIds.insert(0, dummyMyCardId);
     }
+    CNT_EXIT
 }
 
 /*!
@@ -364,11 +435,12 @@
  */
 QContact CntListModel::contact(int row) const
 {
-    if (!validRowId(row) || d->contactIds[row] == dummyMyCardId) {
+    CNT_ENTRY
+    if (!validRowId(row) || d->m_contactIds[row] == dummyMyCardId) {
         return QContact();
     }
-
-    return d->m_contactManager->contact(d->contactIds[row]);
+    CNT_EXIT
+    return d->m_contactManager->contact(d->m_contactIds[row]);
 }
 
 /*!
@@ -390,7 +462,7 @@
  */
 int CntListModel::rowId(const QContactLocalId &contactId) const
 {
-    return d->contactIds.indexOf(contactId);
+    return d->m_contactIds.indexOf(contactId);
 }
 
 /*!
@@ -402,16 +474,17 @@
  */
 QVariant CntListModel::dataForDisplayRole(int row) const
 {
+    CNT_ENTRY
     QStringList list;
     QString name;
     QString infoText;
     bool isSelfContact = false;
     bool isNonEmptySelfContact = false;
     
-    QContactLocalId id = d->contactIds[row];
-    if (d->mMyCardId == id || dummyMyCardId == id) {
+    QContactLocalId id = d->m_contactIds[row];
+    if (d->m_myCardId == id || dummyMyCardId == id) {
         isSelfContact = true;
-        if (d->currentContact.id() == -1) {
+        if (d->m_currentContact.id() == -1) {
             // empty card
             name = hbTrId("txt_phob_dblist_mycard");
             infoText = hbTrId("txt_phob_dblist_mycard_val_create_my_identity");
@@ -422,11 +495,11 @@
     }
 
     if (!isSelfContact || isNonEmptySelfContact) {
-        name = d->currentContact.name();
+        name = d->m_currentContact.name();
         if (name.isEmpty()) {
             name = hbTrId("txt_phob_list_unnamed");
         }
-        infoText = d->currentContact.text();
+        infoText = d->m_currentContact.text();
     }
     
     list << name;
@@ -434,7 +507,7 @@
     if (!isNonEmptySelfContact) {
         list << infoText;
     }
-    
+    CNT_EXIT
     return list;
 }
 
@@ -445,10 +518,12 @@
  */
 void CntListModel::handleAdded(const QList<QContactLocalId>& contactIds)
 {
+    CNT_ENTRY
+    
     //if contacts are added already, no need to do anything
     bool newContacts = false;
     for (int k = 0; k < contactIds.count() && !newContacts; k++) { 
-        if(!d->contactIds.contains(contactIds.at(k))) {
+        if(!d->m_contactIds.contains(contactIds.at(k))) {
             newContacts = true;
         }
     }
@@ -457,15 +532,15 @@
     }
 
     //invalidate cached contact
-    d->currentRow = -1;
+    d->m_currentRow = -1;
     
-    QList<QContactLocalId> oldIdList = d->contactIds;
+    QList<QContactLocalId> oldIdList = d->m_contactIds;
     updateContactIdsArray();
     
     //Find all new contacts (=rows)
     QList<int> newRows;
-    for(int i = 0; i < d->contactIds.count(); i++) {
-        if (!oldIdList.contains(d->contactIds.at(i))) {
+    for(int i = 0; i < d->m_contactIds.count(); i++) {
+        if (!oldIdList.contains(d->m_contactIds.at(i))) {
             newRows.append(i);
         }
     }
@@ -483,6 +558,7 @@
         reset();
         endResetModel();
     }
+    CNT_EXIT
 }
 
 /*!
@@ -492,12 +568,14 @@
  */
 void CntListModel::handleChanged(const QList<QContactLocalId>& contactIds)
 {
+    CNT_ENTRY
+    
     if (contactIds.count() == 0) {
         return;
     }
     
     //invalidate cached contact
-    d->currentRow = -1; 
+    d->m_currentRow = -1; 
 
     int firstChangedContactPosBefore = rowId(contactIds.at(0));  
     updateContactIdsArray();
@@ -517,6 +595,8 @@
         reset();
         endResetModel();
     }
+    
+    CNT_EXIT
 }
 
 /*!
@@ -526,8 +606,10 @@
  */
 void CntListModel::handleRemoved(const QList<QContactLocalId>& contactIds)
 {
+    CNT_ENTRY
+    
     bool removeContacts = false;
-    QList<QContactLocalId> idList = d->contactIds;
+    QList<QContactLocalId> idList = d->m_contactIds;
     for (int k = 0; k < contactIds.count() && !removeContacts; k++) {
         if(idList.contains(contactIds.at(k))) {
             removeContacts = true;
@@ -546,14 +628,14 @@
     }
     
     // invalidate cached contact
-    d->currentRow = -1;
+    d->m_currentRow = -1;
         
     bool removeMyCard(false);
     int myCardRow = -1;
-    if (contactIds.contains(d->mMyCardId)) {
+    if (contactIds.contains(d->m_myCardId)) {
         removeMyCard = true;
-        myCardRow = rowId(d->mMyCardId);    
-        d->mMyCardId = 0;
+        myCardRow = rowId(d->m_myCardId);    
+        d->m_myCardId = 0;
     }
     
     int removeRowsCount=removeRows.count();
@@ -561,7 +643,7 @@
     for(int j = 0; j < removeRows.count(); j++) {
         if (removeMyCard 
              && removeRows.at(j) == myCardRow 
-             && d->showMyCard) {
+             && d->m_showMyCard) {
             QModelIndex index = createIndex(0, 0);
             emit dataChanged(index, index);
             removeRowsCount--;
@@ -575,13 +657,15 @@
     
     // check row count in new list
     // if there is a mismatch, probable late events. reset model
-    QList<QContactLocalId> updatedIdList = d->contactIds;
+    QList<QContactLocalId> updatedIdList = d->m_contactIds;
     int rowsRemoved = idList.count() - updatedIdList.count();
     if (rowsRemoved != removeRowsCount) {
         beginResetModel();
         reset();
         endResetModel();
     }
+    
+    CNT_EXIT
 }
 
 /*!
@@ -590,31 +674,21 @@
  * \param oldId Id of the old MyCard.
  * \param newId Id of the new MyCard.
  */
-void CntListModel::handleMyCardChanged(const QContactLocalId& oldId, const QContactLocalId& newId)
+void CntListModel::handleMyCardChanged(const QContactLocalId& /*oldId*/, const QContactLocalId& newId)
 {
-    int row = rowId(newId);
-
+    CNT_ENTRY
+    
     //invalidate cached contact
-    d->currentRow = -1;
-    d->mMyCardId = newId;
+    d->m_currentRow = -1;
+    d->m_myCardId = newId;
 
-    // if the new mycard was taken from an existing contact,
-    // notify views that that row was removed
-    if (row > 0) {
-        beginRemoveRows(QModelIndex(), row, row);
-        endRemoveRows();
-    }
     updateContactIdsArray();
     
-    // if old mycard is not 0, it means it probably appears in the list
-    if (oldId > 0 && rowId(oldId) > 0) {
-        beginInsertRows(QModelIndex(), rowId(oldId), rowId(oldId));
-        endInsertRows();    
-    }
+    beginResetModel();
+    reset();
+    endResetModel();
     
-    // notify views that mycard was updated
-    QModelIndex index = createIndex(rowId(newId), 0);
-    emit dataChanged(index, index);
+    CNT_EXIT
 }
 
 /*!
@@ -625,9 +699,13 @@
 */
 void CntListModel::handleContactInfoUpdated(QContactLocalId contactId)
 {
+    CNT_ENTRY
+    
     QModelIndex index = createIndex(rowId(contactId), 0);
-    if (index.row() == d->currentRow) {
-        d->currentRow = -1;
+    if (index.row() == d->m_currentRow) {
+        d->m_currentRow = -1;
     }
     emit dataChanged(index, index);
+    
+    CNT_EXIT
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/src/cntpresenceinfoprovider.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,172 @@
+/*
+* 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: Presence info provider plugin for CntListModel. It can provide
+*              the presence information of a contact (icon2 field).
+*
+*/
+
+#include <qtcontacts.h>
+#include "cntpresenceinfoprovider.h"
+
+#include <prcpresencebuddyinfo_qt.h>
+#include <prcpresencereader_qt.h>
+
+CntPresenceInfoProvider::CntPresenceInfoProvider() :
+    iReader(NULL),
+    mManager(NULL)
+{
+    iReader = PrcPresenceReader::createReader();
+    connect(iReader, SIGNAL(signalPresenceNotification(bool , PrcPresenceBuddyInfoQt*)), 
+                           this, SLOT(handlePresenceUpdate(bool , PrcPresenceBuddyInfoQt*)));
+    
+    mManager = new QContactManager("symbian");
+}
+
+CntPresenceInfoProvider::~CntPresenceInfoProvider()
+{
+    delete iReader;
+    delete mManager;
+}
+
+/*!
+    /return the info fields supported by this provider
+ */
+ContactInfoFields CntPresenceInfoProvider::supportedFields() const
+{
+    // this provider has only info for the icon2 field
+    return ContactInfoIcon2Field;
+}
+
+/*!
+    The contact contains all the info this provider needs, so signals with the requested info
+    fields are emitted immediately.
+
+    /param contact the contact for which info is requested
+    /param requestedInfo one or more of the flags in ContactInfoFields
+ */
+void CntPresenceInfoProvider::requestInfo(const QContact& contact, ContactInfoFields requestedInfo)
+{
+    if (requestedInfo & ContactInfoIcon2Field)
+    {
+        QList<QContactOnlineAccount> accounts = contact.details<QContactOnlineAccount>();
+        
+        QList<PrcPresenceBuddyInfoQt*> buddies;
+        
+        foreach (QContactOnlineAccount account, accounts)
+        {
+            QString fullAccount = account.serviceProvider() + ':' + account.accountUri();
+            PrcPresenceBuddyInfoQt* buddy = iReader->presenceInfo(fullAccount);
+            
+            if (buddy)
+            {
+                buddies.append(buddy);
+                if (!mBuddyMap.contains(buddy->buddyId()))
+                {
+                    mBuddyMap.insert(buddy->buddyId(), contact.localId());
+                    iReader->subscribePresenceBuddyChange(buddy->buddyId());
+                }
+            }
+        }
+        
+        if (buddies.count())
+        {
+            QString icon = parsePresence(buddies);
+            
+            if (!icon.isEmpty())
+            {
+                emit infoFieldReady(this, contact.localId(), ContactInfoIcon2Field, icon);
+            }
+            
+            qDeleteAll(buddies);
+        }
+    }
+}
+
+/*!
+    Update presence icon for contact if needed. Stop listening to presence changes for buddy
+    if online account detail was deleted.
+
+    /param aErrorCode error (if any)
+    /param aPresenceBuddyInfo presence buddy that was updated
+ */
+void CntPresenceInfoProvider::handlePresenceUpdate(bool aSuccess, PrcPresenceBuddyInfoQt* aPresenceBuddyInfo)
+{
+    if (aSuccess && aPresenceBuddyInfo != NULL)
+    {
+        QContactLocalId id = mBuddyMap.value(aPresenceBuddyInfo->buddyId());
+        QContact contact = mManager->contact(id);
+        
+        QList<QContactOnlineAccount> accounts = contact.details<QContactOnlineAccount>();
+        
+        QList<PrcPresenceBuddyInfoQt*> buddies;
+        bool accountFound = false;
+        
+        foreach (QContactOnlineAccount account, accounts)
+        {
+            QString fullAccount = account.serviceProvider() + ':' + account.accountUri();
+            PrcPresenceBuddyInfoQt* buddy = iReader->presenceInfo(fullAccount);
+            
+            if (buddy)
+            {
+                buddies.append(buddy);
+                
+                if (fullAccount == aPresenceBuddyInfo->buddyId())
+                {
+                    accountFound = true;
+                }
+                
+                if (!mBuddyMap.contains(buddy->buddyId()))
+                {
+                    mBuddyMap.insert(buddy->buddyId(), contact.localId());
+                    iReader->subscribePresenceBuddyChange(buddy->buddyId());
+                }
+            }
+        }
+        
+        // Account was removed, no need to listen to presence changes anymore
+        if (accounts.isEmpty() || !accountFound)
+        {
+            mBuddyMap.remove(aPresenceBuddyInfo->buddyId());
+            iReader->unSubscribePresenceBuddyChange(aPresenceBuddyInfo->buddyId());
+        }
+
+        if (id > 0)
+        {
+            QString icon = parsePresence(buddies);
+            emit infoFieldReady(this, id, ContactInfoIcon2Field, icon);
+        }
+
+        qDeleteAll(buddies);
+    }
+}
+
+/*!
+    Parse the required presence icon from multiple accounts.
+
+    /param buddyList list of buddies
+ */
+QString CntPresenceInfoProvider::parsePresence(const QList<PrcPresenceBuddyInfoQt*>& buddyList)
+{
+    foreach (PrcPresenceBuddyInfoQt* buddy, buddyList)
+    {
+        PrcPresenceBuddyInfoQt::AvailabilityValues availability = buddy->availability();
+        
+        if (availability == PrcPresenceBuddyInfoQt::PrcAvailable)
+        {
+            return QString("qtg_small_online");
+        }
+    }
+    
+    return QString();
+}
Binary file phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/image1.png has changed
Binary file phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/image2.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/testrunner.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* 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:
+*
+*/
+
+#ifndef TESTRUNNER_H
+#define TESTRUNNER_H
+
+#include <QXmlDefaultHandler>
+
+
+class TestRunner : public QXmlDefaultHandler
+{
+public: // Constructors and destructor
+    TestRunner(const QString& name);
+    ~TestRunner();
+       
+public: // New functions
+    
+    int runTests(QObject& testObject);
+    void printResults();
+    
+protected: // From QXmlContentHandler 
+    bool startElement(
+        const QString& namespaceURI,
+        const QString& localName,
+        const QString& qName,
+        const QXmlAttributes& atts);
+    
+    bool endElement(
+        const QString& namespaceURI,
+        const QString& localName,
+        const QString& qName);
+    
+    bool characters(const QString& ch);
+
+private: // New functions
+
+    void parse(const QString& fileName);
+
+private: // Data
+    QStringList mTestRunParams;
+    QString mHomeDir;
+    int mTestCount;
+    QStringList mErrors;
+    bool mParsingIncidentElement;
+    bool mParsingDescriptionElement;
+    bool mCurrentTestFailed;
+    QString mCurrentTestName;
+    QString mCurrentTestFile;
+    int mCurrentTestFailureLine;
+};
+
+
+#endif // TESTRUNNER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntcache.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QObject>
+#include <qtcontacts.h>
+
+QTM_USE_NAMESPACE
+
+static const int CntTestContacts = 6;
+
+class TestCntCache : public QObject
+{
+    Q_OBJECT
+
+private:
+    void cleanDatabase();
+    QContact createContact(QString firstName, QString lastName, QString phoneNumber, QString imageName);
+
+private slots:
+	void initTestCase();
+	void cleanupTestCase();
+    
+    void construction();
+    void fetchContactInfo();
+    void clearCache();
+	
+private:
+    QContactManager *mContactManager;
+    QContact mContacts[CntTestContacts];
+    QList<int> mContactOrder;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntdefaultinfoprovider.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,42 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QObject>
+#include <qtcontacts.h>
+
+class CntDefaultInfoProvider;
+
+QTM_USE_NAMESPACE
+
+class TestCntDefaultInfoProvider : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void initTestCase();
+    void create();
+    
+    void testSupportedFields();
+    void testRequestInfo();
+    
+    void cleanupTestCase();
+    
+private:
+    CntDefaultInfoProvider    *mCntDefaultInfoProvider;
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntlistmodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,82 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QObject>
+#include <qtcontacts.h>
+
+QTM_BEGIN_NAMESPACE
+class QContactManager;
+QTM_END_NAMESPACE
+
+QTM_USE_NAMESPACE
+
+class CntListModel;
+class ModelListener;
+
+class TestCntListModel : public QObject
+{
+    Q_OBJECT
+
+private:
+    void contactReady(int start, int end);
+
+private slots:
+	void initTestCase();
+	void create();
+	
+	void data();
+	void rowCount();
+	
+	void contact();
+	void indexOfContact();
+	void contactManager();
+	void setFilter();
+	void myCard();
+
+	void rowId();
+	void dataForDisplayRole();
+
+    void handleAdded();
+    void handleChanged();
+    void handleRemoved();
+	void handleMyCardChanged();
+	
+	void cleanupTestCase();
+	
+private:
+    QContactManager *mManager;
+    CntListModel    *mCntModel;
+    ModelListener   *mModelListener;
+    bool             mDataReady;
+
+friend class ModelListener;
+};
+
+class ModelListener : public QObject
+{
+    Q_OBJECT
+
+public:
+    ModelListener(TestCntListModel* parent);
+
+private slots:
+    void onDataChanged(QModelIndex start, QModelIndex end);
+
+private:
+    TestCntListModel* mParent;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/inc/ut_cntpresenceinfoprovider.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QObject>
+#include <qtcontacts.h>
+
+class CntPresenceInfoProvider;
+
+QTM_USE_NAMESPACE
+
+class TestCntPresenceInfoProvider : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void initTestCase();
+    void create();
+    
+    void testSupportedFields();
+    void testRequestInfo();
+
+    void testHandlePresenceUpdate();
+
+    void testParsePresence();
+    
+    void cleanupTestCase();
+    
+private:
+    CntPresenceInfoProvider    *mCntPresenceInfoProvider;
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/runtest.cmd	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,14 @@
+call del MON.sym
+call del MON.dat
+call del profile.txt
+
+call qmake
+call sbs reallyclean
+call sbs -c winscw_udeb
+call sbs -c winscw_udeb
+call qmake
+call ctcwrap -i d -C "EXCLUDE+moc_*.cpp" -C "EXCLUDE+ut_*.*" sbs -c winscw_udeb
+
+call \epoc32\release\winscw\udeb\ut_cntlistmodel.exe -noprompt
+call ctcpost MON.sym MON.dat -p profile.txt
+call ctc2html -i profile.txt -nsb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/main.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,66 @@
+/*
+* 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:
+*
+*/
+
+#include "testrunner.h"
+
+#include "ut_cntlistmodel.h"
+#include "ut_cntcache.h"
+#include "ut_cntpresenceinfoprovider.h"
+#include "ut_cntdefaultinfoprovider.h"
+
+#include <QtTest/QtTest>
+
+int main(int argc, char *argv[]) 
+{
+    bool promptOnExit(true);
+    for (int i=0; i<argc; i++) {
+        if (QString(argv[i]) == "-noprompt")
+            promptOnExit = false;
+    }
+    printf("Running tests...\n");
+            
+    QApplication app(argc, argv);
+    
+    QTranslator translator;
+    QString lang = QLocale::system().name();
+    QString path = "z:/resource/qt/translations/";
+    translator.load(path + "contacts_" + lang);
+    app.installTranslator(&translator);
+
+    TestRunner testRunner("ut_cntlistmodel");
+    
+    TestCntListModel ut_CntListModel;
+    testRunner.runTests(ut_CntListModel);
+    
+    TestCntCache ut_CntCache;
+    testRunner.runTests(ut_CntCache);
+    
+    TestCntPresenceInfoProvider ut_CntPresenceInfoProvider;
+    testRunner.runTests(ut_CntPresenceInfoProvider);
+    
+    TestCntDefaultInfoProvider ut_CntDefaultInfoProvider;
+    testRunner.runTests(ut_CntDefaultInfoProvider);
+
+    testRunner.printResults();
+
+    if (promptOnExit) {
+        printf("Press any key...\n");
+        getchar(); 
+    }
+    return 0;   
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/testrunner.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,152 @@
+/*
+* 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:
+*
+*/
+
+#include "testrunner.h"
+#include <QtTest/QtTest>
+#include <QDir>
+#include <stdio.h>
+
+const char testFunctionElement[] = "TestFunction";
+const char incidentElement[] = "Incident";
+const char descriptionElement[] = "Description";
+const char nameAttr[] = "name";
+const char typeAttr[] = "type";
+const char fileAttr[] = "file";
+const char lineAttr[] = "line";
+const char attrValueFail[] = "fail";
+
+
+TestRunner::TestRunner(const QString& name)
+: mTestCount(0),
+  mParsingIncidentElement(false),
+  mParsingDescriptionElement(false),
+  mCurrentTestFailed(false),
+  mCurrentTestFailureLine(0)
+{
+    mTestRunParams.append(name);
+    mTestRunParams.append("-xml");
+    mTestRunParams.append("-o");
+    mHomeDir = QDir::homePath();
+    mTestRunParams.append(QString()); // Initial result file name
+
+    if (!mHomeDir.endsWith(QString::fromAscii("/")))
+        mHomeDir += QString::fromAscii("/");
+}
+
+TestRunner::~TestRunner()
+{
+}
+
+int TestRunner::runTests(QObject& testObject)
+{
+    QString className(testObject.metaObject()->className());
+    printf("Running tests for %s ... ", className.toUtf8().data());
+    QString resultFileName = mHomeDir + className + ".xml";
+    mTestRunParams.replace(mTestRunParams.count()-1,resultFileName);
+    int errorsBefore = mErrors.count();
+    int error = QTest::qExec(&testObject, mTestRunParams);
+    parse(resultFileName);
+    printf("Failures: %d\n",mErrors.count()-errorsBefore);
+    fflush(stdout);
+    return error;
+}
+
+void TestRunner::printResults()
+{
+    printf("\nTests executed: %d\n",mTestCount);
+    if (mErrors.count() > 0) {
+        printf("Failures (%d):\n", mErrors.count());
+        foreach(QString error, mErrors) {
+            printf("\n%s", error.toUtf8().data());
+        }
+        printf("\n");
+    } else {
+        printf("All passed.\n\n");
+    }
+    fflush(stdout);
+}
+
+void TestRunner::parse(const QString& fileName)
+{
+    QFile file(fileName);
+    QXmlInputSource inputSource(&file);
+    QXmlSimpleReader reader;
+    reader.setContentHandler(this);
+    reader.parse(inputSource);
+}
+
+bool TestRunner::startElement(
+    const QString& /*namespaceURI*/, 
+    const QString& /*localName*/, 
+    const QString& qName, 
+    const QXmlAttributes& atts)
+{
+    if (qName == QString::fromAscii(testFunctionElement)) {
+        mTestCount++;
+        mCurrentTestName = atts.value(QString::fromAscii(nameAttr));
+        return true;
+    }
+    if (qName == QString::fromAscii(incidentElement)) {
+        mParsingIncidentElement = true;
+        if (atts.value(QString::fromAscii(typeAttr)) == QString::fromAscii(attrValueFail)) {
+            mCurrentTestFailed = true;
+            mCurrentTestFile = atts.value(QString::fromAscii(fileAttr));
+            mCurrentTestFailureLine = atts.value(QString::fromAscii(lineAttr)).toInt();
+        }
+        return true;
+    }
+    mParsingDescriptionElement =
+        (qName == QString::fromAscii(descriptionElement));
+    return true;
+}
+
+bool TestRunner::endElement(
+    const QString& /*namespaceURI*/,
+    const QString& /*localName*/,
+    const QString& qName)
+{
+    if (qName == QString::fromAscii(incidentElement)) {
+        mParsingIncidentElement = false;
+        mCurrentTestFailed = false;
+        return true;
+    }
+    if (qName == QString::fromAscii(descriptionElement)) {
+        mParsingDescriptionElement = false;
+    }    
+    return true;
+}
+
+bool TestRunner::characters(const QString& ch)
+{
+    if (mParsingIncidentElement && 
+        mParsingDescriptionElement &&
+        mCurrentTestFailed) {
+        QByteArray testResult = mCurrentTestName.toAscii() + " failed:\n";
+        testResult += "File: ";
+        testResult += mCurrentTestFile.toAscii();
+        testResult += "\n";
+        testResult += "Line: ";
+        testResult += QByteArray::number(mCurrentTestFailureLine);
+        testResult += "\n";
+        testResult += "Reason: ";
+        testResult += ch.toAscii();
+        testResult += "\n";
+        mErrors.append(QString::fromAscii(testResult.data()));
+    }
+    return true;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntcache.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,234 @@
+/*
+* 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:
+*
+*/
+
+#include "ut_cntcache.h"
+#include "cntcache.h"
+#include "cntcache_p.h"
+
+void TestCntCache::initTestCase()
+{
+    mContactManager = new QContactManager("symbian");
+
+    // start with a clean database
+    cleanDatabase();
+
+    // TODO: This test needs to be run with the default provider, so when there is a mechanism
+    //       to variate the info provider, use that mechanism here to select the default provider.
+
+    // create contacts; twins with same image at indexes 0,5 and 2,3 (good for increasing branch coverage)
+    mContacts[0] = createContact("Joe", "Doe", "1234567", "c:/data/images/image1.png");
+    mContacts[1] = createContact("Marja", "Meikalainen", "7654321", "");
+    mContacts[2] = createContact("Sven", "Dufva", "12121212", "c:/data/images/image2.png");
+    mContacts[3] = createContact("Twin", "Dufva", "12121212", "c:/data/images/image2.png");
+    mContacts[4] = createContact("", "", "123123", "");
+    mContacts[5] = createContact("Twin", "Doe", "1234568", "c:/data/images/image1.png");
+}
+
+void TestCntCache::cleanupTestCase()
+{
+    // end with a clean database
+    cleanDatabase();
+
+    delete mContactManager;
+    mContactManager = NULL;
+}
+
+/*
+    Test case: Constructing and deleting the cache.
+ */
+void TestCntCache::construction()
+{
+    // test creation
+    QPointer<CntCache> cache = CntCache::instance();
+    QVERIFY(cache != NULL);
+    QPointer<CntCacheThread> worker = cache->mWorker;
+    QVERIFY(worker != NULL);
+
+    // test singleton property
+    QVERIFY(cache == CntCache::instance());
+
+    // test data members
+    QVERIFY(cache->mContactManager != NULL);
+    QVERIFY(worker->mContactManager != NULL);
+    QVERIFY(worker->mThumbnailManager != NULL);
+    QVERIFY(!worker->mStarted);
+    QVERIFY(!worker->mJobLoopRunning);
+    QVERIFY(!worker->mPostponeJobs);
+    QVERIFY(worker->mDataProviders.count() >= 1);
+
+    // test deletion
+    cache->onShutdown();
+    QVERIFY(cache == NULL);
+    QVERIFY(worker == NULL);
+}
+
+/*
+    Test case: Fetch contact info.
+
+    Fetches all six contacts in two batches of four and two contacts. The contacts are
+    divided up so that one pair of twins is in the same batch and the other pair of twins
+    has one twin in each batch. This maximizes branch coverage.
+ */
+void TestCntCache::fetchContactInfo()
+{
+    CntContactInfo info[CntTestContacts];    // info for each of the contacts
+
+    // create cache and attach a signal spy to it
+    CntCache* cache = CntCache::instance();
+    QSignalSpy spy(cache, SIGNAL(contactInfoUpdated(QContactLocalId)));
+
+    // create list of ids
+    QList<QContactLocalId> idList;
+    for (int i = 0; i < CntTestContacts; ++i) {
+        idList << mContacts[i].localId();
+    }
+
+    // fetch three of the contacts in rapid succession, one of them twice
+    info[1] = cache->fetchContactInfo(1, idList);
+    info[0] = cache->fetchContactInfo(0, idList);
+    info[4] = cache->fetchContactInfo(4, idList);
+    info[0] = cache->fetchContactInfo(0, idList);
+    info[5] = cache->fetchContactInfo(5, idList);
+
+    // check that names are ok
+    QVERIFY(info[1].name() == mContacts[1].displayLabel());
+    QVERIFY(info[0].name() == mContacts[0].displayLabel());
+    QVERIFY(info[4].name() == mContacts[4].displayLabel());
+    QVERIFY(info[5].name() == mContacts[5].displayLabel());
+
+    // wait for possible signals to arrive (in the future, all info could be returned immediately)
+    QTest::qWait(4000);
+    spy.clear();
+
+    // fetch all contacts -- they should be cached now by the read-ahead mechanism
+    for (int i = 0; i < CntTestContacts; ++i) {
+        info[i] = cache->fetchContactInfo(i, idList);
+    }
+
+    // confirm that no further signals from cache (i.e. they were all really cached)
+    QTest::qWait(2000);
+    QVERIFY(spy.count() == 0);
+
+    // confirm that returned data equals created data 
+    for (int i = 0; i < CntTestContacts; ++i) {
+        QVERIFY(info[i].name() == mContacts[i].displayLabel());
+        QVERIFY(info[i].text() == mContacts[i].detail<QContactPhoneNumber>().number());
+    }
+
+    // confirm that info cache contains correct data
+    int cacheItemCount = 0;
+    foreach (CntInfoCacheItem* item, cache->mInfoCache) {
+        // find corresponding contact
+        for (int i = 0; i < CntTestContacts; ++i) {
+            if (mContacts[i].localId() == item->contactId) {
+                QVERIFY(item->name == mContacts[i].displayLabel());
+                QVERIFY(item->text == mContacts[i].detail<QContactPhoneNumber>().number());
+                QVERIFY(item->icons[0].replace('\\', '/') == mContacts[i].detail<QContactAvatar>().imageUrl().toString().replace('\\', '/'));
+                ++cacheItemCount;
+            }
+        }
+    }
+    QVERIFY(cacheItemCount == CntTestContacts);
+
+    // confirm that icon cache contains correct data
+    cacheItemCount = 0;
+    foreach (CntIconCacheItem* item, cache->mIconCache) {
+        // find corresponding contact
+        for (int i = 0; i < CntTestContacts; ++i) {
+            if (mContacts[i].detail<QContactAvatar>().imageUrl().toString().replace('\\','/') == item->iconName.replace('\\','/')) {
+                QVERIFY(item->isFetched);
+                QVERIFY(!item->icon.isNull());
+                ++cacheItemCount;
+            }
+        }
+    }
+    QVERIFY(cacheItemCount == 2*2); // two images, both used by two contacts
+
+    delete cache;
+}
+
+/*
+    Test case: Clear cache.
+ */
+void TestCntCache::clearCache()
+{
+    CntCache* cache = CntCache::instance();
+
+    QList<QContactLocalId> idList;
+    for (int i = 0; i < CntTestContacts; ++i) {
+        idList << mContacts[i].localId();
+    }
+
+    cache->fetchContactInfo(1, idList);
+    cache->fetchContactInfo(3, idList);
+
+    QVERIFY(cache->mInfoCache.count() == 2);
+    QTest::qWait(3000);
+    QVERIFY(cache->mIconCache.count() == 2);
+
+    cache->clearCache();
+    QVERIFY(cache->mInfoCache.count() == 0);    // icon cache needn't be cleared
+    
+    delete cache;
+}
+
+/* TODO: Test cases for overflowing info and icon requests (>30) -- IDs need not be real, just confirm
+         that cancellation notifications eventually arrive */
+
+/*  
+    Helper function for cleaning the database.
+ */
+void TestCntCache::cleanDatabase()
+{
+    QList<QContactLocalId> ids = mContactManager->contactIds();
+    QMap<int, QContactManager::Error> errorMapInit;
+    mContactManager->removeContacts(ids, &errorMapInit);
+    mContactManager->removeContact(mContactManager->selfContactId());
+}
+
+/*  
+    Helper function for creating contacts.
+ */
+QContact TestCntCache::createContact(QString firstName, QString lastName, QString phoneNumber, QString imageName)
+{
+    QContact contact;
+
+    if (!firstName.isEmpty() && !lastName.isEmpty()) {
+        QContactName name;
+        name.setFirstName(firstName);
+        name.setLastName(lastName);
+        contact.saveDetail(&name);
+    }
+
+    if (!phoneNumber.isEmpty()) {
+        QContactPhoneNumber number;
+        number.setNumber(phoneNumber);
+        number.setContexts(QContactDetail::ContextHome);
+        number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+        contact.saveDetail(&number);
+    }
+
+    if (!imageName.isEmpty()) {
+        QContactAvatar avatar;
+        avatar.setImageUrl(imageName);
+        contact.saveDetail(&avatar);
+    }
+
+    mContactManager->saveContact(&contact);
+
+    return contact;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntdefaultinfoprovider.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,92 @@
+/*
+* 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:
+*
+*/
+
+#include "ut_cntdefaultinfoprovider.h"
+#include "cntdefaultinfoprovider.h"
+
+void TestCntDefaultInfoProvider::initTestCase()
+{
+    mCntDefaultInfoProvider = NULL;
+}
+
+void TestCntDefaultInfoProvider::create()
+{
+    mCntDefaultInfoProvider = new CntDefaultInfoProvider();
+}
+
+void TestCntDefaultInfoProvider::testSupportedFields()
+{
+    QVERIFY(mCntDefaultInfoProvider->supportedFields() == ContactInfoIcon1Field | ContactInfoTextField);
+}
+
+void TestCntDefaultInfoProvider::testRequestInfo()
+{
+    QSignalSpy spy(mCntDefaultInfoProvider, SIGNAL(infoFieldReady(CntInfoProvider*, int, ContactInfoField, const QString&)));
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    
+    ContactInfoFields fields;
+    fields = ContactInfoIcon2Field;
+    
+    mCntDefaultInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 0);
+    
+    fields = ContactInfoIcon1Field | ContactInfoTextField;
+    
+    mCntDefaultInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 0);
+    
+    QContactPhoneNumber number;
+    number.setNumber("1234567");
+    number.setContexts(QContactDetail::ContextHome);
+    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+    c.saveDetail(&number);
+    
+    mCntDefaultInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 1);
+    spy.clear();
+    
+    c.setPreferredDetail("call", number);
+    
+    mCntDefaultInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 1);
+    spy.clear();
+    
+    QContactAvatar avatar;
+    c.saveDetail(&avatar);
+    
+    mCntDefaultInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 1);
+    spy.clear();
+    
+    avatar.setImageUrl(QUrl("dummyavatar"));
+    c.saveDetail(&avatar);
+    
+    mCntDefaultInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 2);
+}
+
+void TestCntDefaultInfoProvider::cleanupTestCase()
+{
+    delete mCntDefaultInfoProvider;
+    mCntDefaultInfoProvider = NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntlistmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,485 @@
+/*
+* 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:
+*
+*/
+
+#include "ut_cntlistmodel.h"
+#include "cntlistmodel.h"
+#include "cntlistmodel_p.h"
+
+#include <hbnamespace.h>
+#include <qtcontacts.h>
+#include <QUrl>
+
+void TestCntListModel::initTestCase()
+{
+    //let's have clean database before running tests 
+    mManager = new QContactManager("symbian");
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMapInit;
+    mManager->removeContacts(ids, &errorMapInit);
+    mManager->removeContact(mManager->selfContactId());
+}
+
+void TestCntListModel::contactReady(int startRow, int endRow)
+{
+    QVERIFY(startRow == endRow);
+    mDataReady = true;
+}
+
+void TestCntListModel::create()
+{
+    mCntModel = new CntListModel();
+    QVERIFY(mCntModel != NULL);
+    QVERIFY(mCntModel->rowCount() == 1);
+    QVERIFY(mCntModel->d->m_cache);
+    QVERIFY(mCntModel->d->m_ownedContactManager);
+    QVERIFY(mCntModel->d->m_contactManager != NULL);
+    
+    delete mCntModel;
+    mCntModel = NULL;
+    
+    mCntModel = new CntListModel(mManager);
+    QVERIFY(mCntModel != NULL);
+    QCOMPARE(mCntModel->rowCount(), 1);
+    QVERIFY(mCntModel->rowCount() == 1);
+    QVERIFY(mCntModel->d->m_cache);
+    QVERIFY(!mCntModel->d->m_ownedContactManager);
+    QVERIFY(mCntModel->d->m_contactManager != NULL);
+}
+
+void TestCntListModel::data()
+{
+    mModelListener = new ModelListener(this);
+    mDataReady = false;
+
+    //create and save contact
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QContactPhoneNumber number;
+    number.setNumber("1234567");
+    number.setContexts(QContactDetail::ContextHome);
+    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+    c.saveDetail(&number);
+    QContactEmailAddress email;
+    email.setEmailAddress("dummyemail");
+    c.saveDetail(&email);
+    QVERIFY(mManager->saveContact(&c));
+    QTest::qWait(1000);
+    
+    //check invalid row and column
+    QVariant ret;
+    ret = mCntModel->data(QModelIndex(), Qt::UserRole);
+    QVERIFY(ret.isNull());
+    
+    //check the saved contact's info
+    QModelIndex modelIndex = mCntModel->indexOfContact(c);
+    int row = modelIndex.row();
+    QContact contactFromModel = mCntModel->contact(modelIndex);
+    QVERIFY(c == contactFromModel);
+    
+    ret = mCntModel->data(modelIndex, Qt::UserRole); 
+    QVERIFY(ret.isNull());
+    
+    ret = mCntModel->data(modelIndex, Qt::DisplayRole); 
+    QVERIFY(ret.type() == QVariant::StringList);
+    QStringList displayContent;
+    displayContent = ret.toStringList();
+    QVERIFY(displayContent.count() == 2);
+    QVERIFY(displayContent.at(0) == "firstname lastname");
+    // second string is only an empty placeholder, e.g. " ", until cache has fetched the value
+
+    // wait for cache to signal that all contact info is ready
+    while (!mDataReady) { QTest::qWait(200); QApplication::processEvents(); }
+    mDataReady = false;
+    ret = mCntModel->data(modelIndex, Qt::DisplayRole); 
+
+    QVERIFY(ret.type() == QVariant::StringList);
+    displayContent = ret.toStringList();
+    QVERIFY(displayContent.count() == 2);
+    QVERIFY(displayContent.at(0) == "firstname lastname");
+    QVERIFY(displayContent.at(1) == "1234567");
+   
+    // check backgroundrole
+    ret = mCntModel->data(modelIndex, Qt::BackgroundRole); 
+    QVERIFY(ret.isNull());
+    
+    //check decoration role
+    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
+    QVERIFY(ret.type() == QVariant::List);
+    
+    ret = mCntModel->data(modelIndex, Hb::IndexFeedbackRole); 
+    QVERIFY(ret.type() == QVariant::String);
+
+    // add empty avatar and check decoration
+    QContactAvatar avatar;
+    c.saveDetail(&avatar);
+    QVERIFY(mManager->saveContact(&c));
+    QTest::qWait(1000);
+    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
+    QVERIFY(ret.type() == QVariant::List);
+    
+    // add data to the avatar and check decoration
+    avatar.setImageUrl(QUrl("dummyimagepath"));
+    c.saveDetail(&avatar);
+    QVERIFY(mManager->saveContact(&c));
+    QTest::qWait(1000);
+    modelIndex = mCntModel->indexOfContact(c);
+    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
+
+    // wait for cache to signal that all contact info is ready
+    while (!mDataReady) { QTest::qWait(200); QApplication::processEvents(); }
+    mDataReady = false;
+    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
+    QVERIFY(ret.type() == QVariant::List);
+    
+    // check MyCard info from the model
+    modelIndex = mCntModel->index(0, 0);
+    ret = mCntModel->data(modelIndex, Qt::BackgroundRole);
+    QVERIFY(!ret.isNull());
+    
+    // create and assign empty MyCard
+    QContact myCard;
+    QVERIFY(mManager->saveContact(&myCard));
+    QTest::qWait(1000);
+    mManager->setSelfContactId(myCard.localId());
+    QTest::qWait(1000);
+    
+    // check that MyCard was really saved
+    QCOMPARE(mCntModel->myCardId(), myCard.localId());
+    
+    // check MyCard info from the model
+    myCard = mManager->contact(mManager->selfContactId());
+    modelIndex = mCntModel->indexOfContact(myCard);
+    ret = mCntModel->data(modelIndex, Qt::BackgroundRole);
+    QVERIFY(!ret.isNull());
+    
+    ret = mCntModel->data(modelIndex, Qt::DisplayRole);
+    QVERIFY(ret.type() == QVariant::StringList);
+    displayContent = ret.toStringList();
+    QVERIFY(displayContent.count() == 1); // "Unnamed"
+    
+    // add some content to MyCard
+    myCard.saveDetail(&number);
+    QVERIFY(mManager->saveContact(&myCard));
+    QTest::qWait(1000);
+    ret = mCntModel->data(modelIndex, Qt::DisplayRole);
+    // wait for cache
+    QTest::qWait(1000);
+    ret = mCntModel->data(modelIndex, Qt::DisplayRole);
+    QVERIFY(ret.type() == QVariant::StringList);
+    displayContent = ret.toStringList();
+    QVERIFY(displayContent.contains(hbTrId("txt_phob_list_unnamed")));
+    
+    ret = mCntModel->data(modelIndex, Hb::IndexFeedbackRole); 
+    QVERIFY(ret.isNull());
+}
+
+void TestCntListModel::rowCount()
+{
+    // we should have 2 contacts in the model saved from the last test case
+    QTest::qWait(5000);
+    QCOMPARE(mCntModel->rowCount(), 2);
+}
+
+void TestCntListModel::contact()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMapContact;
+    mManager->removeContacts(ids,&errorMapContact);
+    QTest::qWait(1000);
+    
+    QModelIndex modelIndex = mCntModel->index(0, 0);
+    QContact empty = mCntModel->contact(modelIndex);
+    //QVERIFY(empty.isEmpty());
+    
+    //create and save contact
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QContactPhoneNumber number;
+    number.setNumber("1234567");
+    number.setContexts(QContactDetail::ContextHome);
+    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+    c.saveDetail(&number);
+    QContactEmailAddress email;
+    email.setEmailAddress("dummyemail");
+    c.saveDetail(&email);
+    QVERIFY(mManager->saveContact(&c));
+    QTest::qWait(1000);
+    
+    modelIndex = mCntModel->index(10, 0);
+    c = mCntModel->contact(modelIndex);
+    QVERIFY(c.isEmpty());
+    
+    modelIndex = mCntModel->index(1, 0);
+    c = mCntModel->contact(modelIndex);
+    QVERIFY(!c.isEmpty());
+}
+
+void TestCntListModel::indexOfContact()
+{
+    QModelIndex modelIndex = mCntModel->index(1, 0);
+    QContact c = mCntModel->contact(modelIndex);
+    
+    QVERIFY(mCntModel->indexOfContact(c) == modelIndex);
+}
+
+void TestCntListModel::contactManager()
+{
+    QVERIFY(mManager == &(mCntModel->contactManager()));
+}
+
+void TestCntListModel::setFilter()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+    
+    QContactUnionFilter unionFilter;
+
+    QContactDetailFilter landlineFilter;
+    landlineFilter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldSubTypes); 
+    landlineFilter.setValue(QLatin1String(QContactPhoneNumber::SubTypeLandline));
+    unionFilter << landlineFilter;
+
+    QContactDetailFilter mobileFilter;
+    mobileFilter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldSubTypes); 
+    mobileFilter.setValue(QLatin1String(QContactPhoneNumber::SubTypeMobile));
+    unionFilter << mobileFilter;
+    
+    mCntModel->setFilter(unionFilter);
+    
+    QModelIndex modelIndex = mCntModel->indexOfContact(c);
+    QVERIFY(modelIndex.row() < 0);
+    QVERIFY(mCntModel->d->m_filter == unionFilter);
+    QVERIFY(mCntModel->d->m_sortOrders.count() == 3);
+}
+
+void TestCntListModel::myCard()
+{
+    delete mCntModel;
+    mCntModel = 0;
+    
+    mCntModel = new CntListModel(mManager);
+    
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+    
+    QSignalSpy spy(mCntModel, SIGNAL(modelReset()));
+    
+    QVERIFY(mCntModel->myCardStatus());
+    
+    mCntModel->showMyCard(false);
+    QVERIFY(!mCntModel->myCardStatus());
+    QCOMPARE(spy.count(), 2);
+    
+    mCntModel->showMyCard(true);
+    QVERIFY(mCntModel->myCardStatus());
+    QCOMPARE(spy.count(), 4);
+    
+    mManager->setSelfContactId(c.localId());
+    QTest::qWait(1000);
+    spy.clear();
+    
+    mCntModel->showMyCard(false);
+    QVERIFY(!mCntModel->myCardStatus());
+    QCOMPARE(spy.count(), 2);
+    
+    mCntModel->showMyCard(true);
+    QVERIFY(mCntModel->myCardStatus());
+    QCOMPARE(spy.count(), 4);
+    mCntModel->showMyCard(true);
+    QVERIFY(mCntModel->myCardStatus());
+    QCOMPARE(spy.count(), 4);
+}
+
+void TestCntListModel::rowId()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+    
+    int row = mCntModel->rowId(c.localId());
+    QVERIFY(row > 0);
+    QVERIFY(mCntModel->validRowId(row));
+    QVERIFY(!mCntModel->validRowId(-100));
+    QVERIFY(!mCntModel->validRowId(100));
+}
+
+void TestCntListModel::dataForDisplayRole()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+    
+    int row = mCntModel->rowId(c.localId());
+    QVariant var = mCntModel->dataForDisplayRole(row);
+    QVERIFY(var.type() == QVariant::StringList);
+    
+    var = mCntModel->dataForDisplayRole(0);
+    QVERIFY(var.type() == QVariant::StringList);
+}
+
+void TestCntListModel::handleAdded()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+
+    QSignalSpy spy(mCntModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)));
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+
+    QCOMPARE(spy.count(), 1);
+    
+    QList<QContactLocalId> emptyList;
+    mCntModel->handleAdded(emptyList);
+    QCOMPARE(spy.count(), 1);
+}
+
+void TestCntListModel::handleChanged()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+    
+    QSignalSpy spy(mCntModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex&)));
+
+    name.setMiddleName("mid");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+
+    QCOMPARE(spy.count(), 1);
+    
+    QList<QContactLocalId> emptyList;
+    mCntModel->handleChanged(emptyList);
+    QCOMPARE(spy.count(), 1);
+}
+
+void TestCntListModel::handleRemoved()
+{
+    QSignalSpy spy(mCntModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
+    
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QCOMPARE(spy.count(), 1);
+    
+    QList<QContactLocalId> emptyList;
+    mCntModel->handleRemoved(emptyList);
+    QCOMPARE(spy.count(), 1);
+}
+
+void TestCntListModel::handleMyCardChanged()
+{
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids,&errorMap);
+    QTest::qWait(1000);
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QVERIFY(mManager->saveContact(&c));
+    
+    mCntModel->handleMyCardChanged(0, c.localId());
+    QVERIFY(mCntModel->d->m_myCardId == c.localId());
+}
+
+void TestCntListModel::cleanupTestCase()
+{
+    mCntModel->d->m_cache->onShutdown();
+    delete mCntModel;
+    mCntModel = 0;
+    
+    //let's have clean database after running tests
+    QList<QContactLocalId> ids = mManager->contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    mManager->removeContacts(ids, &errorMap);
+    delete mManager;
+    mManager = 0;
+    delete mModelListener;
+    mModelListener = 0;
+}
+
+
+ModelListener::ModelListener(TestCntListModel* parent)
+    : mParent(parent)
+{
+    connect(mParent->mCntModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(onDataChanged(QModelIndex,QModelIndex)));
+}
+
+void ModelListener::onDataChanged(QModelIndex start, QModelIndex end)
+{
+    mParent->contactReady(start.row(), end.row());
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/src/ut_cntpresenceinfoprovider.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,190 @@
+/*
+* 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:
+*
+*/
+
+#include "ut_cntpresenceinfoprovider.h"
+#include "cntpresenceinfoprovider.h"
+
+#include <prcpresencebuddyinfo_qt.h>
+#include <prcpresencereader_qt.h>
+#include <prcpresencewriter_qt.h>
+
+void TestCntPresenceInfoProvider::initTestCase()
+{
+    mCntPresenceInfoProvider = NULL;
+}
+
+void TestCntPresenceInfoProvider::create()
+{
+    mCntPresenceInfoProvider = new CntPresenceInfoProvider();
+}
+
+void TestCntPresenceInfoProvider::testSupportedFields()
+{
+    QVERIFY(mCntPresenceInfoProvider->supportedFields() == ContactInfoIcon2Field);
+}
+
+void TestCntPresenceInfoProvider::testRequestInfo()
+{
+    PrcPresenceWriter *writer = PrcPresenceWriter::createWriter();
+    
+    PrcPresenceBuddyInfoQt *buddy = PrcPresenceBuddyInfoQt::createInstance();
+    buddy->setIdentity("sip:test@test.com");
+    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcNotAvailable, "meh");
+    writer->writePresence(*buddy);
+    
+    QContactManager manager("symbian");
+    
+    QContact c;
+    QContactName name;
+    name.setFirstName("firstname");
+    name.setLastName("lastname");
+    c.saveDetail(&name);
+    QContactPhoneNumber number;
+    number.setNumber("1234567");
+    number.setContexts(QContactDetail::ContextHome);
+    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+    c.saveDetail(&number);
+    manager.saveContact(&c);
+    
+    ContactInfoFields fields;
+    fields = ContactInfoTextField;
+    
+    QSignalSpy spy(mCntPresenceInfoProvider, SIGNAL(infoFieldReady(CntInfoProvider*, int, ContactInfoField, const QString&)));
+    
+    mCntPresenceInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 0);
+    QVERIFY(mCntPresenceInfoProvider->mBuddyMap.isEmpty());
+    
+    fields = ContactInfoIcon2Field;
+    
+    mCntPresenceInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 0);
+    QVERIFY(mCntPresenceInfoProvider->mBuddyMap.isEmpty());
+    
+    QContactOnlineAccount account;
+    account.setSubTypes(QStringList() << QContactOnlineAccount::SubTypeSip);
+    account.setServiceProvider("sip");
+    account.setAccountUri("test@test.com");
+    c.saveDetail(&account);
+    QContactOnlineAccount account2;
+    account2.setSubTypes(QStringList() << QContactOnlineAccount::SubTypeSipVoip);
+    account.setServiceProvider("sip");
+    account2.setAccountUri("test@test.com");
+    c.saveDetail(&account2);
+    QContactOnlineAccount account3;
+    account3.setSubTypes(QStringList() << QContactOnlineAccount::SubTypeSip);
+    account3.setAccountUri("malformatted");
+    c.saveDetail(&account3);
+    manager.saveContact(&c);
+    
+    mCntPresenceInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy.count(), 0);
+    QCOMPARE(mCntPresenceInfoProvider->mBuddyMap.count(), 1);
+    
+    delete mCntPresenceInfoProvider;
+    mCntPresenceInfoProvider = NULL;
+    
+    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcAvailable, "meh");
+    writer->writePresence(*buddy);
+    
+    mCntPresenceInfoProvider = new CntPresenceInfoProvider();
+    
+    QSignalSpy spy2(mCntPresenceInfoProvider, SIGNAL(infoFieldReady(CntInfoProvider*, int, ContactInfoField, const QString&)));
+    mCntPresenceInfoProvider->requestInfo(c, fields);
+    QCOMPARE(spy2.count(), 1);
+    QCOMPARE(mCntPresenceInfoProvider->mBuddyMap.count(), 1);
+    
+    delete buddy;
+    delete writer;
+}
+
+void TestCntPresenceInfoProvider::testHandlePresenceUpdate()
+{
+    QSignalSpy spy(mCntPresenceInfoProvider, SIGNAL(infoFieldReady(CntInfoProvider*, int, ContactInfoField, const QString&)));
+    
+    PrcPresenceWriter *writer = PrcPresenceWriter::createWriter();
+    PrcPresenceReader *reader = PrcPresenceReader::createReader();
+    
+    PrcPresenceBuddyInfoQt *dummyBuddy = PrcPresenceBuddyInfoQt::createInstance();
+    dummyBuddy->setIdentity("sip:dummy@dummy.com");
+    dummyBuddy->setAvailability(PrcPresenceBuddyInfoQt::PrcAvailable, "meh");
+    writer->writePresence(*dummyBuddy);
+    
+    mCntPresenceInfoProvider->handlePresenceUpdate(true, dummyBuddy);
+    QCOMPARE(spy.count(), 0);
+
+    mCntPresenceInfoProvider->handlePresenceUpdate(false, dummyBuddy);
+    QCOMPARE(spy.count(), 0);
+
+    mCntPresenceInfoProvider->handlePresenceUpdate(true, NULL);
+    QCOMPARE(spy.count(), 0);
+    
+    PrcPresenceBuddyInfoQt *buddy = reader->presenceInfo("sip:test@test.com");
+    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcNotAvailable, "meh");
+    writer->writePresence(*buddy);
+    QTest::qWait(5000);
+    QCOMPARE(spy.count(), 1);
+    
+    QContactManager manager("symbian");
+    QContact c = manager.contact(mCntPresenceInfoProvider->mBuddyMap.value("sip:test@test.com"));
+    
+    QList<QContactOnlineAccount> accounts = c.details<QContactOnlineAccount>();
+    foreach (QContactOnlineAccount account, accounts)
+    {
+        c.removeDetail(&account);
+    }
+    manager.saveContact(&c);
+    
+    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcAvailable, "meh");
+    writer->writePresence(*buddy);
+    QTest::qWait(5000);
+    QCOMPARE(spy.count(), 2);
+    
+    delete writer;
+    delete reader;
+    delete dummyBuddy;
+    delete buddy;
+}
+
+void TestCntPresenceInfoProvider::testParsePresence()
+{
+    PrcPresenceBuddyInfoQt *buddy = PrcPresenceBuddyInfoQt::createInstance();
+    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcNotAvailable, "meh");
+
+    QList<PrcPresenceBuddyInfoQt*> buddies;
+    buddies.append(buddy);
+
+    QVERIFY(mCntPresenceInfoProvider->parsePresence(buddies).isEmpty());
+
+    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcAvailable, "meh");
+
+    QVERIFY(mCntPresenceInfoProvider->parsePresence(buddies) == "qtg_small_online");
+    
+    delete buddy;
+}
+
+void TestCntPresenceInfoProvider::cleanupTestCase()
+{
+    delete mCntPresenceInfoProvider;
+    mCntPresenceInfoProvider = NULL;
+    
+    QContactManager manager("symbian");
+    QList<QContactLocalId> ids = manager.contactIds();
+    QMap<int, QContactManager::Error> errorMap;
+    manager.removeContacts(ids, &errorMap);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntlistmodel/tsrc/ut_cntlistmodel/ut_cntlistmodel.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,75 @@
+#                                                                    
+# 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:                                                        
+#                                                                     
+#
+
+
+TEMPLATE = app
+TARGET =
+
+DEFINES += QT_NO_DEBUG_OUTPUT
+DEFINES += QT_NO_WARNING_OUTPUT
+DEFINES += CNTLISTMODEL_NO_EXPORT
+    
+MOC_DIR = moc
+
+QT += testlib xml
+
+CONFIG += hb
+
+TARGET.CAPABILITY = ALL \
+    -TCB
+
+INCLUDEPATH += .
+INCLUDEPATH += ../../inc
+INCLUDEPATH += ../../../../inc
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+    
+HEADERS += inc/testrunner.h \
+           inc/ut_cntlistmodel.h \
+           inc/ut_cntcache.h \
+           inc/ut_cntpresenceinfoprovider.h \
+           inc/ut_cntdefaultinfoprovider.h \
+           ../../inc/cntlistmodelglobal.h \
+           ../../inc/cntlistmodel.h \
+           ../../inc/cntlistmodel_p.h \
+           ../../inc/cntcache.h \
+           ../../inc/cntcache_p.h \
+           ../../inc/cntinfoprovider.h \
+           ../../inc/cntdefaultinfoprovider.h \
+           ../../inc/cntpresenceinfoprovider.h \
+           ../../../../inc/cntdebug.h
+
+SOURCES += src/testrunner.cpp \
+           src/main.cpp \
+           src/ut_cntlistmodel.cpp \
+           src/ut_cntcache.cpp \
+           src/ut_cntpresenceinfoprovider.cpp \
+           src/ut_cntdefaultinfoprovider.cpp \
+           ../../src/cntlistmodel.cpp \
+           ../../src/cntcache.cpp \
+           ../../src/cntcache_p.cpp \
+           ../../src/cntdefaultinfoprovider.cpp \
+           ../../src/cntpresenceinfoprovider.cpp
+
+BLD_INF_RULES.prj_exports += "image1.png /epoc32/winscw/c/data/images/"
+BLD_INF_RULES.prj_exports += "image2.png /epoc32/winscw/c/data/images/"
+    
+LIBS += -lQtContacts \
+        -lhbcore \
+        -lthumbnailmanagerqt \
+        -lpresencecacheqt \
+        -lxqsettingsmanager
+
Binary file phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/image1.png has changed
Binary file phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/image2.png has changed
--- a/phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/inc/testrunner.h	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
-* 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:
-*
-*/
-
-#ifndef TESTRUNNER_H
-#define TESTRUNNER_H
-
-#include <QXmlDefaultHandler>
-
-
-class TestRunner : public QXmlDefaultHandler
-{
-public: // Constructors and destructor
-    TestRunner(const QString& name);
-    ~TestRunner();
-       
-public: // New functions
-    
-    int runTests(QObject& testObject);
-    void printResults();
-    
-protected: // From QXmlContentHandler 
-    bool startElement(
-        const QString& namespaceURI,
-        const QString& localName,
-        const QString& qName,
-        const QXmlAttributes& atts);
-    
-    bool endElement(
-        const QString& namespaceURI,
-        const QString& localName,
-        const QString& qName);
-    
-    bool characters(const QString& ch);
-
-private: // New functions
-
-    void parse(const QString& fileName);
-
-private: // Data
-    QStringList mTestRunParams;
-    QString mHomeDir;
-    int mTestCount;
-    QStringList mErrors;
-    bool mParsingIncidentElement;
-    bool mParsingDescriptionElement;
-    bool mCurrentTestFailed;
-    QString mCurrentTestName;
-    QString mCurrentTestFile;
-    int mCurrentTestFailureLine;
-};
-
-
-#endif // TESTRUNNER_H
--- a/phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/inc/ut_mobcntmodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
-* 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:
-*
-*/
-
-#include <QtTest/QtTest>
-#include <QObject>
-#include <qtcontacts.h>
-
-QTM_BEGIN_NAMESPACE
-class QContactManager;
-QTM_END_NAMESPACE
-
-QTM_USE_NAMESPACE
-
-class CntListModel;
-class ModelListener;
-
-class TestMobCntModel : public QObject
-{
-    Q_OBJECT
-
-private:
-    void contactReady(int start, int end);
-
-private slots:
-	void initTestCase();
-	void create();
-	
-	void data();
-	void rowCount();
-	
-	void contact();
-	void indexOfContact();
-	void contactManager();
-	void setFilterAndSortOrder();
-	void myCard();
-
-	void rowId();
-	void dataForDisplayRole();
-
-    void handleAdded();
-    void handleChanged();
-    void handleRemoved();
-	void handleMyCardChanged();
-	
-	void cleanupTestCase();
-	
-private:
-    QContactManager *mManager;
-    CntListModel    *mCntModel;
-    ModelListener   *mModelListener;
-    bool             mDataReady;
-
-friend class ModelListener;
-};
-
-class ModelListener : public QObject
-{
-    Q_OBJECT
-
-public:
-    ModelListener(TestMobCntModel* parent);
-
-private slots:
-    void onDataChanged(QModelIndex start, QModelIndex end);
-
-private:
-    TestMobCntModel* mParent;
-};
--- a/phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/src/main.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
-* 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:
-*
-*/
-
-#include "testrunner.h"
-
-#include "ut_mobcntmodel.h"
-
-#include <QtTest/QtTest>
-
-int main(int argc, char *argv[]) 
-{
-    bool promptOnExit(true);
-    for (int i=0; i<argc; i++) {
-        if (QString(argv[i]) == "-noprompt")
-            promptOnExit = false;
-    }
-    printf("Running tests...\n");
-            
-    QApplication app(argc, argv);
-    
-    TestRunner testRunner("ut_mobcntmodel");
-    
-    TestMobCntModel ut_MobCntModel;
-    testRunner.runTests(ut_MobCntModel);
-
-    testRunner.printResults();
-
-    if (promptOnExit) {
-        printf("Press any key...\n");
-        getchar(); 
-    }
-    return 0;   
-}
-
--- a/phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/src/testrunner.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/*
-* 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:
-*
-*/
-
-#include "testrunner.h"
-#include <QtTest/QtTest>
-#include <QDir>
-#include <stdio.h>
-
-const char testFunctionElement[] = "TestFunction";
-const char incidentElement[] = "Incident";
-const char descriptionElement[] = "Description";
-const char nameAttr[] = "name";
-const char typeAttr[] = "type";
-const char fileAttr[] = "file";
-const char lineAttr[] = "line";
-const char attrValueFail[] = "fail";
-
-
-TestRunner::TestRunner(const QString& name)
-: mTestCount(0),
-  mParsingIncidentElement(false),
-  mParsingDescriptionElement(false),
-  mCurrentTestFailed(false),
-  mCurrentTestFailureLine(0)
-{
-    mTestRunParams.append(name);
-    mTestRunParams.append("-xml");
-    mTestRunParams.append("-o");
-    mHomeDir = QDir::homePath();
-    mTestRunParams.append(QString()); // Initial result file name
-
-    if (!mHomeDir.endsWith(QString::fromAscii("/")))
-        mHomeDir += QString::fromAscii("/");
-}
-
-TestRunner::~TestRunner()
-{
-}
-
-int TestRunner::runTests(QObject& testObject)
-{
-    QString className(testObject.metaObject()->className());
-    printf("Running tests for %s ... ", className.toUtf8().data());
-    QString resultFileName = mHomeDir + className + ".xml";
-    mTestRunParams.replace(mTestRunParams.count()-1,resultFileName);
-    int errorsBefore = mErrors.count();
-    int error = QTest::qExec(&testObject, mTestRunParams);
-    parse(resultFileName);
-    printf("Failures: %d\n",mErrors.count()-errorsBefore);
-    fflush(stdout);
-    return error;
-}
-
-void TestRunner::printResults()
-{
-    printf("\nTests executed: %d\n",mTestCount);
-    if (mErrors.count() > 0) {
-        printf("Failures (%d):\n", mErrors.count());
-        foreach(QString error, mErrors) {
-            printf("\n%s", error.toUtf8().data());
-        }
-        printf("\n");
-    } else {
-        printf("All passed.\n\n");
-    }
-    fflush(stdout);
-}
-
-void TestRunner::parse(const QString& fileName)
-{
-    QFile file(fileName);
-    QXmlInputSource inputSource(&file);
-    QXmlSimpleReader reader;
-    reader.setContentHandler(this);
-    reader.parse(inputSource);
-}
-
-bool TestRunner::startElement(
-    const QString& /*namespaceURI*/, 
-    const QString& /*localName*/, 
-    const QString& qName, 
-    const QXmlAttributes& atts)
-{
-    if (qName == QString::fromAscii(testFunctionElement)) {
-        mTestCount++;
-        mCurrentTestName = atts.value(QString::fromAscii(nameAttr));
-        return true;
-    }
-    if (qName == QString::fromAscii(incidentElement)) {
-        mParsingIncidentElement = true;
-        if (atts.value(QString::fromAscii(typeAttr)) == QString::fromAscii(attrValueFail)) {
-            mCurrentTestFailed = true;
-            mCurrentTestFile = atts.value(QString::fromAscii(fileAttr));
-            mCurrentTestFailureLine = atts.value(QString::fromAscii(lineAttr)).toInt();
-        }
-        return true;
-    }
-    mParsingDescriptionElement =
-        (qName == QString::fromAscii(descriptionElement));
-    return true;
-}
-
-bool TestRunner::endElement(
-    const QString& /*namespaceURI*/,
-    const QString& /*localName*/,
-    const QString& qName)
-{
-    if (qName == QString::fromAscii(incidentElement)) {
-        mParsingIncidentElement = false;
-        mCurrentTestFailed = false;
-        return true;
-    }
-    if (qName == QString::fromAscii(descriptionElement)) {
-        mParsingDescriptionElement = false;
-    }    
-    return true;
-}
-
-bool TestRunner::characters(const QString& ch)
-{
-    if (mParsingIncidentElement && 
-        mParsingDescriptionElement &&
-        mCurrentTestFailed) {
-        QByteArray testResult = mCurrentTestName.toAscii() + " failed:\n";
-        testResult += "File: ";
-        testResult += mCurrentTestFile.toAscii();
-        testResult += "\n";
-        testResult += "Line: ";
-        testResult += QByteArray::number(mCurrentTestFailureLine);
-        testResult += "\n";
-        testResult += "Reason: ";
-        testResult += ch.toAscii();
-        testResult += "\n";
-        mErrors.append(QString::fromAscii(testResult.data()));
-    }
-    return true;
-}
-
--- a/phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/src/ut_mobcntmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,474 +0,0 @@
-/*
-* 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:
-*
-*/
-
-#include "ut_mobcntmodel.h"
-#include "cntlistmodel.h"
-#include "cntlistmodel_p.h"
-
-#include <qtcontacts.h>
-#include <QUrl>
-
-void TestMobCntModel::initTestCase()
-{
-    //let's have clean database before running tests 
-    mManager = new QContactManager("symbian");
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMapInit;
-    mManager->removeContacts(ids, &errorMapInit);
-}
-
-void TestMobCntModel::contactReady(int startRow, int endRow)
-{
-    QVERIFY(startRow == endRow);
-    mDataReady = true;
-}
-
-void TestMobCntModel::create()
-{
-    mCntModel = new CntListModel();
-    QVERIFY(mCntModel != 0);
-    QVERIFY(mCntModel->rowCount() == 1);
-    QVERIFY(mCntModel->d->m_cache);
-    QVERIFY(mCntModel->d->ownedContactManager);
-    QVERIFY(mCntModel->d->m_contactManager != 0);
-    
-    delete mCntModel;
-    mCntModel = 0;
-    
-    mCntModel = new CntListModel(mManager);
-    QVERIFY(mCntModel != 0);
-    QCOMPARE(mCntModel->rowCount(),1);
-    QVERIFY(mCntModel->rowCount() == 1);
-    QVERIFY(mCntModel->d->m_cache);
-    QVERIFY(!mCntModel->d->ownedContactManager);
-    QVERIFY(mCntModel->d->m_contactManager != 0);
-}
-
-void TestMobCntModel::data()
-{
-    mModelListener = new ModelListener(this);
-    mDataReady = false;
-
-    //create and save contact
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QContactPhoneNumber number;
-    number.setNumber("1234567");
-    number.setContexts(QContactDetail::ContextHome);
-    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
-    c.saveDetail(&number);
-    QContactEmailAddress email;
-    email.setEmailAddress("dummyemail");
-    c.saveDetail(&email);
-    QVERIFY(mManager->saveContact(&c));
-    QTest::qWait(1000);
-    
-    //check invalid row and column
-    QVariant ret;
-    ret = mCntModel->data(QModelIndex(), Qt::UserRole);
-    QVERIFY(ret.isNull());
-    
-    //check the saved contact's info
-    QModelIndex modelIndex = mCntModel->indexOfContact(c);
-    int row = modelIndex.row();
-    QContact contactFromModel = mCntModel->contact(modelIndex);
-    QVERIFY(c == contactFromModel);
-    
-    ret = mCntModel->data(modelIndex, Qt::UserRole); 
-    QVERIFY(ret.isNull());
-    
-    ret = mCntModel->data(modelIndex, Qt::DisplayRole); 
-    QVERIFY(ret.type() == QVariant::StringList);
-    QStringList displayContent;
-    displayContent = ret.toStringList();
-    QVERIFY(displayContent.count() == 2);
-    QVERIFY(displayContent.at(0) == "firstname lastname");
-    // second string is only an empty placeholder, e.g. " ", until cache has fetched the value
-
-    // wait for cache to signal that all contact info is ready
-    while (!mDataReady) { QTest::qWait(200); QApplication::processEvents(); }
-    mDataReady = false;
-    ret = mCntModel->data(modelIndex, Qt::DisplayRole); 
-
-    QVERIFY(ret.type() == QVariant::StringList);
-    displayContent = ret.toStringList();
-    QVERIFY(displayContent.count() == 2);
-    QVERIFY(displayContent.at(0) == "firstname lastname");
-    QVERIFY(displayContent.at(1) == "1234567");
-   
-    // check backgroundrole
-    ret = mCntModel->data(modelIndex, Qt::BackgroundRole); 
-    QVERIFY(ret.isNull());
-    
-    //check decoration role
-    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
-    QVERIFY(ret.type() == QVariant::List);
-
-    // add empty avatar and check decoration
-    QContactAvatar avatar;
-    c.saveDetail(&avatar);
-    QVERIFY(mManager->saveContact(&c));
-    QTest::qWait(1000);
-    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
-    QVERIFY(ret.type() == QVariant::List);
-    
-    // add data to the avatar and check decoration
-    avatar.setImageUrl(QUrl("dummyimagepath"));
-    c.saveDetail(&avatar);
-    QVERIFY(mManager->saveContact(&c));
-    QTest::qWait(1000);
-    modelIndex = mCntModel->indexOfContact(c);
-    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
-
-    // wait for cache to signal that all contact info is ready
-    while (!mDataReady) { QTest::qWait(200); QApplication::processEvents(); }
-    mDataReady = false;
-    ret = mCntModel->data(modelIndex, Qt::DecorationRole); 
-    QVERIFY(ret.type() == QVariant::List);
-    
-    // check MyCard info from the model
-    modelIndex = mCntModel->index(0, 0);
-    ret = mCntModel->data(modelIndex, Qt::BackgroundRole);
-    QVERIFY(!ret.isNull());
-    
-    // create and assign empty MyCard
-    QContact myCard;
-    QVERIFY(mManager->saveContact(&myCard));
-    QTest::qWait(1000);
-    mManager->setSelfContactId(myCard.localId());
-    QTest::qWait(1000);
-    
-    // check MyCard info from the model
-    myCard = mManager->contact(mManager->selfContactId());
-    modelIndex = mCntModel->indexOfContact(myCard);
-    ret = mCntModel->data(modelIndex, Qt::BackgroundRole);
-    QVERIFY(!ret.isNull());
-    
-    ret = mCntModel->data(modelIndex, Qt::DisplayRole);
-    QVERIFY(ret.type() == QVariant::StringList);
-    displayContent = ret.toStringList();
-    QVERIFY(displayContent.count() == 1); // "Unnamed"
-    
-    // add some content to MyCard
-    myCard.saveDetail(&number);
-    QVERIFY(mManager->saveContact(&myCard));
-    QTest::qWait(1000);
-    ret = mCntModel->data(modelIndex, Qt::DisplayRole);
-    // wait for cache
-    QTest::qWait(1000);
-    ret = mCntModel->data(modelIndex, Qt::DisplayRole);
-    QVERIFY(ret.type() == QVariant::StringList);
-    displayContent = ret.toStringList();
-    QVERIFY(displayContent.contains(hbTrId("txt_phob_list_unnamed")));
-}
-
-void TestMobCntModel::rowCount()
-{
-    // we should have 2 contacts in the model saved from the last test case
-    QCOMPARE(mCntModel->rowCount(),3);
-    QVERIFY(mCntModel->rowCount() == 3);
-}
-
-void TestMobCntModel::contact()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMapContact;
-    mManager->removeContacts(ids,&errorMapContact);
-    QTest::qWait(1000);
-    
-    QModelIndex modelIndex = mCntModel->index(0, 0);
-    QContact empty = mCntModel->contact(modelIndex);
-    //QVERIFY(empty.isEmpty());
-    
-    //create and save contact
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QContactPhoneNumber number;
-    number.setNumber("1234567");
-    number.setContexts(QContactDetail::ContextHome);
-    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
-    c.saveDetail(&number);
-    QContactEmailAddress email;
-    email.setEmailAddress("dummyemail");
-    c.saveDetail(&email);
-    QVERIFY(mManager->saveContact(&c));
-    QTest::qWait(1000);
-    
-    modelIndex = mCntModel->index(10, 0);
-    c = mCntModel->contact(modelIndex);
-    QVERIFY(c.isEmpty());
-    
-    modelIndex = mCntModel->index(1, 0);
-    c = mCntModel->contact(modelIndex);
-    QVERIFY(!c.isEmpty());
-}
-
-void TestMobCntModel::indexOfContact()
-{
-    QModelIndex modelIndex = mCntModel->index(1, 0);
-    QContact c = mCntModel->contact(modelIndex);
-    
-    QVERIFY(mCntModel->indexOfContact(c) == modelIndex);
-}
-
-void TestMobCntModel::contactManager()
-{
-    QVERIFY(mManager == &(mCntModel->contactManager()));
-}
-
-void TestMobCntModel::setFilterAndSortOrder()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-    
-    QContactUnionFilter unionFilter;
-    QContactDetailFilter landlineFilter;
-    landlineFilter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldSubTypes); 
-    landlineFilter.setValue(QLatin1String(QContactPhoneNumber::SubTypeLandline));
-    unionFilter << landlineFilter;
-    QContactDetailFilter mobileFilter;
-    mobileFilter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldSubTypes); 
-    mobileFilter.setValue(QLatin1String(QContactPhoneNumber::SubTypeMobile));
-    unionFilter << mobileFilter;
-    
-    mCntModel->setFilterAndSortOrder(unionFilter);
-    
-    QModelIndex modelIndex = mCntModel->indexOfContact(c);
-    QVERIFY(modelIndex.row() < 0);
-    QVERIFY(mCntModel->d->filter == unionFilter);
-    QVERIFY(mCntModel->d->sortOrders.count() == 0);
-    
-    QList<QContactSortOrder> sortOrders;
-    QContactSortOrder sortOrderFirstName;
-    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirstName);
-    sortOrders.append(sortOrderFirstName);
-    
-    mCntModel->setFilterAndSortOrder(unionFilter, sortOrders);
-    
-    modelIndex = mCntModel->indexOfContact(c);
-    QVERIFY(modelIndex.row() < 0);
-    QVERIFY(mCntModel->d->filter == unionFilter);
-    QVERIFY(mCntModel->d->sortOrders.count() == 1);
-}
-
-void TestMobCntModel::myCard()
-{
-    delete mCntModel;
-    mCntModel = 0;
-    
-    mCntModel = new CntListModel(mManager);
-    
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-    
-    QSignalSpy spy(mCntModel, SIGNAL(modelReset()));
-    
-    QVERIFY(mCntModel->myCardStatus());
-    
-    mCntModel->showMyCard(false);
-    QVERIFY(!mCntModel->myCardStatus());
-    QCOMPARE(spy.count(), 2);
-    
-    mCntModel->showMyCard(true);
-    QVERIFY(mCntModel->myCardStatus());
-    QCOMPARE(spy.count(), 4);
-    
-    mManager->setSelfContactId(c.localId());
-    QTest::qWait(1000);
-    spy.clear();
-    
-    mCntModel->showMyCard(false);
-    QVERIFY(!mCntModel->myCardStatus());
-    QCOMPARE(spy.count(), 2);
-    
-    mCntModel->showMyCard(true);
-    QVERIFY(mCntModel->myCardStatus());
-    QCOMPARE(spy.count(), 4);
-    mCntModel->showMyCard(true);
-    QVERIFY(mCntModel->myCardStatus());
-    QCOMPARE(spy.count(), 4);
-}
-
-void TestMobCntModel::rowId()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-    
-    int row = mCntModel->rowId(c.localId());
-    QVERIFY(row > 0);
-    QVERIFY(mCntModel->validRowId(row));
-    QVERIFY(!mCntModel->validRowId(-100));
-    QVERIFY(!mCntModel->validRowId(100));
-}
-
-void TestMobCntModel::dataForDisplayRole()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-    
-    int row = mCntModel->rowId(c.localId());
-    QVariant var = mCntModel->dataForDisplayRole(row);
-    QVERIFY(var.type() == QVariant::StringList);
-    
-    var = mCntModel->dataForDisplayRole(0);
-    QVERIFY(var.type() == QVariant::StringList);
-}
-
-void TestMobCntModel::handleAdded()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-
-    QSignalSpy spy(mCntModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)));
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-
-    QCOMPARE(spy.count(), 1);
-}
-
-void TestMobCntModel::handleChanged()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-    
-    QSignalSpy spy(mCntModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex&)));
-
-    name.setMiddleName("mid");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-
-    QCOMPARE(spy.count(), 1);
-}
-
-void TestMobCntModel::handleRemoved()
-{
-    QSignalSpy spy(mCntModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
-    
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QCOMPARE(spy.count(), 1);
-}
-
-void TestMobCntModel::handleMyCardChanged()
-{
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids,&errorMap);
-    QTest::qWait(1000);
-    
-    QContact c;
-    QContactName name;
-    name.setFirstName("firstname");
-    name.setLastName("lastname");
-    c.saveDetail(&name);
-    QVERIFY(mManager->saveContact(&c));
-    
-    QSignalSpy spy(mCntModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex&)));
-
-    mCntModel->handleMyCardChanged(0, c.localId());
-    QCOMPARE(spy.count(), 1);
-    QVERIFY(mCntModel->d->mMyCardId == c.localId());
-}
-
-void TestMobCntModel::cleanupTestCase()
-{
-    delete mCntModel;
-    mCntModel = 0;
-    
-    //let's have clean database after running tests
-    QList<QContactLocalId> ids = mManager->contactIds();
-    QMap<int, QContactManager::Error> errorMap;
-    mManager->removeContacts(ids, &errorMap);
-    delete mManager;
-    mManager = 0;
-    delete mModelListener;
-    mModelListener = 0;
-}
-
-
-ModelListener::ModelListener(TestMobCntModel* parent)
-    : mParent(parent)
-{
-    connect(mParent->mCntModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(onDataChanged(QModelIndex,QModelIndex)));
-}
-
-void ModelListener::onDataChanged(QModelIndex start, QModelIndex end)
-{
-    mParent->contactReady(start.row(), end.row());
-}
-
--- a/phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/ut_mobcntmodel.pro	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-#                                                                    
-# 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:                                                        
-#                                                                     
-#
-
-
-TEMPLATE = app
-TARGET =
-
-DEFINES += QT_NO_DEBUG_OUTPUT
-DEFINES += QT_NO_WARNING_OUTPUT
-DEFINES += CNTLISTMODEL_NO_EXPORT
-    
-MOC_DIR = moc
-
-QT += testlib xml
-
-CONFIG += hb
-
-TARGET.CAPABILITY = ALL \
-    -TCB
-
-INCLUDEPATH += .
-INCLUDEPATH += ../../inc
-INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
-    
-HEADERS += inc/testrunner.h
-HEADERS += inc/ut_mobcntmodel.h
-HEADERS += ../../inc/cntlistmodelglobal.h \
-           ../../inc/cntlistmodel.h \
-           ../../inc/cntlistmodel_p.h \
-           ../../inc/cntcache.h \
-           ../../inc/cntcache_p.h \
-           ../../inc/cntinfoprovider.h \
-           ../../inc/cntdefaultinfoprovider.h
-
-SOURCES += src/testrunner.cpp
-SOURCES += src/main.cpp
-SOURCES += src/ut_mobcntmodel.cpp
-SOURCES += ../../src/cntlistmodel.cpp
-SOURCES += ../../src/cntcache.cpp
-SOURCES += ../../src/cntcache_p.cpp
-SOURCES += ../../src/cntdefaultinfoprovider.cpp
-
-BLD_INF_RULES.prj_exports += "image1.png /epoc32/winscw/c/data/images/"
-BLD_INF_RULES.prj_exports += "image2.png /epoc32/winscw/c/data/images/"
-    
-LIBS += -lQtContacts \
-        -lhbcore \
-        -lthumbnailmanagerqt
-
Binary file phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/ut_mobcntmodel_template.sis has changed
Binary file phonebookengines/cntlistmodel/tsrc/ut_mobcntmodel/ut_mobcntmodel_template.sisx has changed
--- a/phonebookengines/cntmaptileservice/cntmaptileservice.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntmaptileservice/cntmaptileservice.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -24,7 +24,8 @@
 
 CONFIG += dll
 CONFIG += hb
-    
+CONFIG += mobility
+MOBILITY = publishsubscribe
 
 DEPENDPATH += .
 INCLUDEPATH += .
@@ -36,7 +37,7 @@
 DEFINES += CNTMAPTILESERVICEDLL
 
 INTERNAL_PUBLIC_HEADERS +=  inc/cntmaptileservice.h        
-
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 # Input
 HEADERS +=  $$INTERNAL_PUBLIC_HEADERS \
            ./inc/cntmaptiledblookuptable.h  
@@ -60,8 +61,12 @@
            -ledbms  \
            -lbafl \
            -lcentralrepository \
-           -leuser
+           -leuser \
+           -lefsrv
    
+        myCrml.sources = ./conf/cntmaptilepublisher.qcrml
+        myCrml.path = c:/resource/qt/crml
+        DEPLOYMENT += myCrml
 
 }  
 
@@ -71,4 +76,11 @@
 DEPLOYMENT += exportheaders
 
 # This is for new exporting system coming in garden
-for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
\ No newline at end of file
+for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
+defBlock = \      
+	"$${LITERAL_HASH}if defined(EABI)" \
+		"DEFFILE  ../eabi/cntmaptileservice.def" \
+    "$${LITERAL_HASH}else" \
+        "DEFFILE  ../bwins/cntmaptileservice.def" \
+	"$${LITERAL_HASH}endif"
+MMP_RULES += defBlock
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/conf/cntmaptilepublisher.qcrml	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository target="RProperty" version="" uidName="repo" uidValue="0x20022EF9">
+<key ref="/cntmaptilepublisher/name" int="0x1"/>
+</repository>
\ No newline at end of file
--- a/phonebookengines/cntmaptileservice/inc/cntmaptiledblookuptable.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntmaptileservice/inc/cntmaptiledblookuptable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -23,10 +23,13 @@
 #include <f32file.h> //RFs
 #include <d32dbms.h>  //RDbNamedDatabase,RDbView 
 
+#include "cntmaptileservice.h"
+
 // maptile database column names
 _LIT( NCntColUid, "cntuid" );
 _LIT( NCntColFilePath, "filepath" );
 _LIT( NColSource, "source" );
+_LIT( NColMaptileStatus, "fetchingstatus" );
 
 // maptile lookup database name
 _LIT( KMapTileLookupDatabaseName, "mylocationsmaptilelookup.db" );
@@ -40,8 +43,10 @@
 const TInt KColumncntUid = 1;
 // source type column number
 const TInt KColumnSource = 2;
-// source type column number
+// maptile image path column number
 const TInt KColumnFilePath = 3;
+// maptile status column number
+const TInt KColumnMapTileFetchingStatus = 4;
 
 
 /**
@@ -56,27 +61,11 @@
     // Source type
     TUint32 iSource;
     
-    // Landmark uid in the landmarks database
-    TUint32 iLmId;
-    
-    // Uid of the Contact
-    TUint32 icntUid; 
-    
     // File Path
     TFileName iFilePath;
-};
-
-/**
- *  Defines uid source type
- */
-enum TUidSourceType
-{
-    /** Uid Source type contacts default/prefered address */
-    ESourceContactsPref  = 3,
-    /** Uid Source type contacts work address */
-    ESourceContactsWork,
-    /** Uid Source type contacts home address */
-    ESourceContactsHome,
+    
+    //Map tile fetching status
+    TUint32 iFetchingStatus;    
 };
 
 /**
@@ -112,16 +101,31 @@
     * The source iUid is passed in the lookup item
     */
     void FindEntryL( TLookupItem& aLookupItem );
+    
+   /**
+    * Finds number of address associated with an contact id.
+    * @param[in] aId The contact id .
+    * @return Number of address a contact has.
+    */
+    int FindNumberOfAddressL( int& aId );
 
+#ifdef CNTMAPTILESERVICE_UNIT_TEST
+public:
+#else     
 private:
-    
+#endif  
     // default constructor
     CLookupMapTileDatabase();
     
     // Second phase constructor
     void ConstructL( const TDesC& aLookupTableName );
+
     
+#ifdef CNTMAPTILESERVICE_UNIT_TEST
+public:
+#else     
 private:
+#endif  
     
     // Handle to the items database
     RDbNamedDatabase iItemsDatabase;
@@ -137,7 +141,6 @@
 
 };
 
-
 #endif  // __MAPTILEDBLOOKUPTABLE_H__`
 
 // End of file
--- a/phonebookengines/cntmaptileservice/inc/cntmaptileservice.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntmaptileservice/inc/cntmaptileservice.h	Wed Jun 23 18:02:44 2010 +0300
@@ -22,7 +22,15 @@
 
 #include <QString>
 #include <QtGlobal>
+#include <QObject>
+#include <qmobilityglobal.h>
 
+QTM_BEGIN_NAMESPACE
+class QValueSpacePublisher;
+class QValueSpaceSubscriber;
+QTM_END_NAMESPACE
+
+QTM_USE_NAMESPACE
 
 #ifdef  CNTMAPTILESERVICEDLL
 #define CNTMAPTILESERVICE_EXPORT Q_DECL_EXPORT
@@ -30,7 +38,8 @@
 #define CNTMAPTILESERVICE_EXPORT Q_DECL_IMPORT
 #endif
 
-
+//Forward declaration
+class TLookupItem;
 
 // CLASS DECLARATION
 
@@ -40,30 +49,59 @@
 *
 *  Note: Location feature can be enabled or disabled by modifying conf\cntmaptileservice.confml file.
 */
-class CNTMAPTILESERVICE_EXPORT CntMapTileService 
+class CNTMAPTILESERVICE_EXPORT CntMapTileService : public QObject
 {
-
+    Q_OBJECT
 public:
 
     /** 
+     * Maptile fetching status
+     */
+    enum MapTileStatus
+    {
+        /** Map tile fetching completed */
+        MapTileFetchingCompleted = 0,
+        /** Map tile fetching in progress */
+        MapTileFetchingInProgress,
+        /** Map  tile fetching n/w error */
+        MapTileFetchingNetworkError,
+        /** Map tile fetching invalid address */
+        MapTileFetchingInvalidAddress,
+        /** Map tile fetching unknown erro */
+        MapTileFetchingUnknownError
+    };
+
+	
+    /** 
      * Contact address types
      */
     enum ContactAddressType      
     {
         /** Address Type Pref */
         AddressPreference,
+        /** Address type Home */
+        AddressHome,
         /** Address type Work */
-        AddressWork,
-        /** Address type Home */
-        AddressHome
+        AddressWork
     };
-      
+    
+    
+   /**
+    * Default Constructor
+    */  
+    CntMapTileService();
+    
+   /**
+    * Destructor
+    */
+    ~CntMapTileService();
+    
    /**
     * Checks whether location feature enabled or disabled.
     * 
     * @return Returns true or false based on location feature setting.
     */
-    static bool isLocationFeatureEnabled();
+    bool isLocationFeatureEnabled();
             
    /**
     * Gets a maptile image associated with a contact id. Returns a maptile 
@@ -71,11 +109,70 @@
     * 
     * @param contactId  Contact id     
     * @param sourceType Source address type( Preferred, Home , Work address )
+    * @param imagePath  Maptile image path associated with the contact id
     *      
-    * @return Returns maptile image path if it is available, else NULL.
+    * @return Returns the maptile fetching status.
     */
-    static QString getMapTileImage( int contactId, ContactAddressType sourceType  );  
-     	
+    int getMapTileImage( int Id, ContactAddressType sourceType, QString& imagePath  );   
+    
+public slots: 
+    /**
+     * Receives maptile status information and emits the maptilFetchingStatusUpdate
+     * signal.
+     */
+    void setMaptileStatus();
+    
+signals:
+    /**
+     * Signal to update the maptile fetchings status to contact application.
+     * @param id  Contact id     
+     * @param addressType Source address type( Preferred, Home , Work address )
+     * @param status Maptile status for the associated address
+     */
+     void maptileFetchingStatusUpdate( int id, int addressType, int status );
+    
+
+#ifdef CNTMAPTILESERVICE_UNIT_TEST
+public:
+#else     
+private:
+#endif  
+     
+    /**
+     * Publishes the contact address information to backend engine
+     * @param id  Contact id     
+     * @param sourceType Source address type( Preferred, Home , Work address )
+     * @param addressCount Number of address associated with this contact
+     */ 
+     void publishValue( int id, ContactAddressType sourceType, int addressCount );
+    
+     /**
+      * Reads the contact maptile information from maptile database.
+      * @param id  Contact id     
+      * @param sourceType Source address type( Preferred, Home , Work address )
+      * @param aLookupItem Contains the maptile information of a contact entry.
+      * @param aNoOfAddress Number of address associated with this contact.
+      * 
+      * @return Returns zero if successful or error.
+      */ 
+     int readEntryFromMaptileDataBase( int id, ContactAddressType sourceType,
+                          TLookupItem& aLookupItem, int& aNoOfAddress  );
+
+#ifdef CNTMAPTILESERVICE_UNIT_TEST
+public:
+#else     
+private:
+#endif  
+
+    //The contact id for which maptile requested
+    int mLastViewedContactId;
+    //Maptile request publisher
+    QValueSpacePublisher *mPublisher;
+    //Maptile status request subscriber
+    QValueSpaceSubscriber *mSubscriber;
+    //Contact information stored as string 
+    QString mContactEntryInfo;
+
 };
 
 #endif //_CNTMAPTILESERVICE_H_
--- a/phonebookengines/cntmaptileservice/src/cntmaptiledblookuptable.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntmaptileservice/src/cntmaptiledblookuptable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -33,6 +33,7 @@
 _LIT( KStringAnd, " AND " );
 
 
+_LIT(KQueryByMaptileState,"SELECT * FROM cntmaptilelookuptable WHERE cntuid = %d AND ( fetchingstatus = %d OR fetchingstatus = %d )");
 // -----------------------------------------------------------------------------
 // CLookupMapTileDatabase::CLookupMapTileDatabase()
 // Default constructor.
@@ -104,6 +105,52 @@
     }
 }
 
+// -----------------------------------------------------------------------------
+// CLookupMapTileDatabase::FindNumberOfAddressL()
+// Finds the number of address associated with an contact.
+// -----------------------------------------------------------------------------
+//
+int CLookupMapTileDatabase::FindNumberOfAddressL( int& aId )
+{
+    int count = 0;
+    
+    // Create a query to find the item.
+    TFileName queryBuffer;
+    queryBuffer.Format( KQueryByMaptileState,aId,
+             CntMapTileService::MapTileFetchingInProgress,
+             CntMapTileService::MapTileFetchingNetworkError );
+    
+    TInt ret = iItemsDatabase.Open( iFsSession, iDbFileName );
+    
+    if( ret != KErrNone )
+    {          
+        //if already opened , close and open again
+        iItemsDatabase.Close();          
+        User::LeaveIfError( iItemsDatabase.Open( iFsSession, iDbFileName ) );
+    }
+    
+    User::LeaveIfError( iItemsDatabase.Begin() );       
+    // Create a view of the table with the above query.
+    RDbView myView;
+    myView.Prepare( iItemsDatabase, TDbQuery( queryBuffer ) );
+    CleanupClosePushL( myView );
+    myView.EvaluateAll();
+    myView.FirstL();
+    
+    
+    while (myView.AtRow())
+    {
+        count++;
+        myView.NextL();
+    }
+    
+    CleanupStack::PopAndDestroy( &myView ); // myView
+         
+    //Close the database
+    iItemsDatabase.Close();
+
+    return count;
+}
 
 // -----------------------------------------------------------------------------
 // CLookupMapTileDatabase::FindEntryL()
@@ -125,7 +172,7 @@
         queryBuffer.Append( KStringWhere );
         queryBuffer.Append( NCntColUid );
         queryBuffer.Append( KStringEqual );
-        queryBuffer.AppendNum( aLookupItem.icntUid );
+        queryBuffer.AppendNum( aLookupItem.iUid );
         queryBuffer.Append( KStringAnd );
         queryBuffer.Append( NColSource );
         queryBuffer.Append( KStringEqual );
@@ -152,9 +199,10 @@
         {   
             // Item found. get the details.
             myView.GetL();      
-            if( aLookupItem.icntUid == myView.ColUint( KColumncntUid ) )
+            if( aLookupItem.iUid == myView.ColUint( KColumncntUid ) )
             {
                 aLookupItem.iFilePath.Copy( myView.ColDes16( KColumnFilePath ) );
+                aLookupItem.iFetchingStatus = myView.ColUint( KColumnMapTileFetchingStatus );
                 entryAvailable = ETrue;
             }      
         } 
--- a/phonebookengines/cntmaptileservice/src/cntmaptileservice.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntmaptileservice/src/cntmaptileservice.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -18,7 +18,9 @@
 
 
 #include <centralrepository.h> 
-
+#include <locationservicedefines.h>
+#include <qvaluespacepublisher.h>
+#include <qvaluespacesubscriber.h>
 
 #include "cntmaptileservice.h"
 #include "cntmaptiledblookuptable.h"
@@ -29,9 +31,49 @@
 // Central Repository Key IDs
 const TInt KEnableLocationFeature           = 0x1;
 
+const char *CNT_MAPTILE_STATUS_RECEIVER = "/maptilestatuspublisher/name";
+const char *CNT_MAPTILE_STATUS_PUBLISHER = "/cntmaptilepublisher";
+
 
 // -----------------------------------------------------------------------------
-// MapTileService::isLocationFeatureEnabled()
+// CntMapTileService::CntMapTileService()
+// Default constructor
+// -----------------------------------------------------------------------------
+//
+CntMapTileService::CntMapTileService()
+{
+    //publisher
+    mPublisher = NULL;
+    
+    //subscriber
+    mSubscriber = new QValueSpaceSubscriber( CNT_MAPTILE_STATUS_RECEIVER );
+    //Connect for maptile status change key
+    QObject::connect(mSubscriber, SIGNAL(contentsChanged()), this, SLOT(setMaptileStatus()));
+
+}
+
+
+// -----------------------------------------------------------------------------
+// CntMapTileService::~CntMapTileService()
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CntMapTileService::~CntMapTileService()
+{
+    if( mSubscriber )
+    {
+        delete mSubscriber;
+        mSubscriber = NULL;
+    }
+    
+    if( mPublisher )
+    {
+        delete mPublisher;
+        mPublisher = NULL;
+    }
+}
+// -----------------------------------------------------------------------------
+// CntMapTileService::isLocationFeatureEnabled()
 // Checks whether location feature is enabled or disabled
 // -----------------------------------------------------------------------------
 //
@@ -41,8 +83,9 @@
     bool enableLocationFeature = false;
     
     CRepository* centralRepository = NULL;  
-     
+
     TRAPD( err, centralRepository = CRepository::NewL( KUidMapTileInterface ) );
+
     if ( KErrNone == err )
     {
         TInt repValue;
@@ -64,54 +107,187 @@
 
 
 // -----------------------------------------------------------------------------
-// MapTileService::getMapTileImage()
+// CntMapTileService::getMapTileImage()
 // Gets the maptile image path associated with a contact.
 // -----------------------------------------------------------------------------
 //
-QString CntMapTileService::getMapTileImage( int contactId , ContactAddressType sourceType )    
+int CntMapTileService::getMapTileImage( int contactId , ContactAddressType sourceType, QString& imagePath )    
+{
+    
+    TLookupItem lookupItem;
+    
+    int addressCount = 0;
+    int maptileStatus = MapTileFetchingUnknownError;
+    
+    //Read the entry from maptile database
+    int error = readEntryFromMaptileDataBase( contactId, sourceType, lookupItem, addressCount );
+    
+    //if entry available returns the file path otherwise NULL. 
+    if ( KErrNone == error  )
+    {
+        maptileStatus = lookupItem.iFetchingStatus;
+        
+        if( maptileStatus == MapTileFetchingCompleted )
+        {
+            //Get the image path
+            QString imageFile((QChar*)lookupItem.iFilePath.Ptr(),
+                    lookupItem.iFilePath.Length());
+            imagePath = imageFile;
+        }
+        else if( maptileStatus == MapTileFetchingNetworkError ||
+                    maptileStatus == MapTileFetchingInProgress )
+        {
+            //Publish the contact id for maptile processing
+           	publishValue( contactId, sourceType, addressCount );
+        }
+
+    }
+    else if ( KErrNotFound == error )
+    {
+        //If entry is not found , it will be a newly added entry.
+        publishValue( contactId, sourceType, addressCount );
+        maptileStatus = MapTileFetchingInProgress;
+    }
+   
+    //Return the maptile status
+    return maptileStatus;
+}
+
+
+// -----------------------------------------------------------------------------
+// CntMapTileService::setMaptileStatus()
+// Emits the maptile status changed event to contact application
+// -----------------------------------------------------------------------------
+//
+void CntMapTileService::setMaptileStatus()
 {
-    //Image file to return;
-   
+    QString imagePath;
+    ContactAddressType addressType = AddressPreference;
+    
+    QStringList subPath = mSubscriber->subPaths();
+    QVariant value = mSubscriber->value(subPath.at(0));
+    
+    //Subscriber Protocol : [contactid-addresstype-maptilestatus]
+    QStringList text = value.toString().split("-");
+    int id = text.at(0).toInt();
+    int status = text.at(2).toInt();
+    
+    switch( text.at(1).toInt() )
+    {
+        case ESourceContactsPref:
+            addressType = AddressPreference;
+            break;
+        case ESourceContactsWork:
+            addressType = AddressWork;
+            break;        
+        case ESourceContactsHome:
+            addressType = AddressHome;
+            break;
+        default:
+            break;
+    }
+  
+    //Emit the maptile status signal 
+    int type = addressType;
+    if( mLastViewedContactId == id )
+    {
+        emit maptileFetchingStatusUpdate( mLastViewedContactId, type , status );
+    }
+}
+
+
+// -----------------------------------------------------------------------------
+// CntMapTileService::publishValue()
+// Publish the the contact id and address for which maptile to be processed.
+// -----------------------------------------------------------------------------
+//
+void CntMapTileService::publishValue( int id, ContactAddressType sourceType, int addressCount )
+{
+    
+    mLastViewedContactId = id;
+    int addressType = ESourceInvalid;
+    
+    switch( sourceType )
+    {
+        case AddressPreference:
+            addressType = ESourceContactsPref;
+            break;
+        case AddressWork:
+            addressType = ESourceContactsWork;
+            break;
+        case AddressHome:
+            addressType = ESourceContactsHome;
+            break;
+    }
+    
+    if ( !mPublisher )
+    {
+        /* Constructs a QValueSpacePublisher that publishes values under path /mypublisher*/
+        mPublisher = new QValueSpacePublisher( CNT_MAPTILE_STATUS_PUBLISHER, this);
+    }
+       
+    /* Publisher protocol [appid-addresstype-count] */
+    mContactEntryInfo.clear();
+    mContactEntryInfo.append( QVariant(id).toString());
+    mContactEntryInfo.append( QChar('-') );
+    mContactEntryInfo.append( QVariant(addressType).toString());
+    mContactEntryInfo.append( QChar('-') );
+    mContactEntryInfo.append( QVariant(addressCount).toString() );
+    
+    mPublisher->setValue("name", mContactEntryInfo.toAscii() );
+    mPublisher->sync();
+    
+}
+
+// -----------------------------------------------------------------------------
+// CntMapTileService::readEntryFromMaptileDataBase()
+// Read the entry from maptile database
+// -----------------------------------------------------------------------------
+//
+int CntMapTileService::readEntryFromMaptileDataBase( 
+            int id, ContactAddressType sourceType, TLookupItem& aLookupItem, int& aNoOfAddress )
+{
+    
     //Maptile database  instance
     CLookupMapTileDatabase* mapTileDatabase = NULL;
-   
+
     TRAPD( err, mapTileDatabase = CLookupMapTileDatabase::NewL(
             KMapTileLookupDatabaseName ) );
+
     if ( KErrNone == err )
     {
-        TLookupItem lookupItem;
-        lookupItem.icntUid = contactId;
+        int appId = id;
+        TRAP( err, aNoOfAddress = mapTileDatabase->FindNumberOfAddressL(appId) );
+       
+        if( err != KErrNone )
+        {
+            aNoOfAddress = 0;
+        }
+            
+        aLookupItem.iUid = id;
         switch( sourceType )
         {
            case AddressPreference:
-               lookupItem.iSource = ESourceContactsPref;
+               aLookupItem.iSource = ESourceContactsPref;
                break;
            case AddressWork:
-               lookupItem.iSource = ESourceContactsWork;
+               aLookupItem.iSource = ESourceContactsWork;
                break;
            case AddressHome:
-               lookupItem.iSource = ESourceContactsHome;
+               aLookupItem.iSource = ESourceContactsHome;
                break;
            default: 
                break;
         }
-       
-        TRAP( err , mapTileDatabase->FindEntryL( lookupItem ) );
-       
+   
+        TRAP( err , mapTileDatabase->FindEntryL( aLookupItem ) );
+        
         //delet the database instance
         delete mapTileDatabase;
-       
-        //if entry available returns the file path otherwise NULL. 
-        if ( KErrNone == err  )
-        {
-           //Get the image path
-            QString imageFile((QChar*)lookupItem.iFilePath.Ptr(),
-                    lookupItem.iFilePath.Length());
-            return imageFile;
-        }
+           
     }
     
-    return QString();
+    return err;
 }
 
 // End of file
Binary file phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/data/homeaddressmap.png has changed
Binary file phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/data/preferredaddressmap.png has changed
Binary file phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/data/workaddressmap.png has changed
Binary file phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/homeaddressmap.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/inc/testrunner.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,67 @@
+/*
+* 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:
+*
+*/
+
+#ifndef TESTRUNNER_H
+#define TESTRUNNER_H
+
+#include <QXmlDefaultHandler>
+
+
+class TestRunner : public QXmlDefaultHandler
+{
+public: // Constructors and destructor
+    TestRunner(const QString& name);
+    ~TestRunner();
+       
+public: // New functions
+    
+    int runTests(QObject& testObject);
+    void printResults();
+    
+protected: // From QXmlContentHandler 
+    bool startElement(
+        const QString& namespaceURI,
+        const QString& localName,
+        const QString& qName,
+        const QXmlAttributes& atts);
+    
+    bool endElement(
+        const QString& namespaceURI,
+        const QString& localName,
+        const QString& qName);
+    
+    bool characters(const QString& ch);
+
+private: // New functions
+
+    void parse(const QString& fileName);
+
+private: // Data
+    QStringList mTestRunParams;
+    QString mHomeDir;
+    int mTestCount;
+    QStringList mErrors;
+    bool mParsingIncidentElement;
+    bool mParsingDescriptionElement;
+    bool mCurrentTestFailed;
+    QString mCurrentTestName;
+    QString mCurrentTestFile;
+    int mCurrentTestFailureLine;
+};
+
+
+#endif // TESTRUNNER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/inc/ut_cntmaptileservice.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,48 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QtGui>
+#include <QString>
+#include <qtcontacts.h>
+#include <qcontactmanager.h>
+
+#include "cntmaptileservice.h"
+
+//Maptile test interface class
+class T_MaptileServiceTest: public QObject
+{
+    Q_OBJECT
+    
+private slots:
+    void init();
+    void cleanup();
+    
+private slots:
+    
+    void checkLocationFeature();
+    void getPreferredAddressMapTilePath();
+    void getWorkAddressMapTilePath();
+    void getHomeAddressMapTilePath();
+    void checkInvalidContactId();
+    void publishForMaptileFetching();
+    void readInvalidContactInfotmation();
+    
+private:
+    CntMapTileService* maptileService;
+};
+// End of File
Binary file phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/preferredaddressmap.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/src/main.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+
+#include "testrunner.h"
+#include "ut_cntmaptileservice.h"
+
+int main(int argc, char *argv[]) 
+{
+    bool promptOnExit(true);
+    for (int i=0; i<argc; i++) {
+        if (QString(argv[i]) == "-noprompt")
+            promptOnExit = false;
+    }
+   // printf("Running tests...\n");
+            
+    QApplication app(argc, argv);
+    
+    TestRunner testRunner("ut_maptilefetcher");
+    
+    T_MaptileServiceTest maptileService;
+    testRunner.runTests( maptileService );
+    
+    testRunner.printResults();
+
+    if (promptOnExit) {
+       // printf("Press any key...\n");
+        getchar(); 
+    }
+    return 0;   
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/src/testrunner.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,176 @@
+/*
+* 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:
+*
+*/
+
+#include "testrunner.h"
+#include <QtTest/QtTest>
+#include <QDir>
+#include <stdio.h>
+
+const char testFunctionElement[] = "TestFunction";
+const char incidentElement[] = "Incident";
+const char descriptionElement[] = "Description";
+const char nameAttr[] = "name";
+const char typeAttr[] = "type";
+const char fileAttr[] = "file";
+const char lineAttr[] = "line";
+const char attrValueFail[] = "fail";
+
+
+TestRunner::TestRunner(const QString& name)
+: mTestCount(0),
+  mParsingIncidentElement(false),
+  mParsingDescriptionElement(false),
+  mCurrentTestFailed(false),
+  mCurrentTestFailureLine(0)
+{
+    mTestRunParams.append(name);
+    mTestRunParams.append("-xml");
+    mTestRunParams.append("-o");
+    mHomeDir = QDir::homePath();
+    mTestRunParams.append(QString()); // Initial result file name
+
+    if (!mHomeDir.endsWith(QString::fromAscii("/")))
+        mHomeDir += QString::fromAscii("/");
+}
+
+TestRunner::~TestRunner()
+{
+}
+
+int TestRunner::runTests(QObject& testObject)
+{
+    QString className(testObject.metaObject()->className());
+    printf("Running tests for %s ... ", className.toUtf8().data());
+    QString resultFileName = mHomeDir + className + ".xml";
+    mTestRunParams.replace(mTestRunParams.count()-1,resultFileName);
+    int errorsBefore = mErrors.count();
+    int error = QTest::qExec(&testObject, mTestRunParams);
+    parse(resultFileName);
+    printf("Failures: %d\n",mErrors.count()-errorsBefore);
+    fflush(stdout);
+    return error;
+}
+
+void TestRunner::printResults()
+{
+    printf("\nTests executed: %d\n",mTestCount);
+    if (mErrors.count() > 0) {
+        printf("Failures (%d):\n", mErrors.count());
+        foreach(QString error, mErrors) {
+            printf("\n%s", error.toUtf8().data());
+        }
+        printf("\n");
+    } else {
+        printf("All passed.\n\n");
+    }
+    fflush(stdout);
+    
+    //To write in file
+    QFile file("C:\\CntMaptileServiceResult.txt");
+    if(file.open(QIODevice::WriteOnly)) 
+    {
+        QTextStream ts( &file );
+        ts << "Tests executed: " << mTestCount << "\n";
+        if (mErrors.count() > 0)
+        {
+            ts <<"Failures : " << mErrors.count() << "\n";
+            foreach(QString error, mErrors)
+                {
+                    ts << error.toUtf8().data();
+                }
+            ts << "\n";
+        }
+        else
+        {
+            ts<< "All passed.\n\n";
+        }
+        
+        ts << endl;
+        file.close();
+    } 
+}
+
+void TestRunner::parse(const QString& fileName)
+{
+    QFile file(fileName);
+    QXmlInputSource inputSource(&file);
+    QXmlSimpleReader reader;
+    reader.setContentHandler(this);
+    reader.parse(inputSource);
+}
+
+bool TestRunner::startElement(
+    const QString& /*namespaceURI*/, 
+    const QString& /*localName*/, 
+    const QString& qName, 
+    const QXmlAttributes& atts)
+{
+    if (qName == QString::fromAscii(testFunctionElement)) {
+        mTestCount++;
+        mCurrentTestName = atts.value(QString::fromAscii(nameAttr));
+        return true;
+    }
+    if (qName == QString::fromAscii(incidentElement)) {
+        mParsingIncidentElement = true;
+        if (atts.value(QString::fromAscii(typeAttr)) == QString::fromAscii(attrValueFail)) {
+            mCurrentTestFailed = true;
+            mCurrentTestFile = atts.value(QString::fromAscii(fileAttr));
+            mCurrentTestFailureLine = atts.value(QString::fromAscii(lineAttr)).toInt();
+        }
+        return true;
+    }
+    mParsingDescriptionElement =
+        (qName == QString::fromAscii(descriptionElement));
+    return true;
+}
+
+bool TestRunner::endElement(
+    const QString& /*namespaceURI*/,
+    const QString& /*localName*/,
+    const QString& qName)
+{
+    if (qName == QString::fromAscii(incidentElement)) {
+        mParsingIncidentElement = false;
+        mCurrentTestFailed = false;
+        return true;
+    }
+    if (qName == QString::fromAscii(descriptionElement)) {
+        mParsingDescriptionElement = false;
+    }    
+    return true;
+}
+
+bool TestRunner::characters(const QString& ch)
+{
+    if (mParsingIncidentElement && 
+        mParsingDescriptionElement &&
+        mCurrentTestFailed) {
+        QByteArray testResult = mCurrentTestName.toAscii() + " failed:\n";
+        testResult += "File: ";
+        testResult += mCurrentTestFile.toAscii();
+        testResult += "\n";
+        testResult += "Line: ";
+        testResult += QByteArray::number(mCurrentTestFailureLine);
+        testResult += "\n";
+        testResult += "Reason: ";
+        testResult += ch.toAscii();
+        testResult += "\n";
+        mErrors.append(QString::fromAscii(testResult.data()));
+    }
+    return true;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/src/ut_cntmaptileservice.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,287 @@
+/*
+* 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:
+*
+*/
+#include <qvaluespacepublisher.h>
+#include <qvaluespacesubscriber.h>
+
+#include "cntmaptiledblookuptable.h"
+#include "ut_cntmaptileservice.h"
+
+//Maximum maptile processing time
+const int KMapTileFetchTime  = 60000;
+
+QTM_USE_NAMESPACE
+
+
+void T_MaptileServiceTest::init()
+{
+    maptileService  = new CntMapTileService;
+}
+
+void T_MaptileServiceTest::cleanup()
+{
+   delete maptileService;
+}
+  
+//Checks whether location feature enabled or disabled
+void T_MaptileServiceTest::checkLocationFeature()
+{
+    QVERIFY( maptileService->isLocationFeatureEnabled() == 1 );
+}
+
+//Checks the maptile path retrieval for preferred address
+void T_MaptileServiceTest::getPreferredAddressMapTilePath()
+{
+    
+    QContact* contact = new QContact();
+    
+    //Add contact name   
+    QContactName* name = new QContactName();
+    name->setFirstName("Raj");
+    contact->saveDetail( name );
+    
+    //Add address
+    QContactAddress* address = new QContactAddress();
+    address->setPostOfficeBox("87640");
+    address->setStreet("Torstrasse");
+    address->setPostcode("12345");
+    address->setLocality("Berlin");
+    address->setCountry("Germany");
+    contact->saveDetail(address);
+    
+    //Save the contact
+    QContactManager* contactManager = NULL;
+    contactManager = new QContactManager("symbian");
+    contactManager->saveContact( contact );
+    
+    //Wait till maptile operation complete
+    QTest::qWait( KMapTileFetchTime );
+    
+   
+    //Get the saved id
+    QContactId savedId = contact->id();
+    TUint32 contactId = savedId.localId();
+    QString string;
+    
+    //Get the maptile 
+    int error = maptileService->getMapTileImage( 
+                    contactId, CntMapTileService::AddressPreference, string );
+    
+    //Construct the QPimap from reference bitmap
+    QImage referenceBitmap( "c:\\maptiletest\\preferredaddressmap.png" );
+    
+    //Construct the QPixmap from new retrieved bitmap
+    QImage retrievedBitmap( string );
+    
+      
+    //delete the contact
+    contactManager->removeContact( contactId );
+    
+    delete contact;
+    delete name;
+    delete address;
+    delete contactManager;
+
+}
+
+//Checks the maptile path retrieval for work address
+void T_MaptileServiceTest::getWorkAddressMapTilePath()
+{
+    QContact* contact = new QContact();
+    //Set name
+    QContactName* name = new QContactName();
+    name->setFirstName("Mike");
+    contact->saveDetail(name);
+    
+    //Set address
+    QContactAddress* address = new QContactAddress();
+    address->setPostOfficeBox("2345");
+    address->setPostcode("29834");
+    address->setStreet("Domlur");
+    address->setLocality("Bangalore");
+    address->setCountry("India");
+    address->setContexts(QContactDetail::ContextWork);
+    contact->saveDetail(address);
+    
+    //Save the contact
+    QContactManager* contactManager = NULL;
+    contactManager = new QContactManager("symbian");
+    contactManager->saveContact( contact );
+      
+    //Wait till maptile operation complete
+    QTest::qWait( KMapTileFetchTime );
+    
+     
+    //Get the saved id
+    QContactId savedId = contact->id();
+    TUint32 contactId = savedId.localId();
+    QString string;
+    
+    //Get the maptile 
+    int error = maptileService->getMapTileImage( 
+               contactId, CntMapTileService::AddressWork, string );
+    
+    //Construct the QPimap from already stored bitmap
+    QImage referenceBitmap( "c:\\maptiletest\\workaddressmap.png" );
+    
+    //Construct the QPixmap from new retrieved bitmap
+    QImage retrievedBitmap( string );
+    
+    //check results are same
+    QVERIFY( retrievedBitmap == referenceBitmap );
+    
+        
+    contactManager->removeContact( contactId );
+    
+    delete contact;
+    delete name;
+    delete address;
+    delete contactManager;
+}
+
+//Checks the maptile path retrieval for home address
+void T_MaptileServiceTest::getHomeAddressMapTilePath()
+{
+    QContact* contact = new QContact();
+        
+    QContactName* name = new QContactName();
+    name->setFirstName("first");
+    contact->saveDetail(name);
+    
+    QContactAddress* address = new QContactAddress();
+    address->setContexts(QContactDetail::ContextHome);
+    address->setPostOfficeBox("81282");
+    address->setStreet("Keilalahdentie");
+    address->setPostcode("67890");
+    address->setLocality("Espoo");
+    address->setCountry("Finland");
+    contact->saveDetail(address);
+    
+    //Save the contact
+    QContactManager* contactManager = NULL;
+    contactManager = new QContactManager("symbian");
+    contactManager->saveContact( contact );
+    
+    //Wait till maptile operation complete
+    QTest::qWait( KMapTileFetchTime );
+    
+    //Get the saved id
+    QContactId savedId = contact->id();
+    TUint32 contactId = savedId.localId();
+    QString string;
+    
+    //Get the maptile 
+    int error = maptileService->getMapTileImage( 
+             contactId, CntMapTileService::AddressHome, string );
+    
+    //Construct the QPimap from already stored bitmap
+    QImage referenceBitmap( "c:\\maptiletest\\homeaddressmap.png" );
+    
+    //Construct the QPixmap from new retrieved bitmap
+    QImage retrievedBitmap( string );
+    
+    //comapre the bitmaps
+    QVERIFY( retrievedBitmap == referenceBitmap );
+    
+      
+    contactManager->removeContact( contactId );
+    
+    delete contact;
+    delete name;
+    delete address;
+    delete contactManager;
+}
+
+//Checks the maptile path retrieval returns NULL for invalid address
+void  T_MaptileServiceTest::checkInvalidContactId()
+{
+    
+    QContact* contact = new QContact();
+   
+    QContactName* name = new QContactName();
+    name->setFirstName("first");
+    contact->saveDetail(name);
+    
+    //Add some invalid address
+    QContactAddress* address = new QContactAddress();
+    address->setPostOfficeBox("11111");
+    address->setStreet("htrtfdsk");
+    address->setPostcode("98989");
+    address->setLocality("ghwdxnkwnn");
+    address->setCountry("Fbsjwskws");
+    contact->saveDetail(address);
+    
+    //Save the contact
+    QContactManager* contactManager = NULL;
+    contactManager = new QContactManager("symbian");
+    contactManager->saveContact( contact );
+    
+    //Wait till maptile operation complete
+    QTest::qWait( KMapTileFetchTime );
+    
+     
+    //Get the saved id
+    QContactId savedId = contact->id();
+    TUint32 contactId = savedId.localId();
+    QString string;
+    
+    //Get the maptile 
+    int error = maptileService->getMapTileImage( 
+            contactId, CntMapTileService::AddressPreference, string );
+    
+    contactManager->removeContact( contactId );
+    
+    //Maptile path should be NULL for invalid address
+    QVERIFY( string.isEmpty() );
+    
+    delete contact;
+    delete name;
+    delete address;
+    delete contactManager;
+}
+
+void T_MaptileServiceTest::publishForMaptileFetching()
+{
+    int addressCount = 1;
+    int contactId = 10;
+    
+    maptileService->publishValue( contactId, CntMapTileService::AddressPreference, addressCount );
+    QVERIFY( maptileService->mContactEntryInfo == QString("10-3-1"));
+    
+    maptileService->publishValue( contactId, CntMapTileService::AddressHome, addressCount );
+    QVERIFY( maptileService->mContactEntryInfo == QString("10-4-1"));
+    
+    maptileService->publishValue( contactId, CntMapTileService::AddressWork, addressCount );
+    QVERIFY( maptileService->mContactEntryInfo == QString("10-5-1"));
+}
+
+void T_MaptileServiceTest::readInvalidContactInfotmation()
+{
+   int contactId = -1;
+   TLookupItem lookupItem;
+   int numberOfaddress = 0; 
+   
+   int error = maptileService->readEntryFromMaptileDataBase( 
+                  contactId, 
+                  CntMapTileService::AddressPreference, 
+                  lookupItem, 
+                  numberOfaddress );
+   QVERIFY( error == KErrNotFound );
+   
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/ut_cntmaptileservice.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,74 @@
+#
+# 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:
+#
+
+TEMPLATE = app
+QT += testlib sql xml
+
+CONFIG += hb
+CONFIG += mobility
+MOBILITY = publishsubscribe
+
+DEFINES += QT_NO_DEBUG_OUTPUT
+DEFINES += QT_NO_WARNING_OUTPUT
+DEFINES += CNTMAPTILESERVICEDLL
+DEFINES += CNTMAPTILESERVICE_UNIT_TEST
+
+INCLUDEPATH += inc
+INCLUDEPATH += ../inc
+INCLUDEPATH += ../../inc
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+
+symbian:
+{
+    :BLD_INF_RULES.prj_exports += "../../../cntmaptileservice/conf/cntmaptileservice.confml APP_LAYER_CONFML(cntmaptileservice.confml)"
+    :BLD_INF_RULES.prj_exports += "../../../cntmaptileservice/conf/cntmaptileservice_2002C3A8.crml APP_LAYER_CRML(cntmaptileservice_2002C3A8.crml)"
+    :BLD_INF_RULES.prj_exports += "../../../cntmaptileservice/conf/2002C3A8.txt /epoc32/winscw/c/private/10202be9/2002C3A8.txt"
+ 
+    :BLD_INF_RULES.prj_exports += "data/preferredaddressmap.png /epoc32/winscw/c/maptiletest/preferredaddressmap.png"
+    :BLD_INF_RULES.prj_exports += "data/workaddressmap.png /epoc32/winscw/c/maptiletest/workaddressmap.png"
+    :BLD_INF_RULES.prj_exports += "data/homeaddressmap.png /epoc32/winscw/c/maptiletest/homeaddressmap.png"
+    SYSTEMINCLUDEPATH += \epoc32\include\stdapis
+}
+
+SOURCES += src/testrunner.cpp
+SOURCES += src/main.cpp
+SOURCES += src/ut_cntmaptileservice.cpp
+
+SOURCES += ../../src/cntmaptileservice.cpp
+SOURCES += ../../src/cntmaptiledblookuptable.cpp
+
+# Input
+HEADERS += inc/testrunner.h
+HEADERS += inc/ut_cntmaptileservice.h
+
+HEADERS += ../../inc/cntmaptileservice.h
+HEADERS += ../../inc/cntmaptiledblookuptable.h
+
+
+LIBS += -lQtContacts \
+        -lcntmodel \      
+        -ledbms  \
+        -lbafl \
+        -lcentralrepository \
+        -leuser
+
+myCrml.sources = ../../../cntmaptileservice/conf/cntmaptilepublisher.qcrml
+        myCrml.path = c:/resource/qt/crml
+        DEPLOYMENT += myCrml
+
+
+TARGET.CAPABILITY = ALL -TCB    
+
--- a/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/ut_maptileservice.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-/*
-* 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:
-*
-*/
-#include <QtTest/QtTest>
-#include <QtGui>
-#include <QString>
-#include <qtcontacts.h>
-#include <qcontactmanager.h>
-
-
-#include "cntmaptileservice.h"
-
-
-//Maximum maptile processing time
-const int KMapTileFetchTime  = 150000;
-
-QTM_USE_NAMESPACE
-
-
-//Maptile test interface class
-class MaptileServiceTest: public QObject
-{
-    Q_OBJECT
-    
-private slots:
-    
-    void checkLocationFeature();
-    void getPreferredAddressMapTilePath();
-    void getWorkAddressMapTilePath();
-    void getHomeAddressMapTilePath();
-    void checkInvalidContactId();
- 
-};
-
-
-//Checks whether location feature enabled or disabled
-void MaptileServiceTest::checkLocationFeature()
-{
-   
-    QVERIFY( CntMapTileService::isLocationFeatureEnabled() == 1 );
-}
-
-//Checks the maptile path retrieval for preferred address
-void MaptileServiceTest::getPreferredAddressMapTilePath()
-{
-    
-    QContact* contact = new QContact();
-    
-    //Add contact name   
-    QContactName* name = new QContactName();
-    name->setFirst("Raj");
-    contact->saveDetail( name );
-    
-    //Add address
-    QContactAddress* address = new QContactAddress();
-    address->setPostOfficeBox("87640");
-    address->setStreet("Torstrasse");
-    address->setPostcode("12345");
-    address->setLocality("Berlin");
-    address->setCountry("Germany");
-    contact->saveDetail(address);
-    
-    //Save the contact
-    QContactManager* contactManager = NULL;
-    contactManager = new QContactManager("symbian");
-    contactManager->saveContact( contact );
-    
-    //Wait till maptile operation complete
-    QTest::qWait( KMapTileFetchTime );
-    
-   
-    //Get the saved id
-    QContactId savedId = contact->id();
-    TUint32 contactId = savedId.localId();
-    
-    //Get the maptile 
-    QString string = CntMapTileService::getMapTileImage( contactId, CntMapTileService::AddressPreference );
-    
-    //Construct the QPimap from reference bitmap
-    QImage referenceBitmap( "c:\\maptiletest\\preferredaddressmap.png" );
-    
-    //Construct the QPixmap from new retrieved bitmap
-    QImage retrievedBitmap( string );
-    
-      
-    //delete the contact
-    contactManager->removeContact( contactId );
-    
-    delete contact;
-    delete name;
-    delete address;
-    delete contactManager;
-    
-}
-
-//Checks the maptile path retrieval for work address
-void MaptileServiceTest::getWorkAddressMapTilePath()
-{
-    
-    QContact* contact = new QContact();
-    
-    //Set name
-    QContactName* name = new QContactName();
-    name->setFirst("Mike");
-    contact->saveDetail(name);
-    
-    //Set address
-    QContactAddress* address = new QContactAddress();
-    address->setPostOfficeBox("2345");
-    address->setPostcode("29834");
-    address->setStreet("Domlur");
-    address->setLocality("Bangalore");
-    address->setCountry("India");
-    address->setContexts(QContactDetail::ContextWork);
-    contact->saveDetail(address);
-    
-    //Save the contact
-    QContactManager* contactManager = NULL;
-    contactManager = new QContactManager("symbian");
-    contactManager->saveContact( contact );
-      
-    //Wait till maptile operation complete
-    QTest::qWait( KMapTileFetchTime );
-    
-     
-    //Get the saved id
-    QContactId savedId = contact->id();
-    TUint32 contactId = savedId.localId();
-    
-    //Get the maptile 
-    QString string = CntMapTileService::getMapTileImage( contactId, CntMapTileService::AddressWork );
-    
-    //Construct the QPimap from already stored bitmap
-    QImage referenceBitmap( "c:\\maptiletest\\workaddressmap.png" );
-    
-    //Construct the QPixmap from new retrieved bitmap
-    QImage retrievedBitmap( string );
-    
-    //check results are same
-    QVERIFY( retrievedBitmap == referenceBitmap );
-    
-        
-    contactManager->removeContact( contactId );
-    
-    delete contact;
-    delete name;
-    delete address;
-    delete contactManager;
-    
-}
-
-//Checks the maptile path retrieval for home address
-void MaptileServiceTest::getHomeAddressMapTilePath()
-{
-    
-    QContact* contact = new QContact();
-        
-    QContactName* name = new QContactName();
-    name->setFirst("first");
-    contact->saveDetail(name);
-    
-    QContactAddress* address = new QContactAddress();
-    address->setContexts(QContactDetail::ContextHome);
-    address->setPostOfficeBox("81282");
-    address->setStreet("Keilalahdentie");
-    address->setPostcode("67890");
-    address->setLocality("Espoo");
-    address->setCountry("Finland");
-    contact->saveDetail(address);
-    
-    //Save the contact
-    QContactManager* contactManager = NULL;
-    contactManager = new QContactManager("symbian");
-    contactManager->saveContact( contact );
-    
-    //Wait till maptile operation complete
-    QTest::qWait( KMapTileFetchTime );
-    
-    //Get the saved id
-    QContactId savedId = contact->id();
-    TUint32 contactId = savedId.localId();
-    
-    //Get the maptile 
-    QString string = CntMapTileService::getMapTileImage( contactId, CntMapTileService::AddressHome );
-    
-    //Construct the QPimap from already stored bitmap
-    QImage referenceBitmap( "c:\\maptiletest\\homeaddressmap.png" );
-    
-    //Construct the QPixmap from new retrieved bitmap
-    QImage retrievedBitmap( string );
-    
-    //comapre the bitmaps
-    QVERIFY( retrievedBitmap == referenceBitmap );
-    
-      
-    contactManager->removeContact( contactId );
-    
-    delete contact;
-    delete name;
-    delete address;
-    delete contactManager;
-    
-}
-
-//Checks the maptile path retrieval returns NULL for invalid address
-void  MaptileServiceTest::checkInvalidContactId()
-{
-    
-    QContact* contact = new QContact();
-   
-    QContactName* name = new QContactName();
-    name->setFirst("first");
-    contact->saveDetail(name);
-    
-    //Add some invalid address
-    QContactAddress* address = new QContactAddress();
-    address->setPostOfficeBox("11111");
-    address->setStreet("htrtfdsk");
-    address->setPostcode("98989");
-    address->setLocality("ghwdxnkwnn");
-    address->setCountry("Fbsjwskws");
-    contact->saveDetail(address);
-    
-    //Save the contact
-    QContactManager* contactManager = NULL;
-    contactManager = new QContactManager("symbian");
-    contactManager->saveContact( contact );
-    
-    //Wait till maptile operation complete
-    QTest::qWait( KMapTileFetchTime );
-    
-     
-    //Get the saved id
-    QContactId savedId = contact->id();
-    TUint32 contactId = savedId.localId();
-    
-    //Get the maptile 
-    QString string = CntMapTileService::getMapTileImage( contactId, CntMapTileService::AddressPreference );
-    
-    contactManager->removeContact( contactId );
-    
-    //Maptile path should be NULL for invalid address
-    QVERIFY( string.isNull() );
-    
-    delete contact;
-    delete name;
-    delete address;
-    delete contactManager;
-    
-  
-}
-
-
-QTEST_MAIN(MaptileServiceTest)
-#include "ut_maptileservice.moc"
-
-
--- a/phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/ut_maptileservice.pro	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#
-# 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:
-#
-
-TEMPLATE = app
-QT += testlib
-
-INCLUDEPATH += inc
-INCLUDEPATH += ../inc
-
-symbian:
-{
-   :BLD_INF_RULES.prj_exports += "preferredaddressmap.png /epoc32/winscw/c/maptiletest/preferredaddressmap.png"
-   :BLD_INF_RULES.prj_exports += "workaddressmap.png /epoc32/winscw/c/maptiletest/workaddressmap.png"
-   :BLD_INF_RULES.prj_exports += "homeaddressmap.png /epoc32/winscw/c/maptiletest/homeaddressmap.png"
-   SYSTEMINCLUDEPATH += \epoc32\include\stdapis
-}
-
-SOURCES += ut_maptileservice.cpp
-
-
-LIBS += -lcntmaptileservice \
-        -lQtContacts 
-
-TARGET.CAPABILITY = ALL -TCB    
-
Binary file phonebookengines/cntmaptileservice/tsrc/ut_cntmaptileservice/workaddressmap.png has changed
--- a/phonebookengines/cntsimutility/cntsimutility.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntsimutility/cntsimutility.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -29,7 +29,7 @@
 TARGET.EPOCALLOWDLLDATA = 1
 TARGET.UID3 = 0x2002B3F5
 
-INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 INCLUDEPATH += inc
 
 HEADERS += inc/simutilityglobal.h \
@@ -42,4 +42,12 @@
 LIBS += -letel \
         -letelmm \
         -lsecui \
-        -lcustomapi
+        -lcustomapi \
+        -lcentralrepository
+defBlock = \      
+	"$${LITERAL_HASH}if defined(EABI)" \
+		"DEFFILE  ../eabi/cntsimutility.def" \
+    "$${LITERAL_HASH}else" \
+        "DEFFILE  ../bwins/cntsimutility.def" \
+	"$${LITERAL_HASH}endif"
+MMP_RULES += defBlock
--- a/phonebookengines/cntsimutility/inc/cntsimutility.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntsimutility/inc/cntsimutility.h	Wed Jun 23 18:02:44 2010 +0300
@@ -19,6 +19,8 @@
 
 #include <qglobal.h>
 #include <QObject>
+#include <QDateTime>
+
 #include <etelmm.h>
 #include <rmmcustomapi.h>
 #include <secuisecuritysettings.h> 
@@ -111,7 +113,9 @@
 	bool verifyPin2Code();
 	bool isFdnActive();
 	int setFdnStatus(bool activated);
-
+	QDateTime getLastImportTime(int& error);
+	void setLastImportTime(int& error);
+	
 	//async request
 	bool startGetSimInfo();
 	bool startGetAvailableStores();
--- a/phonebookengines/cntsimutility/src/cntsimutility.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/cntsimutility/src/cntsimutility.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -18,6 +18,13 @@
 #include <mmtsy_names.h>
 #include <startupdomainpskeys.h>
 #include <e32property.h>
+#include <centralrepository.h>
+
+// Number of keys used in central repository to keep latest import date
+// from SIM card: 5 IMSI strings and 5 dates. 
+const int KCenRepKeysNumber = 10; 
+const int KIMSISize = 15;
+const int KCenRepUid = 0x200315A8;
 
 CntSimUtility::CntSimUtility(StoreType type, int& error, QObject *parent)
     : QObject(parent),
@@ -167,6 +174,130 @@
     return status.Int();
 }
 
+QDateTime CntSimUtility::getLastImportTime(int& error)
+{
+    error = KErrNone;
+    if (!isSimInserted()) {
+        error = KErrAccessDenied;
+        return QDateTime();
+    }
+    
+    // get IMSI
+    TBuf<KIMSISize> imsiBuf;
+    TRequestStatus reqStatus;
+    m_etelPhone.GetSubscriberId(reqStatus, imsiBuf);
+    User::WaitForRequest(reqStatus);
+    if (reqStatus.Int() != KErrNone) {
+        error = reqStatus.Int();
+        return QDateTime();
+    }
+    
+    CRepository* cenrep = NULL;
+    TRAPD(err, cenrep = CRepository::NewL(TUid::Uid(KCenRepUid)));
+    if (err != KErrNone) {
+        error = err;
+        return QDateTime();
+    }
+    
+    // find current IMSI in the stored values
+    int lastImportDate = 0;
+    for (int i = 1; i <= KCenRepKeysNumber; i+=2) {
+        TBuf<KIMSISize> storedImsiBuf;
+        if (cenrep->Get(i, storedImsiBuf) == KErrNone) {
+            if (storedImsiBuf.Compare(imsiBuf) == 0) {
+                if (cenrep->Get(i+1, lastImportDate) == KErrNone) {
+                    break;
+                }
+            }
+        }
+    }
+    delete cenrep;
+    cenrep = NULL;
+    
+    if (lastImportDate == 0) {
+        error = KErrNotFound;
+        return QDateTime();
+    }
+    
+    QDateTime retLastImportDate;
+    retLastImportDate.setTime_t(lastImportDate);
+    return retLastImportDate;
+}
+
+void CntSimUtility::setLastImportTime(int& error)
+{
+    error = KErrNone;
+    if (!isSimInserted()) {
+        error = KErrAccessDenied;
+        return;
+    }
+    
+    // get IMSI
+    TBuf<KIMSISize> imsiBuf;
+    TRequestStatus reqStatus;
+    m_etelPhone.GetSubscriberId(reqStatus, imsiBuf);
+    User::WaitForRequest(reqStatus);
+    if (reqStatus.Int() != KErrNone) {
+        error = reqStatus.Int();
+        return;
+    }
+    
+    CRepository* cenrep = NULL;
+    TRAPD(err, cenrep = CRepository::NewL(TUid::Uid(KCenRepUid)));
+    if (err != KErrNone) {
+        error = err;
+        return;
+    }
+     
+    // find current IMSI in the stored values
+    int lastImportDate = QDateTime::currentDateTime().toTime_t();
+    bool importDateUpdated = false;
+    for (int i = 1; i <= KCenRepKeysNumber; i+=2) {
+        TBuf<KIMSISize> storedImsiBuf;
+        if (cenrep->Get(i, storedImsiBuf) == KErrNone) {
+            if (storedImsiBuf.Compare(imsiBuf) == 0) {
+                //current IMSI already stored, update import date
+                if (cenrep->Set(i+1, lastImportDate) != KErrNone) {
+                    error = KErrAccessDenied;
+                }
+                importDateUpdated = true;
+                break;
+            }
+        }
+    }
+    
+    if (!importDateUpdated) {
+        int oldestDate = 0;
+        int key = 0;
+        // contacts were not imported from this SIM before,
+        // find oldest import date and replace it
+        for (int j = 2; j <= KCenRepKeysNumber; j+=2) {
+            int date;
+            if (cenrep->Get(j, date) == KErrNone) {
+                if (date >= oldestDate ) {
+                    oldestDate = date;
+                    key = j;
+                }
+            }
+        }
+    
+        if (key == 0) {
+            error = KErrAccessDenied;
+        }
+        else {
+            if (cenrep->Set(key, lastImportDate) != KErrNone) {
+                error = KErrAccessDenied;
+            }
+            if (cenrep->Set(key-1, imsiBuf) != KErrNone) {
+                error = KErrAccessDenied;
+            }
+        }
+    }
+    
+    delete cenrep;
+    cenrep = NULL;
+}
+
 bool CntSimUtility::startGetSimInfo()
 {
     if(m_asyncWorker->IsActive()) {
--- a/phonebookengines/contactsmodel/bwins/cntplsqlU.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/bwins/cntplsqlU.def	Wed Jun 23 18:02:44 2010 +0300
@@ -11,3 +11,7 @@
 	?RegisterDbObserver@CPersistenceLayer@@QAEXAAVMContactDbObserver@@@Z @ 10 NONAME ; void CPersistenceLayer::RegisterDbObserver(class MContactDbObserver &)
 	?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/phonebookengines/contactsmodel/cntmodel/src/ccontactdatabase.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntmodel/src/ccontactdatabase.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -4804,11 +4804,12 @@
 				TContactItemId actualId;
 				TUid contactType = KNullUid;
 				TBool deleted = EFalse;
+				TBool found = EFalse;
 	
         		MLplCollection& collection = FactoryL()->GetCollectorL();
-				TRAP(error, collection.SeekContactL(aContactId,actualId,contactType,deleted));
+				TRAP(error, found = collection.SeekContactL(aContactId,actualId,contactType,deleted));
 				
-				if (CheckSortError(error)==EFalse)
+				if (found && CheckSortError(error)==EFalse)
 					{
 					if (CheckType(contactType))
 						{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/c12keykeymap.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,90 @@
+/*
+* 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: Class to hold the character to key mappings for a virtual
+*   12 key keyboard.
+*/
+
+#ifndef __C12KEYKEYMAP_H__
+#define __C12KEYKEYMAP_H__
+
+// INCLUDE FILES
+#include "cpcskeymap.h"
+
+// FORWARD DECLARATIONS
+class QTextCodec;	// if Thai-recog is needed also in qwerty, move QTextCodecs to CPcsKeyMap
+
+// CLASS DECLARATION
+NONSHARABLE_CLASS(C12keyKeyMap) : public CPcsKeyMap
+	{
+    public: // Constructors and destructor
+        /**
+         * Two phase construction
+         */
+        static C12keyKeyMap* NewL();
+        
+        /**
+         * Destructor
+         */
+		virtual ~C12keyKeyMap();
+
+	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;
+
+		virtual QList<HbInputLanguage> SelectLanguages();
+
+#if defined(USE_ORBIT_KEYMAP)
+		virtual void SetHardcodedCharacters();
+#endif
+
+		/**
+         * Returns ETrue if characters that are mapped to * and # keys, should
+		 * be skipped.
+         */
+		virtual TBool DetermineSpecialCharBehaviour(QString aSource) const;
+		virtual TBool ShouldSkipChar(QChar aChar, TBool aSkipHashStar) const;
+
+	private: // Constructors
+        /**
+         * Constructor
+         */
+		C12keyKeyMap();
+		
+		/**
+		 * Second phase constructor
+		 */
+		void ConstructL();
+
+	private: // New functions
+		void GetTextCodecs();
+
+    private: // Data
+		// Not owned
+		QTextCodec* iLatinCodec;
+		QTextCodec* iThaiCodec;
+
+		// For unit testing
+		friend class UT_CPcsKeyMap;
+	};
+
+#endif // __C12KEYKEYMAP_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/c12keypredictivesearchtable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,70 @@
+/*
+* 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: 
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#ifndef __C12KEYPREDICTIVESEARCHTABLE_H__
+#define __C12KEYPREDICTIVESEARCHTABLE_H__
+
+#include "pltables.h"
+#include <QList>
+
+class CContactItem;
+class RSqlDatabase;
+class QString;
+
+
+/**
+C12keyPredictiveSearchTable class manages the predictive search tables related
+to virtual ITU-T 12-key keyboard.
+*/
+NONSHARABLE_CLASS(C12keyPredictiveSearchTable) : public CPplPredictiveSearchTableBase
+	{
+public:
+	static C12keyPredictiveSearchTable* NewL(RSqlDatabase& aDatabase);
+	static C12keyPredictiveSearchTable* NewLC(RSqlDatabase& aDatabase);
+	~C12keyPredictiveSearchTable();
+
+public: // From CPplPredictiveSearchTableBase
+	void CreateTableL();
+
+	QList<QChar> FillAllTables() const;
+
+private: // From CPplPredictiveSearchTableBase
+	HBufC* TableNameL(const QChar aCh) const;
+	TBool IsValidChar(const QChar aChar) const;
+
+	void FillKeyboardSpecificFieldsL(RSqlStatement& aSqlStatement,
+									 QStringList aTokens);
+
+private:
+	void ConstructL();
+	C12keyPredictiveSearchTable(RSqlDatabase& aDatabase);
+	quint64 ConvertToHex(QString aToken) const;
+	const TDesC& GetTableNameL(const QChar aCh) const;
+
+	// For unit testing
+	friend class UT_CPplPredictiveSearchTable;
+	};
+
+#endif // __C12KEYPREDICTIVESEARCHTABLE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/cntsqlsearch.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** 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
+
+#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 CQwertyKeyMap;
+class C12keyKeyMap;
+
+class CntSqlSearch// : public QObject
+{
+    //Q_OBJECT
+
+public:
+
+enum SearchMethod { Undefinded, ZerosEndOfFirstToken, ZeroIsFirstNumber };
+
+enum QueryType
+        {
+        TwelveTable = 0,
+        QwertyEmail,
+        QwertyContact
+        };
+
+public:
+    CntSqlSearch();
+    
+    ~CntSqlSearch();
+
+    QString CreatePredictiveSearch(const QString &pattern);
+    
+
+private:
+    
+    QString selectQweryTable(const QString &pattern) const;
+    
+    QString SelectTable(const QString &pattern) const;
+    
+    QStringList GetTokens(const QString& pattern) const;
+    
+    QString CreateQwertyQuery(
+            const QString& pattern) const;
+    
+    QString CreateQuery(const QString& pattern) const;
+    
+    QString ExactMatchSearch(const QString& pattern) const;
+    
+    QString ExactMatchSearchQwerty(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,
+								     QueryType queryType = TwelveTable) 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 CompareTwoQwertyColumns(const QString& lower,
+            const QString& upper,
+            const QString& lower2,
+            const QString& upper2) const;
+
+    QString TwoDifferentTokensSearch(const QString& pattern,
+                                                                  const QStringList& tokens) const;
+
+    QString ExactMatch(const QString& pattern, QString table = "") const;
+    
+    QString ExactMatchQwerty(const QString& pattern, QString table = "") const;
+
+    QString CreateJoinTableSearch(QString pattern, QStringList numbers) const;
+
+    QString ExactMatchColumns(QStringList numbers) const;
+
+    QString Order(QStringList numbers, QueryType queryType = TwelveTable ) const;
+
+    QString UpperLimit( const QString &pattern ) const;
+    
+    QString LowerLimit( const QString &pattern ) const;
+
+    QString ChangeStringPadings( const QString &pattern ) const;
+
+    bool TestPattern( const QString &pattern, SearchMethod searchMethod =  Undefinded ) const;
+    
+    QString Pad( const QString &pattern, char padChar ) const;
+    
+    bool isQwerty(const QString &pattern);
+    
+    QStringList qwertyTokens(const QString &pattern) const;
+    
+private:
+    
+    CQwertyKeyMap* mQertyKeyMap; 
+    C12keyKeyMap* mkeyKeyMap;
+    
+    friend class UT_CntSqlSearch;
+};
+//#endif
--- a/phonebookengines/contactsmodel/cntplsql/inc/cpcskeymap.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/inc/cpcskeymap.h	Wed Jun 23 18:02:44 2010 +0300
@@ -25,48 +25,65 @@
 //
 // 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
+#define USE_ORBIT_KEYMAP
+
+// If this macro is defined, the hardcoded keymap contains also Thai characters
+#define THAI_KEYMAP
 
 
 // INCLUDES
 #if defined(USE_ORBIT_KEYMAP)
 #include <QList>
 #include <QLocale>
+#include <hbinputdef.h>	// HbKeyboardType
+#include <hbinputlanguage.h>
 #endif
-
 #include <e32base.h>
 
 // FORWARD DECLARATIONS
-#if defined(USE_ORBIT_KEYMAP)
 class QString;
-class HbInputLanguage;
-class HbKeymap;
-#endif
+class QChar;
+
 
 // CLASS DECLARATION
 NONSHARABLE_CLASS(CPcsKeyMap) : public CBase
 	{
-    public:    
-        /**
-         * Two phase construction
-         */
-        static CPcsKeyMap* NewL();
-        
+    public:
         /**
          * Destructor
          */
 		virtual ~CPcsKeyMap();
 
+    public: // New functions
 		/**
-		 * Converts a string to a numeric string.
+		 * Maps the given string using the key map.
 		 * aSource String to be converted
-		 * aPlainConversion ETrue Perform a simple conversion, without special
-		 *                        handling for sepator characters
-		 *					EFalse Convert spaces to separator characters
 		 * returns Conversion result, ownership is transferred
 		 */
-		HBufC* GetNumericKeyStringL(const TDesC& aSource,
-                                    TBool aPlainConversion) const;
+		HBufC* GetMappedStringL(const TDesC& aSource) const;
+
+		/**
+		 * Maps the given string using the key map.
+		 * aSource String to be converted
+		 * returns Conversion result
+		 *
+		 * Overloaded version using QString.
+		 */
+		QString GetMappedString(QString aSource) const;
+
+		/**
+		 * Computes the upper and lower limits, that can be put into SQL SELECT
+		 * statement, from the string.
+		 * aString Only contains valid characters (for 12-key keymap this means
+		 *  0..9, 'a', 'b', 'f'). This is fulfilled if aString is output from
+		 *  GetMappedStringL or GetMappedString, or a sub-string of the output.
+		 * aLowerLimit Lower limit
+		 * aUpperLimit Upper limit
+		 * returns KErrNone if successful
+		 */
+		TInt GetNumericLimits(QString aString,
+							  QString& aLowerLimit,
+							  QString& aUpperLimit) const;
 
 #if defined(USE_ORBIT_KEYMAP)
 		/*
@@ -75,65 +92,100 @@
 		QChar Separator() const;
 #endif
 
-	private:
-        /**
+	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
+		/**
+         * Returns ETrue if characters that are mapped to certain specific keys,
+		 * should be skipped.
+         */
+		virtual TBool DetermineSpecialCharBehaviour(QString aSource) const;
+
+		virtual TBool ShouldSkipChar(QChar aChar, TBool aSkipHashStar) const;
+
+	protected: // Constructors
+		/**
          * Constructor
          */
-		CPcsKeyMap();
-		
+		CPcsKeyMap(TInt aAmountOfKeys, QChar aPadChar, TInt aMaxKeysStoredInDb);
+
 		/**
 		 * Second phase constructor
 		 */
-		void ConstructL();
-
 #if defined(USE_ORBIT_KEYMAP)
-		/**
-		 * Construct mappings between keys and characters.
-		 */
-		void ContructKeyboardMappings();
+		void ConstructL(HbKeyboardType aKeyboardType);
+#else
+		void ConstructL();
+#endif
+
+	private: // New functions
+#if defined(USE_ORBIT_KEYMAP)
+		void InitKeyMappings();
 
 		/**
-         * Returns a list of languages installed on the phone.
-         */
-		QList<HbInputLanguage> AvailableLanguages() const;
-		
+		 * Construct mappings between keys and characters for all languages.
+		 */
+		void ConstructLanguageMappings(HbKeyboardType aKeyboardType);
+
         /**
          * Returns ETrue if this language is supported
          */
         TBool IsLanguageSupported(QLocale::Language aLanguage) const;
 
         /**
-         * Returns the numeric key id corresponding to a specific character
-         * Considers possible multiple matches for some phone variants
+         * Returns the key into which the given character is mapped.
          */
-        TChar KeyForCharacter(const TChar& aChar) const;
-
-#if defined(_DEBUG)
-        TInt KeyIdToNumber(TInt aKeyId) const;
-#endif // #if defined(_DEBUG)
-
-        TChar ArrayIndexToNumberChar(TInt aArrayIndex) const;
-#else // #if defined(USE_ORBIT_KEYMAP)
-		TChar GetNumericValueForChar(TChar input) const;
+		const QChar MappedKeyForChar(const QChar aChar) const;
 #endif // #if defined(USE_ORBIT_KEYMAP)
 
-    private: // Data
-
 #if defined(USE_ORBIT_KEYMAP)
-		// One QString for each key of the keyboard (1-9,0,*,#).
+	protected:
+		// One QString for each key of the keyboard.
 		// Each contains all the characters that can originate from that key,
         // considering the languages available on the device.
 		//
-		// iKeyMapping[0] has mappings for 1-key, iKeyMapping[1] for 2-key, ...
-		// iKeyMapping[8] for 9-key, iKeyMapping[9] for 0-key,
-		// iKeyMapping[10] for *-key, iKeyMapping[11] for #-key.
+		// 12-key keymap has keys 1-9,0,*,#.
+		//   iKeyMapping[0] has mappings for 1-key, iKeyMapping[1] for 2-key, ...
+		//   iKeyMapping[8] for 9-key, iKeyMapping[9] for 0-key,
+		//   iKeyMapping[10] for *-key, iKeyMapping[11] for #-key.
+		//
+		// Qwerty keymap has keys q, w, e, r, ...
+		//   iKeyMapping[0] has mappings for q-key, iKeyMapping[1] for w-key, ...
         QList<QString> iKeyMapping;
 
 		// Characters that have been hardcoded to certain keys, regardless of
-		// actual keymap.
+		// the actual keymaps.
 		QString iHardcodedChars;
+
+	private: // Data
+		// How many keys (not characters) the keymap has
+		const TInt iAmountOfKeys;
+
+		// 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.
+		const TInt iMaxKeysStoredInDb;
+
 		// For unit testing
 		friend class UT_CPcsKeyMap;
 	};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/cpredictivesearchsettingstable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,81 @@
+/*
+* 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: 
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#ifndef __CPREDICTIVESEARCHSETTINGSTABLE_H__
+#define __CPREDICTIVESEARCHSETTINGSTABLE_H__
+
+#include "pltables.h"
+#include <QLocale>
+
+class CCntSqlStatement;
+class RSqlDatabase;
+
+/**
+The CPplPredictiveSearchTable class contains numeric representation of the
+fields that are checked in predictive search.
+*/
+NONSHARABLE_CLASS(CPredictiveSearchSettingsTable) : public CPplPredictiveSearchTableBase
+	{
+public:
+	static CPredictiveSearchSettingsTable* NewL(RSqlDatabase& aDatabase);
+	static CPredictiveSearchSettingsTable* NewLC(RSqlDatabase& aDatabase);
+	virtual ~CPredictiveSearchSettingsTable();
+
+public: // From CPplTableBase
+	void CreateInDbL(CContactItem& aItem);
+	void UpdateL(const CContactItem& aItem);
+	void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred);
+	void CreateTableL();
+
+public: // CPplPredictiveSearchTableBase
+	QList<QChar> FillAllTables() const;
+
+private: // From CPplPredictiveSearchTableBase
+	HBufC* TableNameL(const QChar aCh) const;
+
+	TBool IsValidChar(const QChar /*aChar*/) const { return ETrue; }
+	void FillKeyboardSpecificFieldsL(RSqlStatement& /*aSqlStatement*/,
+									 QStringList /*aTokens*/) {}
+
+public: // New functions
+	TBool IsLanguageValidL() const;
+	void StoreCurrentLanguageL() const;
+
+protected:
+	void ConstructL();
+	CPredictiveSearchSettingsTable(RSqlDatabase& aDatabase);
+
+private:
+	void WriteToDbL(const CContactItem& aItem);
+
+	enum QLocale::Language GetCurrentLanguageL() const;
+
+	enum QLocale::Language ReadStoredLanguageL() const;
+
+	// For unit testing
+	friend class UT_CPredictiveSearchSettingsTable;
+	};
+
+#endif // __CPREDICTIVESEARCHSETTINGSTABLE_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/cpredictivesearchsynchronizer.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* 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: 
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#ifndef __CPREDICTIVESEARCHSYNCHRONIZER_H__
+#define __CPREDICTIVESEARCHSYNCHRONIZER_H__
+
+// INCLUDES
+#include <e32base.h>
+
+// FORWARD DECLARATIONS
+class RSqlDatabase;
+class CContactItem;
+class CPplPredictiveSearchTableBase;
+class C12keyPredictiveSearchTable;
+class CQwertyPredictiveSearchTable;
+class CPredictiveSearchSettingsTable;
+
+
+/**
+The CPredictiveSearchSynchronizer class takes care of populating predictive
+search tables with the relevant data from contacts.
+*/
+NONSHARABLE_CLASS(CPredictiveSearchSynchronizer) : public CBase
+	{
+public:
+	static CPredictiveSearchSynchronizer*
+		NewL(RSqlDatabase& aDatabase,
+			 C12keyPredictiveSearchTable& a12keyTable,
+			 CQwertyPredictiveSearchTable& aQwertyTable,
+			 CPredictiveSearchSettingsTable& aSettingsTable);
+	static CPredictiveSearchSynchronizer*
+		NewLC(RSqlDatabase& aDatabase,
+			  C12keyPredictiveSearchTable& a12keyTable,
+			  CQwertyPredictiveSearchTable& aQwertyTable,
+			  CPredictiveSearchSettingsTable& aSettingsTable);
+	virtual ~CPredictiveSearchSynchronizer();
+
+public: // New functions
+	void SynchronizeTablesL();
+
+	/**
+	 * Create and fill the specified predictive search tables.
+	 *
+	 * aAllTables If ETrue, then 12-key, QWERTY table and settings table are
+	 *            created. Otherwise just QWERTY table is created.
+	 */
+	void CreatePredSearchTablesL(TBool aAllTables = ETrue);
+	void DeletePredSearchTablesL();
+	
+private:
+	void ConstructL();
+	CPredictiveSearchSynchronizer(RSqlDatabase& aDatabase,
+								  C12keyPredictiveSearchTable& a12keyTable,
+								  CQwertyPredictiveSearchTable& aQwertyTable,
+								  CPredictiveSearchSettingsTable& aSettingsTable);
+
+private: // New functions
+	TBool CheckIfPredSearchTableExistsL(const TDesC& aTableName) const;
+	void DeletePredSearchTableL(CPplPredictiveSearchTableBase& aTable);
+	TBool ReadMailAddressesL(CContactItem& aContact);
+
+private: // Data
+	RSqlDatabase&					iDatabase;
+	C12keyPredictiveSearchTable&	i12keyTable;
+	CQwertyPredictiveSearchTable&	iQwertyTable;
+	CPredictiveSearchSettingsTable& iSettingsTable;
+
+	// For unit testing
+	friend class UT_CPplPredictiveSearchTable;
+	};
+
+#endif // __CPREDICTIVESEARCHSYNCHRONIZER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/cqwertykeymap.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,156 @@
+/*
+* 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 for a virtual
+*   qwerty keyboard.
+*/
+
+#ifndef __CQWERTYKEYMAP_H__
+#define __CQWERTYKEYMAP_H__
+
+// INCLUDE FILES
+#include "cpcskeymap.h"
+#include <QMap.h>
+
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+NONSHARABLE_CLASS(CQwertyKeyMap) : public CPcsKeyMap
+	{
+	public: // Enums
+		enum TQwertyKeyboard
+			{
+			// How many keys have mappings in the virtual QWERTY keypad.
+			// Most languages list 32 keys, some have 36 keys.
+			// 4x11 keyboard could have 44 keys.
+			EAmountOfKeysInQwertyKeypad = 44
+			};
+
+		// These values are used to identify each key in the keyboard.
+		enum TKeyId
+			{
+			// first key at index 0 
+			EKeyQ = 0,
+			EKeyW,
+			EKeyE,
+			EKeyR,
+			EKeyT,
+			EKeyY,
+			EKeyU,
+			EKeyI,
+			EKeyO,
+			EKeyP,
+
+			EKeyA, // 10
+			EKeyS,
+			EKeyD,
+			EKeyF,
+			EKeyG,
+			EKeyH,
+			EKeyJ,
+			EKeyK,
+			EKeyL,
+
+			EKeyZ, // 19
+			EKeyX,
+			EKeyC,
+			EKeyV,
+			EKeyB,
+			EKeyN,
+			EKeyM,
+			EKeyColon,
+			EKeyDot,
+			EKeyDash,	// 28
+			EKeyAt,
+			EKeyQuote,
+			EKeyQuestionMark,
+
+			EKey32,
+			EKey33,
+			EKey34,
+			EKey35,
+			EKey36,
+			EKey37,
+			EKey38,
+			EKey39,
+			EKey40,
+			EKey41,
+			EKey42,
+			EKey43,
+
+			// Value is KBitsInKeyId amount of 1-bits (i.e. 111111 (binary))
+			KPadCharValue = 0x3f
+			};
+
+    public: // Constructors and destructor
+        /**
+         * Two phase construction
+         */
+        static CQwertyKeyMap* NewL();
+        
+        /**
+         * Destructor
+         */
+		virtual ~CQwertyKeyMap();
+
+	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;
+
+	public:
+#if defined(USE_ORBIT_KEYMAP)
+		bool IsValidChar(const QChar aChar) const;
+#endif
+		TInt MapKeyNameToValue(const QChar aKeyName) const;
+
+	private: // Constructors
+        /**
+         * Constructor
+         */
+		CQwertyKeyMap();
+		
+		/**
+		 * Second phase constructor
+		 */
+		void ConstructL();
+
+	private: // New functions
+		void ConstructKeyNameMap();
+
+    private: // Data
+		// Mapping between the virtual keys (TKeyId) of the keyboard, and the
+		// base character of that key (QChar).
+		//
+		// TODO: must place QMap's 1st arg the one that used more,
+		// since reverse lookup (Qmap::key()) is slow
+		QMap<TKeyId, QChar> iKeyNames;
+
+		// List of the valid base characters of the keyboard. Obtained from
+		// iKeyNames.
+		QList<QChar> iKeyValues;
+
+		// For unit testing
+		friend class UT_CQwertyKeyMap;
+	};
+
+#endif // __CQWERTYKEYMAP_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/cqwertypredictivesearchtable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,71 @@
+/*
+* 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: 
+*
+*/
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#ifndef __CQWERTYPREDICTIVESEARCHTABLE_H__
+#define __CQWERTYPREDICTIVESEARCHTABLE_H__
+
+#include "pltables.h"
+#include <QList>
+
+class CContactItem;
+class RSqlDatabase;
+class QStringList;
+
+
+/**
+CQwertyPredictiveSearchTable class manages the predictive search tables related
+to the virtual QWERTY keyboard.
+*/
+NONSHARABLE_CLASS(CQwertyPredictiveSearchTable) : public CPplPredictiveSearchTableBase
+	{
+public:
+	static CQwertyPredictiveSearchTable* NewL(RSqlDatabase& aDatabase);
+	static CQwertyPredictiveSearchTable* NewLC(RSqlDatabase& aDatabase);
+	~CQwertyPredictiveSearchTable();
+
+public: // From CPplPredictiveSearchTableBase
+	void CreateTableL();
+	
+	QList<QChar> FillAllTables() const;
+
+private: // From CPplPredictiveSearchTableBase
+	HBufC* TableNameL(const QChar aCh) const;
+	TBool IsValidChar(const QChar aChar) const;
+
+	void FillKeyboardSpecificFieldsL(RSqlStatement& aSqlStatement,
+									 QStringList aTokens);
+	QStringList GetTableSpecificFields(const CContactItem& aItem,
+									   TBool& aMandatoryFieldsPresent) const;
+
+private:
+	void ConstructL();
+	CQwertyPredictiveSearchTable(RSqlDatabase& aDatabase);
+
+
+	// For unit testing
+	friend class UT_CQwertyPredictiveSearchTable;
+	};
+
+#endif // __CQWERTYPREDICTIVESEARCHTABLE_H__
--- a/phonebookengines/contactsmodel/cntplsql/inc/dbsqlconstants.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/inc/dbsqlconstants.h	Wed Jun 23 18:02:44 2010 +0300
@@ -20,6 +20,7 @@
 
 #include <cntdef.hrh>
 
+
 const TInt KInitialValue = -1;
 const TInt KNumOfTables = 16;
 const TInt KNumColInPrefTable = 6;
@@ -28,25 +29,28 @@
 const TInt KNumColInCommTable = 5;
 const TInt KNumColInPredSearchTable = 7;
 const TInt KNumColInPresenceTable = 5;
+// TODO: qwerty-mail tables are not yet added here
 
 // tables in the contact database 
-_LIT(KSqlContactTableName,"contact");
-_LIT(KSqlContactGroupTableName,"groups");
-_LIT(KSqlContactPrefTableName,"preferences");
-_LIT(KSqlContactCommAddrTableName,"comm_addr");
-_LIT(KSqlContactPredSearchTable0,"predictivesearch0");
-_LIT(KSqlContactPredSearchTable1,"predictivesearch1");
-_LIT(KSqlContactPredSearchTable2,"predictivesearch2");
-_LIT(KSqlContactPredSearchTable3,"predictivesearch3");
-_LIT(KSqlContactPredSearchTable4,"predictivesearch4");
-_LIT(KSqlContactPredSearchTable5,"predictivesearch5");
-_LIT(KSqlContactPredSearchTable6,"predictivesearch6");
-_LIT(KSqlContactPredSearchTable7,"predictivesearch7");
-_LIT(KSqlContactPredSearchTable8,"predictivesearch8");
-_LIT(KSqlContactPredSearchTable9,"predictivesearch9");
-_LIT(KSqlContactPredSearchTable10,"predictivesearch10");
-_LIT(KSqlContactPredSearchTable11,"predictivesearch11");
+_LIT(KSqlContactTableName, "contact");
+_LIT(KSqlContactGroupTableName, "groups");
+_LIT(KSqlContactPrefTableName, "preferences");
+_LIT(KSqlContactCommAddrTableName, "comm_addr");
+_LIT(KSqlContactPredSearchTable0, "predictivesearch0");
+_LIT(KSqlContactPredSearchTable1, "predictivesearch1");
+_LIT(KSqlContactPredSearchTable2, "predictivesearch2");
+_LIT(KSqlContactPredSearchTable3, "predictivesearch3");
+_LIT(KSqlContactPredSearchTable4, "predictivesearch4");
+_LIT(KSqlContactPredSearchTable5, "predictivesearch5");
+_LIT(KSqlContactPredSearchTable6, "predictivesearch6");
+_LIT(KSqlContactPredSearchTable7, "predictivesearch7");
+_LIT(KSqlContactPredSearchTable8, "predictivesearch8");
+_LIT(KSqlContactPredSearchTable9, "predictivesearch9");
+_LIT(KSqlContactPredSearchTable10, "predictivesearch10");
+_LIT(KSqlContactPredSearchTable11, "predictivesearch11");
 _LIT(KSqlContactPresenceTableName, "presence");
+// There are also 44 qwerty-mail tables (qm0..qm43)
+
 
 enum TDatabaseTables
 	{
@@ -66,6 +70,7 @@
 	KContactPredSearchTable9Name,
 	KContactPredSearchTable10Name,
 	KContactPredSearchTable11Name
+	// TODO: qwerty-mail tables are not yet added here
 	};
 
 // columns for contact table
@@ -375,7 +380,35 @@
 "CREATE TABLE presence (contact_id INTEGER NOT NULL,\
 account_uri VARCHAR(255),service_name VARCHAR(255),\
 status INTEGER, status_msg VARCHAR(255),\
-CONSTRAINT contactid_fk FOREIGN KEY (contact_id) REFERENCES contact(contact_id) ON DELETE CASCADE);"); 
+CONSTRAINT contactid_fk FOREIGN KEY (contact_id) REFERENCES contact(contact_id) ON DELETE CASCADE);");
+
+
+// Predictive search for qwerty mail tables
+// columns
+_LIT(KPredSearchQwertyMailContactId, "contact_id");
+_LIT(KPredSearchQwertyMailNameAsNumber, "n");
+_LIT(KPredSearchQwertyMailNameAsNumber2, "n2");
+_LIT(KPredSearchQwertyMailNameAsNumber3, "n3");
+_LIT(KPredSearchQwertyMailNameAsNumber4, "n4");
+_LIT(KPredSearchQwertyMailNameAsNumber5, "n5");
+_LIT(KPredSearchQwertyMailNameAsNumber6, "n6");
+_LIT(KPredSearchQwertyMailNameAsNumber7, "n7");
+_LIT(KPredSearchQwertyMailFirstName, "first_name");
+_LIT(KPredSearchQwertyMailLastName, "last_name");
+
+// parameters
+_LIT(KPredSearchQwertyMailContactIdParam, ":contact_id");
+_LIT(KPredSearchQwertyMailNameAsNumberParam, ":n");
+_LIT(KPredSearchQwertyMailNameAsNumberParam2, ":n2");
+_LIT(KPredSearchQwertyMailNameAsNumberParam3, ":n3");
+_LIT(KPredSearchQwertyMailNameAsNumberParam4, ":n4");
+_LIT(KPredSearchQwertyMailNameAsNumberParam5, ":n5");
+_LIT(KPredSearchQwertyMailNameAsNumberParam6, ":n6");
+_LIT(KPredSearchQwertyMailNameAsNumberParam7, ":n7");
+_LIT(KPredSearchQwertyMailFirstNameParam, ":first_name");
+_LIT(KPredSearchQwertyMailLastNameParam, ":last_name");
+
+
 // Condition strings for searching id
 _LIT(KSelectCondition_SearchForEqual,   "%S == :SeekId");
 
--- a/phonebookengines/contactsmodel/cntplsql/inc/pltables.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/inc/pltables.h	Wed Jun 23 18:02:44 2010 +0300
@@ -42,6 +42,7 @@
 
 class CPcsKeyMap;
 
+
 /**
 The CPplTableBase class forms the base class for all SQLite tables in the
 Persistence Layer. It implements default behaviour for some basic operations.
@@ -305,25 +306,55 @@
 
 
 /**
-The CPplPredictiveSearchTable class contains numeric representation of the
-fields that are checked in predictive search.
+The CPplPredictiveSearchTableBase is a base class for keymap-specific predictive
+search tables that contain numeric representation of the fields that are checked
+in predictive search.
 */
-NONSHARABLE_CLASS(CPplPredictiveSearchTable) : public CPplTableBase
+NONSHARABLE_CLASS(CPplPredictiveSearchTableBase) : public CPplTableBase
 	{
 public:
-	static CPplPredictiveSearchTable* NewL(RSqlDatabase& aDatabase);
-	static CPplPredictiveSearchTable* NewLC(RSqlDatabase& aDatabase);
-	~CPplPredictiveSearchTable();
+	virtual ~CPplPredictiveSearchTableBase();
 
 public: // From CPplTableBase
 	void CreateInDbL(CContactItem& aItem);
 	void UpdateL(const CContactItem& aItem);
 	void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred);
-	void CreateTableL();
+	virtual void CreateTableL() = 0;
+
+public: // New pure virtual functions
+	virtual QList<QChar> FillAllTables() const = 0;
+
+private: // New pure virtual functions
+	virtual HBufC* TableNameL(const QChar aCh) const = 0;
+	virtual TBool IsValidChar(const QChar aChar) const = 0;
+
+	virtual void FillKeyboardSpecificFieldsL(RSqlStatement& aSqlStatement,
+											 QStringList aTokens) = 0;
+
+private: // New virtual functions
+	virtual QStringList
+		GetTableSpecificFields(const CContactItem& aItem,
+							   TBool& aMandatoryFieldsPresent) const;
+
+public:
+	// Return next table's name, ownership is transferred
+	HBufC* GetNextTableNameL(QList<QChar>& aTables) const;
+
+protected:
+	void ConstructL();
+	CPplPredictiveSearchTableBase(RSqlDatabase& aDatabase,
+								  TInt aMaxTokens,
+								  TInt aMaxTokenLength);
+
+	QList<QChar> DetermineTables(QStringList aTokens) const;
+
+	// aFirstName ownership is not transferred
+	// aLastName ownership is not transferred
+	QStringList GetTokens(QStringList aNonTokenizedFields,
+						  HBufC* aFirstName,
+						  HBufC* aLastName) const;
 
 private:
-	void ConstructL();
-	CPplPredictiveSearchTable(RSqlDatabase& aDatabase);
 	void WriteToDbL(const CContactItem& aItem);
 
 	// aFirstNameAsNbr OUT: Pointer to first name converted to numbers,
@@ -340,29 +371,14 @@
 					 HBufC** aFirstName,
 					 HBufC** aLastName) const;
 
-	QList<TChar> DetermineTables(QStringList aTokens) const;
-
 	// aString ownership is not transferred
 	void AddTokens(HBufC* aString, QStringList& aTokens) const;
 
-	TBool IsValidChar(QChar aChar) const;
-
-	// aFirstName ownership is not transferred
-	// aLastName ownership is not transferred
-	QStringList GetNumericTokens(HBufC* aFirstName, HBufC* aLastName) const;
 	void GetNextToken(QStringList& aSource, QStringList& aDestination) const;
 	void DeleteFromAllTablesL(TContactItemId aContactId,
 							  TBool& aLowDiskErrorOccurred) const;
 
-	QList<TChar> FillAllTables() const;
-
-	// Return next table's name, ownership is transferred
-	HBufC* GetNextTableNameL(QList<TChar>& aTables) const;
-	const TDesC& TableNameL(TChar aCh) const;
-
-	quint64 ConvertToHex(QString aToken) const;
-
-private:
+protected:
 	// Owned
 	CCntSqlStatement* iInsertStmnt;
 	// Owned
@@ -371,11 +387,15 @@
 	CPcsKeyMap*		  iKeyMap;
 
 	RSqlDatabase&	  iDatabase;
-	
-	// For unit testing
-	friend class UT_CPplPredictiveSearchTable;
+
+	// Max amount of tokens that can be stored into predictive search table
+	const TInt		  iMaxTokens;
+
+	// Max length of a single token that can be stored into predictive search table
+	const TInt		  iMaxTokenLength;
 	};
 
+
 NONSHARABLE_CLASS(CPplPresenceTable) : public CPplTableBase
     {
 public:
--- a/phonebookengines/contactsmodel/cntplsql/inc/pplcontactitemmanager.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/inc/pplcontactitemmanager.h	Wed Jun 23 18:02:44 2010 +0300
@@ -16,8 +16,6 @@
 */
 
 
-
-
 /**
  @file
  @internalComponent
@@ -37,7 +35,12 @@
 
 class CPplTableBase;
 class CPplPreferencesPersistor;
-class CPplPredictiveSearchTable;
+class CPplPredictiveSearchTableBase;
+class C12keyPredictiveSearchTable;
+class CQwertyPredictiveSearchTable;
+class CPredictiveSearchSettingsTable;
+class CPredictiveSearchSynchronizer;
+
 
 /**
 The CPplContactItemManager implements the MLplPersistenceBroker.
@@ -81,7 +84,10 @@
 	void RecreatePredSearchTablesL();
 
 private:
-	CPplContactItemManager(RSqlDatabase& aDatabase, MLplTransactionManager& aTransactionManager, CLplContactProperties&  aContactProperties, RPplIccContactStore& aIccContactStore);
+	CPplContactItemManager(RSqlDatabase& aDatabase,
+						   MLplTransactionManager& aTransactionManager,
+						   CLplContactProperties& aContactProperties,
+						   RPplIccContactStore& aIccContactStore);
 	void ConstructL();
 	static void CleanupOperationRollbackL(TAny* aDatabase);
 	
@@ -91,24 +97,26 @@
 	TInt NameFieldIndex(const CContactItemField& aNameField) const;
 	void DeleteInLowDiskConditionL(CPplTableBase* aTable, CContactItem* aContactItem);
 
-	TBool DoesPredSearchTableExistL() const;
-	void CreatePredSearchTablesL();
-	void DeletePredSearchTablesL();
+private:
+	RSqlDatabase&				  iDatabase; // CPplContactItemManager does not own the RSqlDatabase object
+	MLplTransactionManager& 	  iTransactionManager;
+	TUint						  iSessionId;
+	CCntSqlStatement* 			  iSelectStatement;
+	CLplContactProperties&  	  iContactProperties;
+	CPplTableBase* 				  iContactTable;
+	CPplTableBase* 				  iGroupTable;	
+	CPplTableBase* 			      iCommAddrTable;
+	C12keyPredictiveSearchTable*  iPredSearch12keyTable;
+	CQwertyPredictiveSearchTable* iPredSearchQwertyTable;
+	CPredictiveSearchSettingsTable* iPredSearchSettingsTable;
+	CPplTableBase*                iPresenceTable;
+	CPplPreferencesPersistor*     iPreferencePersistor;
+	RPplIccContactStore&          iIccContactStore;
+	//RColumboSession             iColSession;
+	CPredictiveSearchSynchronizer* iPredictiveSearchSynchronizer; // Owned
 
-private:
-	RSqlDatabase&				iDatabase;				// CPplContactItemManager does not own the RSqlDatabase object
-	MLplTransactionManager& 	iTransactionManager;
-	TUint						iSessionId;
-	CCntSqlStatement* 			iSelectStatement;
-	CLplContactProperties&  	iContactProperties;
-	CPplTableBase* 				iContactTable;
-	CPplTableBase* 				iGroupTable;	
-	CPplTableBase* 				iCommAddrTable;
-	CPplPredictiveSearchTable*   	iPredSearchTable;
-	CPplTableBase*              iPresenceTable;
-	CPplPreferencesPersistor*	iPreferencePersistor;
-	RPplIccContactStore&        iIccContactStore;
-	//RColumboSession             iColSession;
+	// For unit testing
+	friend class UT_CPplPredictiveSearchTable;
 };
 
 #endif // __PPLCONTACTITEMMANAGER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/predictivesearchlog.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,53 @@
+/*
+* 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: Macros for performing logging 
+*/
+
+#ifndef __PREDICTIVESEARCHLOG_H__
+#define __PREDICTIVESEARCHLOG_H__
+
+
+// To avoid logging in debug builds, define NO_PRED_SEARCH_LOGS macro in the
+// file that includes this header file
+#if !defined(NO_PRED_SEARCH_LOGS) && defined(_DEBUG)
+#define WRITE_PRED_SEARCH_LOGS
+#endif
+
+
+#if defined(WRITE_PRED_SEARCH_LOGS)
+
+#include <e32debug.h> // RDebug
+
+#define PRINT(x)					RDebug::Print(x)
+#define PRINT1(x, y)				RDebug::Print(x, y)
+#define PRINT2(x, y, z)				RDebug::Print(x, y, z)
+#define PRINT3(w, x, y, z)			RDebug::Print(w, x, y, z)
+#define PRINT4(v, w, x, y, z)		RDebug::Print(v, w, x, y, z)
+#define PRINT5(u, v, w, x, y, z)	RDebug::Print(u, v, w, x, y, z)
+
+#else // #if defined(WRITE_PRED_SEARCH_LOGS)
+
+#define PRINT(x)
+#define PRINT1(x, y)
+#define PRINT2(x, y, z)
+#define PRINT3(w, x, y, z)
+#define PRINT4(v, w, x, y, z)
+#define PRINT5(u, v, w, x, y, z)
+
+#endif // #if defined(WRITE_PRED_SEARCH_LOGS)
+
+
+#endif // __PREDICTIVESEARCHLOG_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/c12keykeymap.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,491 @@
+/*
+* 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 "c12keykeymap.h"
+#include "predictivesearchlog.h"
+
+// Detection for Thai language is needed for both hardcoded and Orbit keymaps
+#include <QTextCodec>
+#include <hbinputkeymapfactory.h>
+//#include <hbinputsettingproxy.h>
+
+// How many keys have mappings in ITU-T keypad (keys 0..9, * and # have mappings)
+const TInt KAmountOfKeys = 12;
+
+// Largest amount of keypresses that can be stored in 12-key keyboard's
+// predictive search tables.
+// SQL BIGINT is a 64-bit signed integer, one bit is reserved for sign.
+// 12-key keyboard's keys are identified by TKeyId that needs 4 bits.
+// 63 / 4 = 15
+const TInt KMaxKeysStoredInDb = 15;
+
+
+// The first key of the keyboard has value zero ('1' in the 12-key virtual keypad) 
+enum TKeyId
+    {
+    EKey1 = 0,
+    EKey2,
+    EKey3,
+    EKey4,
+    EKey5,
+    EKey6,
+    EKey7,
+    EKey8,
+    EKey9,
+	EKey0,
+	EKeyStar,
+	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
+const QChar KMappedCharForStar = 'a';
+// # key is mapped to this
+const QChar KMappedCharForHash = 'b';
+// Unmapped (unknown) characters are replaced with this
+const QChar KPadChar		   = 'f';
+
+const QChar KLowerLimitPadding = '0';
+const QChar KUpperLimitPadding = 'f';
+
+const int KLatin1 = 4; // ISO_8859-1
+const int KThaiLanguage = 2259; // Thai Industrial Standards Institute
+
+
+// ============================== MEMBER FUNCTIONS ============================
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::NewL
+// ----------------------------------------------------------------------------
+C12keyKeyMap* C12keyKeyMap::NewL()
+	{
+    PRINT(_L("Enter C12keyKeyMap::NewL"));
+    
+    C12keyKeyMap* self = new (ELeave) C12keyKeyMap();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+
+    PRINT(_L("End C12keyKeyMap::NewL"));
+    return self;
+	}
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::~C12keyKeyMap
+// QTextCodec's destructor is protected, so it is not intended to be deleted.
+// ----------------------------------------------------------------------------
+C12keyKeyMap::~C12keyKeyMap()
+    {
+    PRINT(_L("Enter C12keyKeyMap::~C12keyKeyMap"));
+    PRINT(_L("End C12keyKeyMap::~C12keyKeyMap"));
+    }
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::ArrayIndexToMappedChar
+// Map index of iKeyMapping list, to the number char that the mapping is for.
+// ----------------------------------------------------------------------------
+const QChar C12keyKeyMap::ArrayIndexToMappedChar(TInt aArrayIndex) const
+    {
+    __ASSERT_DEBUG(aArrayIndex < KAmountOfKeys,
+                   User::Panic(_L("C12keyKeyMap::ArrayIndexToMappedChar"),
+                   KErrOverflow));
+    switch (aArrayIndex)
+        {
+        case EKey0:
+            return '0';
+        case EKeyStar:
+            return KMappedCharForStar;
+        case EKeyHash:
+            return KMappedCharForHash;
+        default:
+            return aArrayIndex + '1';
+        }
+    }
+
+#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
+// ----------------------------------------------------------------------------
+TInt C12keyKeyMap::ComputeValue(QString aString,
+							    TBool aUpperLimit,
+							    QString& aValue) const
+	{
+	QString hexString;
+	if (aString.length() < KMaxKeysStoredInDb)
+		{
+		QChar pad = KLowerLimitPadding;
+		if (aUpperLimit)
+			{
+			pad = KUpperLimitPadding;
+			}
+		hexString = aString.leftJustified(KMaxKeysStoredInDb, pad);
+		}
+	else
+		{
+		hexString = aString;
+		}
+    
+    const TInt KHexadecimalBase = 16;
+    bool ok(true);
+    // Use signed int to prevent underflow when padded is "00...00"
+    qint64 value = hexString.toLongLong(&ok, KHexadecimalBase); 
+    if (!ok)
+        {
+		PRINT(_L("CPcsKeyMap::ComputeValue fails"));
+		return KErrArgument;
+        }
+
+	// In order to write queries using '>' and '<' instead of '>=' and '<=',
+	// expand the limit by one.
+	if (aUpperLimit)
+		{
+		++value;
+		}
+	else
+		{
+		--value;
+		}
+
+    aValue = QString::number(value); // Convert to decimal value
+	return KErrNone;
+	}
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::SetHardcodedCharacters
+// In emulator (except in unit tests), select just the default language, as new
+// SDKs have over 40 languages, causing out of memory error.
+// In hardware and when compiling unit tests in emulator, select all languages
+// available in the device. Reason: it is though that HW does not come with
+// dozens of languages and some unit test cases require Thai keymap.
+// ----------------------------------------------------------------------------
+QList<HbInputLanguage> C12keyKeyMap::SelectLanguages()
+	{
+#if defined(__WINSCW__) && !defined(EUNIT_UNIT_TEST_COVERAGE)
+	return CPcsKeyMap::SelectLanguages();
+#else
+	return HbKeymapFactory::availableLanguages();
+#endif
+	}
+
+#if defined(USE_ORBIT_KEYMAP)
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::SetHardcodedCharacters
+// Even though most languages map *, + and # to 1-key, they are here mapped to
+// the distinct *-key or #-key of the 12-key ITU-T keypad.
+// ----------------------------------------------------------------------------
+void C12keyKeyMap::SetHardcodedCharacters()
+	{
+	iKeyMapping[EKeyStar].append(KStar);
+	iKeyMapping[EKeyStar].append(KPlus);
+	iKeyMapping[EKeyHash].append(KHash);
+	iHardcodedChars.append(KStar);
+	iHardcodedChars.append(KPlus);
+	iHardcodedChars.append(KHash);
+	}
+#endif // #if defined(USE_ORBIT_KEYMAP)
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::DetermineSpecialCharBehaviour
+// If input string is Thai language, skip chars that map to star or hash keys.
+// ----------------------------------------------------------------------------
+TBool C12keyKeyMap::DetermineSpecialCharBehaviour(QString aSource) const
+	{
+	/* this code would use the current input language to determine if Thai is in use
+	HbInputLanguage lang = HbInputSettingProxy::instance()->globalInputLanguage();
+    TBool skipHashStar = lang.language() == QLocale::Thai; */
+
+	if (iLatinCodec && iLatinCodec->canEncode(aSource))
+		{
+		return EFalse;
+		}
+    return iThaiCodec && iThaiCodec->canEncode(aSource);
+	}
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::ShouldSkipChar
+// Characters mapped to certain keys (*,#) are skipped for certain languages.
+// ----------------------------------------------------------------------------
+TBool C12keyKeyMap::ShouldSkipChar(QChar aChar, TBool aSkipHashStar) const
+	{
+	return aSkipHashStar &&
+		   (aChar == KMappedCharForStar || aChar == KMappedCharForHash);
+	}
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::C12keyKeyMap
+// Fill QList with empty strings
+// ----------------------------------------------------------------------------
+C12keyKeyMap::C12keyKeyMap() :
+	CPcsKeyMap(KAmountOfKeys, KPadChar, KMaxKeysStoredInDb)
+	{
+	}
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::ConstructL
+// ----------------------------------------------------------------------------
+void C12keyKeyMap::ConstructL()
+	{
+	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());
+    if (err != KErrNone)
+        {
+        PRINT1(_L("C12keyKeyMap::ConstructL exception, err=%d"), err);
+        User::Leave(err);
+        }
+
+	PRINT(_L("End C12keyKeyMap::ConstructL"));
+	}
+
+// ----------------------------------------------------------------------------
+// C12keyKeyMap::GetTextCodecs
+// ----------------------------------------------------------------------------
+void C12keyKeyMap::GetTextCodecs()
+    {
+    iLatinCodec = QTextCodec::codecForMib(KLatin1);
+    iThaiCodec = QTextCodec::codecForMib(KThaiLanguage);
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/c12keypredictivesearchtable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,370 @@
+/*
+* 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: 
+*
+*/
+
+#include "c12keypredictivesearchtable.h"
+#include "dbsqlconstants.h"
+#include "cntitem.h"
+#include "c12keykeymap.h"
+#include <QStringList>
+
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
+
+
+// Max amount of tokens stored from contact
+const TInt KMaxTokens = 4;
+
+// How many digits are stored at most in the numeric field
+// Since BIGINT is a signed 64-bit integer, store only 15 hexadecimal characters
+// to prevent overflow when comparing upper and lower limits.
+const TInt KMaxTokenLength = 15;
+
+const quint64 KConversionError = 0xeeeeeeeeeeeeeee;
+
+#define MAPPED_CHAR_FOR_STAR	'a'
+#define MAPPED_CHAR_FOR_HASH	'b'
+
+const QChar KPadChar = 'f'; // Pad with hex-digit 0xF
+
+
+/**
+@param aDatabase A handle to the database.
+
+@return A pointer to a new C12keyPredictiveSearchTable object.
+*/
+C12keyPredictiveSearchTable*
+C12keyPredictiveSearchTable::NewL(RSqlDatabase& aDatabase)
+	{
+	PRINT(_L("C12keyPredictiveSearchTable::NewL"));
+	C12keyPredictiveSearchTable* self = C12keyPredictiveSearchTable::NewLC(aDatabase);
+	CleanupStack::Pop(self);
+	PRINT(_L("C12keyPredictiveSearchTable::NewL ends"));
+	return self;
+	}
+
+
+/**
+@param aDatabase A handle to the database.
+
+@return A pointer to a new C12keyPredictiveSearchTable object.
+*/
+C12keyPredictiveSearchTable*
+C12keyPredictiveSearchTable::NewLC(RSqlDatabase& aDatabase)
+	{
+	PRINT(_L("C12keyPredictiveSearchTable::NewLC"));
+	C12keyPredictiveSearchTable* self =
+		new (ELeave) C12keyPredictiveSearchTable(aDatabase);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PRINT(_L("C12keyPredictiveSearchTable::NewLC ends"));
+	return self;
+	}
+
+
+/**
+Destructor
+*/
+C12keyPredictiveSearchTable::~C12keyPredictiveSearchTable()
+	{
+	PRINT(_L("C12keyPredictiveSearchTable dtor"));
+	PRINT(_L("C12keyPredictiveSearchTable dtor ends"));
+	}
+
+
+/**
+Creates the 12-key predictive search tables and its indexes in the database.
+*/
+void C12keyPredictiveSearchTable::CreateTableL()
+	{
+	PRINT(_L("C12keyPredictiveSearchTable::CreateTableL"));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable0Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable1Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable2Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable3Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable4Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable5Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable6Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable7Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable8Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable9Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable10Stmnt));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable11Stmnt));
+
+
+	PRINT(_L("Create indexes"));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable0));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable0));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable0));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable0));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable1));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable1));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable1));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable1));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable2));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable2));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable2));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable2));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable3));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable3));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable3));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable3));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable4));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable4));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable4));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable4));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable5));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable5));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable5));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable5));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable6));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable6));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable6));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable6));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable7));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable7));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable7));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable7));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable8));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable8));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable8));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable8));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable9));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable9));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable9));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable9));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable10));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable10));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable10));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable10));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable11));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable11));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable11));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable11));
+
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable0));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable0));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable1));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable1));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable2));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable2));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable3));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable3));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable4));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable4));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable5));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable5));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable6));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable6));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable7));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable7));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable8));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable8));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable9));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable9));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable10));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable10));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable11));
+	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable11));
+
+	PRINT(_L("C12keyPredictiveSearchTable::CreateTableL ends"));
+	}
+
+
+QList<QChar> C12keyPredictiveSearchTable::FillAllTables() const
+	{
+	QList<QChar> tables;
+
+	const TInt KLargestDigitKey = '9';
+	for (TInt i = '0'; i <= KLargestDigitKey; ++i)
+		{
+		QChar ch = i;
+		tables.append(ch);
+		}
+	tables.append(MAPPED_CHAR_FOR_STAR);
+	tables.append(MAPPED_CHAR_FOR_HASH);
+
+	return tables;
+	}
+
+
+HBufC* C12keyPredictiveSearchTable::TableNameL(const QChar aCh) const
+	{
+	// Enough space for the longest table name
+    HBufC* tableName = HBufC::NewLC(KSqlContactPredSearchTable11().Length());
+    TPtr ptr = tableName->Des();
+	ptr.Append(GetTableNameL(aCh));
+	CleanupStack::Pop(tableName);
+	return tableName;
+	}
+
+
+TBool C12keyPredictiveSearchTable::IsValidChar(const QChar aChar) const
+	{
+	return (aChar >= '0' && aChar <= '9') ||
+			aChar == MAPPED_CHAR_FOR_STAR ||
+			aChar == MAPPED_CHAR_FOR_HASH;
+	}
+
+
+void C12keyPredictiveSearchTable::FillKeyboardSpecificFieldsL(
+	RSqlStatement& aSqlStatement,
+	QStringList aTokens)
+	{
+	const TDesC* paramNames[] = {
+		&KPredSearchNameAsNumberParam,
+		&KPredSearchNameAsNumber2Param,
+		&KPredSearchNameAsNumber3Param,
+		&KPredSearchNameAsNumber4Param};
+	for (TInt i = 0; i < aTokens.count(); ++i)
+		{
+		quint64 hex(0);
+		QT_TRYCATCH_LEAVING(hex = ConvertToHex(aTokens[i]));
+		if (hex == KConversionError)
+			{
+			User::Leave(KErrArgument);
+			}
+		User::LeaveIfError(aSqlStatement.BindInt64(
+			User::LeaveIfError(aSqlStatement.ParameterIndex(*paramNames[i])), hex));
+		}
+	}
+
+
+/**
+Set up the CCntSqlStatement objects held by the class.
+*/
+void C12keyPredictiveSearchTable::ConstructL()
+	{
+	PRINT(_L("C12keyPredictiveSearchTable::ConstructL"));
+
+	CPplPredictiveSearchTableBase::ConstructL();
+	// Set details of INSERT
+	iInsertStmnt->SetParamL(KPredSearchContactId,
+	                        KPredSearchContactIdParam);
+	iInsertStmnt->SetParamL(KPredSearchNameAsNumber,
+							KPredSearchNameAsNumberParam);
+	iInsertStmnt->SetParamL(KPredSearchNameAsNumber2,
+							KPredSearchNameAsNumber2Param);
+	iInsertStmnt->SetParamL(KPredSearchNameAsNumber3,
+							KPredSearchNameAsNumber3Param);
+	iInsertStmnt->SetParamL(KPredSearchNameAsNumber4,
+							KPredSearchNameAsNumber4Param);
+	iInsertStmnt->SetParamL(KPredSearchFirstName,
+							KPredSearchFirstNameParam);
+	iInsertStmnt->SetParamL(KPredSearchLastName,
+							KPredSearchLastNameParam);
+
+	PRINT(_L("C12keyPredictiveSearchTable::ConstructL create key map"));
+	iKeyMap = C12keyKeyMap::NewL();
+
+	PRINT(_L("C12keyPredictiveSearchTable::ConstructL ends"));
+	}
+
+
+/**
+Constructor
+*/
+C12keyPredictiveSearchTable::C12keyPredictiveSearchTable(RSqlDatabase& aDatabase) :
+	CPplPredictiveSearchTableBase(aDatabase, KMaxTokens, KMaxTokenLength)
+	{
+	}
+
+
+// TODO: maybe move this fn to CPcsKeyMap, and it can use code of GetNumericLimits()
+
+// E.g. aToken = "01230" -> append KPadChar until has KMaxTokenLength characters
+// -> "01230ffffffffff" -> convert to hexadecimal number -> 0x01230ffffffffff.
+// If this function would leave, causes panic, perhaps because of QString parameter?
+quint64 C12keyPredictiveSearchTable::ConvertToHex(QString aToken) const
+	{
+	if (aToken.length() > KMaxTokenLength)
+		{
+		return KConversionError;
+		}
+    QString padded = aToken.leftJustified(KMaxTokenLength, KPadChar);
+
+    TBuf<KMaxTokenLength> log(padded.utf16());
+    PRINT1(_L("C12keyPredictiveSearchTable::ConvertToHex padded '%S'"), &log);
+
+	// Replace unmapped char and the following characters with KPadChar.
+    QString replaced = padded;
+    bool done(false);
+    for (TInt i = 0; i < KMaxTokenLength && !done; ++i)
+        {
+        if (!IsValidChar(padded[i]))
+            {
+            // replace() does not work, it puts just one KPadChar at end
+            // replaced = padded.replace(i, KMaxTokenLength - i, KPadChar);
+
+            padded.remove(i, KMaxTokenLength - i);
+            replaced = padded.leftJustified(KMaxTokenLength, KPadChar);
+            done = true;
+
+			TBuf<KMaxTokenLength> log2(replaced.utf16());
+			PRINT1(_L("After replacing '%S'"), &log2);
+            }
+        }
+
+    const TInt KHexadecimalBase = 16;
+    bool ok(true);
+    quint64 hex = replaced.toULongLong(&ok, KHexadecimalBase);
+    if (!ok)
+        {
+		PRINT(_L("conv to hex failed"));
+		return KConversionError;
+        }
+    
+    PRINT1(_L("C12keyPredictiveSearchTable::ConvertToHex result 0x%lx"), hex);
+    return hex;
+	}
+
+
+const TDesC& C12keyPredictiveSearchTable::GetTableNameL(const QChar aCh) const
+	{
+	switch (aCh.toAscii())
+		{
+		case '0': return KSqlContactPredSearchTable0;
+		case '1': return KSqlContactPredSearchTable1;
+		case '2': return KSqlContactPredSearchTable2;
+		case '3': return KSqlContactPredSearchTable3;
+		case '4': return KSqlContactPredSearchTable4;
+		case '5': return KSqlContactPredSearchTable5;
+		case '6': return KSqlContactPredSearchTable6;
+		case '7': return KSqlContactPredSearchTable7;
+		case '8': return KSqlContactPredSearchTable8;
+		case '9': return KSqlContactPredSearchTable9;
+		case MAPPED_CHAR_FOR_STAR: return KSqlContactPredSearchTable10;
+		case MAPPED_CHAR_FOR_HASH: return KSqlContactPredSearchTable11;
+		default:
+			PRINT1(_L("C12keyPredictiveSearchTable::GetTableNameL unknown char '%c'"),
+				   aCh.toAscii());
+			User::Leave(KErrArgument);
+			return KNullDesC;
+		}
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cntpredictivesearch.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,77 @@
+/*
+* 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cntsqlsearch.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,1001 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+#include <QStringList>
+
+#include "cntsqlsearch.h"
+#include "cqwertykeymap.h"
+#include "c12keykeymap.h"
+#include <QHash>
+#include <QLocale>
+
+const char KLimitLength = 15;
+const int KTwoTokens = 2;
+const int KOneToken = 1;
+const char KLowerLimitPadding = '0';
+const char KUpperLimitPadding = 'F';
+const int KMinimumSearchPatternLength = 1;
+const int KHexadecimalBase = 16;
+
+
+#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";
+
+// Predictive search qwert table's columns
+const QString KQm1 = "n";
+const QString KQm2 = "n2";
+const QString KQm3 = "n3";
+const QString KQm4 = "n4";
+const QString KQm5 = "n5";
+const QString KQm6 = "n6";
+const QString KQm7 = "n7";
+
+// Special handling for characters that originate from * and # keys
+const QChar KStarChar('*');
+const QChar KPlusChar('+');
+const QChar KPChar('p');
+const QChar KWChar('w');
+const QChar KHashChar('#');
+
+//Predictive search table
+const QString QwertyTableName = "qm";
+
+CntSqlSearch::CntSqlSearch()
+	{
+    QT_TRAP_THROWING(mQertyKeyMap = CQwertyKeyMap::NewL());
+    QT_TRAP_THROWING(mkeyKeyMap = C12keyKeyMap::NewL());
+	}
+
+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"
+// 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")
+//
+// 6: "10", "1000"
+// One token, ends with zero.
+// In this case, query should look-up first toke and number ("10", "1000").
+
+QString CntSqlSearch::CreatePredictiveSearch(const QString &pattern)
+	{
+	int len = pattern.length();
+	QString newPattern;
+	if (isQwerty(pattern))
+	    {
+        return CreateQwertyQuery(pattern);
+	    }
+	else
+	    {
+        newPattern = ChangeStringPadings(pattern);
+        // For best performance, handle 1 digit case first
+        if (len == KMinimumSearchPatternLength)
+            {
+            // Case 1
+            return SELECT_CONTACT_ID + SelectTable(newPattern) + ORDER_BY_FIRSTNAME_LASTNAME;
+            }
+        if (len <= KLimitLength && len > KMinimumSearchPatternLength)
+            {
+            return CreateQuery(newPattern);
+            }
+        return QString(""); // Invalid pattern
+        }
+	}
+QString CntSqlSearch::selectQweryTable(const QString &pattern) const
+    {
+    QString tableNumber; 
+    if(pattern.length() > 0)
+        {
+        return QwertyTableName + tableNumber.setNum(mQertyKeyMap->MapKeyNameToValue(pattern[0]));
+        }
+    else
+        {
+        return QString("");
+        }
+    }
+QString CntSqlSearch::SelectTable(const QString &pattern) const
+	{
+        QString predictivesearch;
+        QStringList tokens = GetTokens(pattern);
+        bool ok;
+        if (pattern.length() == 0)
+                {
+                return "";
+                }
+        QString firstNumber(pattern.at(0));
+        uint hex = firstNumber.toUInt(&ok, 16);
+        if (!ok)
+            {
+            // TODO: handle error (=invalid characters in pattern)
+            }
+        switch (hex)
+            {
+            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;
+            case 10:
+                {
+                predictivesearch = QString("predictivesearch10");
+                }
+            break;
+            case 11:
+                {
+                predictivesearch = QString("predictivesearch11");
+                }
+            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;
+    }
+
+QString CntSqlSearch::CreateQwertyQuery(const QString& pattern) const
+    {
+    QStringList qwertyString; 
+    qwertyString = qwertyTokens(pattern);
+    if(qwertyString.count() == 1 )
+        {
+        if(qwertyString.at(0).length() == 1)
+            {
+            return SELECT_CONTACT_ID + selectQweryTable(qwertyString.at(0)) + ORDER_BY_FIRSTNAME_LASTNAME;
+            }
+        else if (qwertyString.at(0).length() > 1)
+            {
+            return ExactMatchSearchQwerty(qwertyString.at(0)) + ORDER_BY_FIRSTNAME_LASTNAME;
+            }
+        else
+            {
+            //Empty string
+            return QString(""); 
+            }
+        }
+    else
+        {
+        return SearchTokensFromOneTable(pattern, qwertyString, CntSqlSearch::QwertyEmail);
+        }
+    }
+// pattern length is between KMinimumSearchPatternLength...KLimitLength
+QString CntSqlSearch::CreateQuery(const QString& pattern) const
+	{
+	QStringList tokens = GetTokens(pattern);
+	if (tokens.count() < KTwoTokens)
+        {
+	    if (TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken))
+            {
+            return TwoDifferentTokensSearch(pattern, tokens);  // Case 6
+            }
+        else
+            {
+            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)); 
+	}
+
+QString CntSqlSearch::ExactMatchSearchQwerty(const QString& pattern) const
+    {
+    return QString(SELECT_CONTACT_ID + selectQweryTable(pattern) +
+                   " WHERE " + ExactMatchQwerty(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 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)
+//
+//
+// Qwert case
+// 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,
+											   QueryType queryType) const
+    {
+    QString token;
+    QString lower;
+    QString upper;
+    QString lower2;
+    QString upper2;
+    int err;
+    
+    if(queryType == CntSqlSearch::TwelveTable)
+        {
+        err = mkeyKeyMap->GetNumericLimits(tokens.at(0), lower, upper);
+        if(err)
+            {
+            return QString("");
+            }
+        err = mkeyKeyMap->GetNumericLimits(tokens.at(1), lower2, upper2);
+        if(err)
+            {
+            return QString("");
+            }
+        }
+    else
+        {
+        err = mQertyKeyMap->GetNumericLimits(tokens.at(0), lower, upper);
+        err = mQertyKeyMap->GetNumericLimits(tokens.at(1), lower2, upper2);
+        if(err)
+            {
+            return QString("");
+            }
+        }
+    QString query; 
+    if (queryType == CntSqlSearch::TwelveTable)
+		{
+        query = 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
+        {
+    
+        query = SELECT_CONTACT_ID + selectQweryTable(tokens.at(0)) + " WHERE NOT(NOT" +
+        ExactMatchQwerty(pattern) + " AND NOT" +
+        CompareTwoQwertyColumns(lower, upper, lower2, upper2) + " AND NOT" +
+        CompareTwoQwertyColumns(lower2, upper2, lower, upper) + ")";
+        }
+	query += Order(tokens, queryType);
+	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;
+	QString upper;
+	
+	TInt err = mkeyKeyMap->GetNumericLimits(token, lower, upper);
+	    
+#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;
+	}
+
+
+QString CntSqlSearch::TwoDifferentTokensSearch(const QString& pattern, const QStringList& tokens) const
+        {
+        QString token = tokens.at(0);
+        QString sortPatern = pattern;
+        sortPatern.truncate(pattern.length()-1);
+#if defined(USE_DEMORGAN)
+        QString query(SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE NOT(NOT" +
+            ExactMatch(sortPatern) +
+        " AND NOT" + ExactMatch(pattern) + ")");
+#else
+        QString query(SELECT_CONTACT_ID + SelectTable(pattern) + " WHERE (" +
+            ExactMatch(sortPatern) +  // exact match (e.g. "2")
+        ") OR " + ExactMatch(pattern)); // exact match (e.g. "20")
+#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::CompareTwoQwertyColumns(const QString& lower,
+                                        const QString& upper,
+                                        const QString& lower2,
+                                        const QString& upper2) const
+    {
+    // 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')
+        KQm2 + ">" + lower2 + " AND " + KQm2 + "<" + upper2 + " AND " +
+        KQm1 + ">" + lower + " AND " + KQm1 + "<" + upper +
+        ") AND NOT(" +
+        // 3nd & 1st column (='B')
+        KQm3 + ">" + lower2 + " AND " + KQm3 + "<" + upper2 + " AND " +
+        KQm1 + ">" + lower + " AND " + KQm1 + "<" + upper +
+        ") AND NOT(" +
+        // 3rd & 2nd column (='C')
+        KQm3 + ">" + lower2 + " AND " + KQm3 + "<" + upper2 + " AND " +
+        KQm2 + ">" + lower + " AND " + KQm2 + "<" + upper +
+        ") AND NOT(" +
+        // 4th & 1st column (='D')
+        KQm4 + ">" + lower2 + " AND " + KQm4 + "<" + upper2 + " AND " +
+        KQm1 + ">" + lower + " AND " + KQm1 + "<" + upper +
+        ") AND NOT(" +
+        // 4th & 2nd column (='E')
+        KQm4 + ">" + lower2 + " AND " + KQm4 + "<" + upper2 + " AND " +
+        KQm2 + ">" + lower + " AND " + KQm2 + "<" + upper +
+        ") AND NOT(" +
+        // 4th & 3rd column (='F')
+        KQm4 + ">" + lower2 + " AND " + KQm4 + "<" + upper2 + " AND " +
+        KQm3 + ">" + lower + " AND " + KQm3 + "<" + upper + ")))";
+        // 5th & 1rd column (='G')
+        KQm5 + ">" + lower2 + " AND " + KQm5 + "<" + upper2 + " AND " +
+        KQm1 + ">" + lower + " AND " + KQm1 + "<" + upper + ")))";
+        // 5th & 2rd column (='H')
+        KQm5 + ">" + lower2 + " AND " + KQm5 + "<" + upper2 + " AND " +
+        KQm2 + ">" + lower + " AND " + KQm2 + "<" + upper + ")))";
+        // 5th & 3rd column (='I')
+        KQm5 + ">" + lower2 + " AND " + KQm5 + "<" + upper2 + " AND " +
+        KQm3 + ">" + lower + " AND " + KQm3 + "<" + upper + ")))";
+        // 5th & 4rd column (='I')
+        KQm5 + ">" + lower2 + " AND " + KQm5 + "<" + upper2 + " AND " +
+        KQm4 + ">" + lower + " AND " + KQm4 + "<" + upper + ")))";
+        // 6th & 1rd column (='J')
+        KQm6 + ">" + lower2 + " AND " + KQm6 + "<" + upper2 + " AND " +
+        KQm1 + ">" + lower + " AND " + KQm1 + "<" + upper + ")))";
+        // 6th & 2rd column (='K')
+        KQm6 + ">" + lower2 + " AND " + KQm6 + "<" + upper2 + " AND " +
+        KQm2 + ">" + lower + " AND " + KQm2 + "<" + upper + ")))";
+        // 6th & 3rd column (='L')
+        KQm6 + ">" + lower2 + " AND " + KQm6 + "<" + upper2 + " AND " +
+        KQm3 + ">" + lower + " AND " + KQm3 + "<" + upper + ")))";
+        // 6th & 43rd column (='M')
+        KQm6 + ">" + lower2 + " AND " + KQm6 + "<" + upper2 + " AND " +
+        KQm4 + ">" + lower + " AND " + KQm4 + "<" + upper + ")))";
+        // 6th & 5rd column (='M')
+        KQm6 + ">" + lower2 + " AND " + KQm6 + "<" + upper2 + " AND " +
+        KQm5 + ">" + lower + " AND " + KQm5 + "<" + upper + ")))";
+        // 7th & 1rd column (='N')
+        KQm7 + ">" + lower2 + " AND " + KQm7 + "<" + upper2 + " AND " +
+        KQm1 + ">" + lower + " AND " + KQm1 + "<" + upper + ")))";
+        // 7th & 1rd column (='O')
+        KQm7 + ">" + lower2 + " AND " + KQm7 + "<" + upper2 + " AND " +
+        KQm2 + ">" + lower + " AND " + KQm2 + "<" + upper + ")))";
+        // 7th & 3rd column (='P')
+        KQm7 + ">" + lower2 + " AND " + KQm7 + "<" + upper2 + " AND " +
+        KQm3 + ">" + lower + " AND " + KQm3 + "<" + upper + ")))";
+        // 7th & 4rd column (='Q')
+        KQm7 + ">" + lower2 + " AND " + KQm7 + "<" + upper2 + " AND " +
+        KQm4 + ">" + lower + " AND " + KQm4 + "<" + upper + ")))";
+        // 7th & 5rd column (='Q')
+        KQm7 + ">" + lower2 + " AND " + KQm7 + "<" + upper2 + " AND " +
+        KQm5 + ">" + lower + " AND " + KQm5 + "<" + upper + ")))";
+        // 7th & 5rd column (='R')
+        KQm7 + ">" + lower2 + " AND " + KQm7 + "<" + upper2 + " AND " +
+        KQm6 + ">" + lower + " AND " + KQm6 + "<" + upper + ")))";
+       
+    return query;
+    }
+QString CntSqlSearch::ExactMatch(const QString& pattern, QString table) const
+    {
+    QString lower;
+    QString upper;
+    
+    int err = mkeyKeyMap->GetNumericLimits(pattern, lower, upper);
+    if(err)
+        {
+        return QString("");
+        }
+    
+    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(N4>lower && < N4<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
+    }
+
+QString CntSqlSearch::ExactMatchQwerty(const QString& pattern, QString table) const
+    {
+    QString lower;
+    QString upper;
+    TInt err = mQertyKeyMap->GetNumericLimits(pattern, lower, upper);
+    
+    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(N4>lower && < N4<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 + KQm1 + ">" + lower + " AND " + table + KQm1 + "<" + upper + ") AND NOT(" +
+        table + KQm2 + ">" + lower + " AND " + table + KQm2 + "<" + upper + ") AND NOT(" +
+        table + KQm3 + ">" + lower + " AND " + table + KQm3 + "<" + upper + ") AND NOT(" +
+        table + KQm4 + ">" + lower + " AND " + table + KQm4 + "<" + upper + ") AND NOT(" +
+        table + KQm5 + ">" + lower + " AND " + table + KQm5 + "<" + upper + ") AND NOT(" +
+        table + KQm6 + ">" + lower + " AND " + table + KQm6 + "<" + upper + ") AND NOT(" +
+        table + KQm7 + ">" + lower + " AND " + table + KQm7 + "<" + 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 + KQm1 + ">" + lower + " AND " + table + KQm1 + "<" + upper + ") OR (" +
+        table + KQm2 + ">" + lower + " AND " + table + KQm2 + "<" + upper + ") OR (" +
+        table + KQm3 + ">" + lower + " AND " + table + KQm3 + "<" + upper + ") OR (" +
+        table + KQm4 + ">" + lower + " AND " + table + KQm4 + "<" + upper + ") OR (" +
+        table + KQm5 + ">" + lower + " AND " + table + KQm5 + "<" + upper + ") OR (" +
+        table + KQm6 + ">" + lower + " AND " + table + KQm6 + "<" + upper + ") OR (" +
+        table + KQm7 + ">" + lower + " AND " + table + KQm7 + "<" + 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
+    {
+    const int KFirstColumn = 0;
+    const int KSecondColumn = 1;
+    QString firstColumn = numbers.at(KFirstColumn);
+    QString secondColumn = numbers.at(KSecondColumn);
+
+    if( firstColumn.count() >  1 && secondColumn.count() > 1)
+        {
+        return "(" + ExactMatch(numbers.at(KFirstColumn), SelectTable(numbers.at(KFirstColumn)))
+            + " AND " +
+            ExactMatch(numbers.at(KSecondColumn), SelectTable(numbers.at(KSecondColumn))) + ")";
+        }
+    else if(firstColumn.count() > 1)
+        {
+        return ExactMatch(numbers.at(KFirstColumn), SelectTable(numbers.at(KFirstColumn)));
+        }
+    else
+        {
+        return ExactMatch(numbers.at(KSecondColumn), SelectTable(numbers.at(KSecondColumn)));
+        }
+    }
+
+QString CntSqlSearch::Order(QStringList tokens, QueryType queryType) const
+	{
+    QString table;
+	if (tokens.count() > 1 )
+		{
+        if(queryType == CntSqlSearch::QwertyEmail)
+            {
+            table = selectQweryTable(tokens.at(0));
+            }
+        else
+            {
+            table = SelectTable(tokens.at(0));
+            }
+        return QString(" ORDER BY " + table + ".first_name, " + table + ".last_name ASC;");
+		}
+	return QString(ORDER_BY_FIRSTNAME_LASTNAME);
+	}
+
+QString CntSqlSearch::ChangeStringPadings( const QString &pattern ) const
+    { 
+    QString newPattern = pattern;
+    if (QLocale::system().language() == QLocale::Thai)
+        {
+        newPattern.remove(KStarChar, Qt::CaseInsensitive);
+        newPattern.remove(KPlusChar, Qt::CaseInsensitive);
+        newPattern.remove(KPChar, Qt::CaseInsensitive);
+        newPattern.remove(KWChar, Qt::CaseInsensitive);
+        newPattern.remove(KHashChar, Qt::CaseInsensitive);
+        }
+    else
+        { 
+        newPattern.replace(KStarChar, 'A');
+        newPattern.replace(KPlusChar, 'A');
+        newPattern.replace(KPChar, 'A');
+        newPattern.replace(KWChar, 'A');
+        newPattern.replace(KHashChar, 'B');
+        }
+    return newPattern;
+    }
+
+bool CntSqlSearch::TestPattern( const QString &pattern, SearchMethod searchMethod ) const
+    {
+    QStringList tokens = GetTokens(pattern);
+    if (!tokens.isEmpty() && !pattern.isEmpty())
+        {
+        if (CntSqlSearch::ZerosEndOfFirstToken == searchMethod)
+            {
+            if( tokens.count() == KOneToken && !tokens.at(0).contains("0")
+                && !pattern.startsWith('0') && pattern.count('0') == 1
+                && pattern.endsWith('0'))
+                {
+                return true;
+                }
+            }
+        if (CntSqlSearch::ZeroIsFirstNumber == searchMethod )
+            {
+            if(pattern.startsWith('0') && pattern.count() > 1 
+                && pattern.at(1) != '0')
+                {
+                return true;
+                }
+            }
+        }
+    return false;
+    }
+
+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);
+            }
+        }
+    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);
+    }
+
+bool CntSqlSearch::isQwerty(const QString &pattern)
+    {
+    QChar rs(30);
+    int rs_index = pattern.indexOf(rs);  
+    int qwerty_index = pattern.indexOf("vqwerty");
+    if(rs_index >= 0 && qwerty_index >= 0 )
+        {
+        if(rs_index + 1 == qwerty_index)
+            {
+            return true;
+            }
+        return false;
+        }
+    return false;
+    }
+QStringList CntSqlSearch::qwertyTokens(const QString &pattern) const
+    {
+    QString decodePatern;
+    QString keymapsString = mQertyKeyMap->GetMappedString(pattern);
+    int index = pattern.indexOf(30);
+    if(index > 0 )
+        {
+        QString decodePatern = keymapsString.left(index);
+        return decodePatern.split(32, QString::SkipEmptyParts);
+        }
+    else
+        {
+        return QStringList("");
+        }
+    }
+QString CntSqlSearch::UpperLimit( const QString &pattern ) const
+    {
+    return Pad( pattern, KUpperLimitPadding );
+    }
+
+QString CntSqlSearch::LowerLimit( const QString &pattern ) const
+    {
+    return Pad( pattern, KLowerLimitPadding );
+    }
--- a/phonebookengines/contactsmodel/cntplsql/src/cpcskeymap.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/src/cpcskeymap.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -16,98 +16,27 @@
 
 // INCLUDE FILES
 #include "cpcskeymap.h"
+#include <QChar>
+#include <QString>
 
 #if defined(USE_ORBIT_KEYMAP)
-
-// If defined, only the currently used language's keymap is used
-//#define USE_ONLY_DEFAULT_LANG_KEYMAP
-
-
-#include <QLocale>
-#include <hbinputlanguage.h>
 #include <hbinputkeymap.h>
 #include <hbinputkeymapfactory.h>
 #endif // #if defined(USE_ORBIT_KEYMAP)
 
-
-#if defined(_DEBUG)
-#include <e32debug.h> // RDebug
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
 
-#define PRINT(x)			RDebug::Print(x)
-#define PRINT1(x,y)			RDebug::Print(x,y)
-#define PRINT2(x,y,z)		RDebug::Print(x,y,z)
-#define PRINT3(w,x,y,z)		RDebug::Print(w,x,y,z)
-#else // #if defined(_DEBUG)
-#define PRINT(x)            
-#define PRINT1(x,y)         
-#define PRINT2(x,y,z)       
-#define PRINT3(w,x,y,z)
-#endif // #if defined(_DEBUG)
-
-
-#define KSpaceChar      ' '
-
-#if defined(USE_ORBIT_KEYMAP)
-#define KSeparatorChar  ' '
-#endif // #if defined(USE_ORBIT_KEYMAP)
+const QChar KSpaceChar = ' ';
 
 // Separator character stored in predictive search table columns
-_LIT(KSeparator, " ");
-
-#if defined(USE_ORBIT_KEYMAP)
-// How many keys have mappings in ITU-T keypad (keys 0..9, * and # have mappings)
-const TInt KAmountOfKeys = 12;
-
-// The first key of the keyboard has value zero ('1' in the 12-key virtual keypad) 
-enum TKeyId
-    {
-    EKey1 = 0,
-    EKey2,
-    EKey3,
-    EKey4,
-    EKey5,
-    EKey6,
-    EKey7,
-    EKey8,
-    EKey9,
-	EKey0,
-	EKeyStar,
-	EKeyHash,
-	ELastKey = EKeyHash
-    };
-
-const QChar KStar = '*';
-const QChar KPlus = '+';
-const QChar KHash = '#';
-#endif // #if defined(USE_ORBIT_KEYMAP)
-
-// * key is mapped to this
-const TChar KMappedCharForStar = 'a';
-// # key is mapped to this
-const TChar KMappedCharForHash = 'b';
-// Unmapped (unknown) characters are replaced with this
-const TChar KPadChar = 'f';
+const QChar KSeparatorChar = ' ';
 
 
 // ============================== MEMBER FUNCTIONS ============================
 
 // ----------------------------------------------------------------------------
-// CPcsKeyMap::NewL
-// ----------------------------------------------------------------------------
-CPcsKeyMap* CPcsKeyMap::NewL()
-	{
-    PRINT(_L("Enter CPcsKeyMap::NewL"));
-    
-    CPcsKeyMap* self = new (ELeave) CPcsKeyMap();
-    CleanupStack::PushL(self);
-    self->ConstructL();
-    CleanupStack::Pop(self);
-
-    PRINT(_L("End CPcsKeyMap::NewL"));
-    return self;
-	}
-
-// ----------------------------------------------------------------------------
 // CPcsKeyMap::~CPcsKeyMap
 // ----------------------------------------------------------------------------
 CPcsKeyMap::~CPcsKeyMap()
@@ -117,40 +46,93 @@
     }
 
 // ----------------------------------------------------------------------------
-// CPcsKeyMap::GetNumericKeyStringL
-// If aPlainConversion is EFalse, supports sub-string searches and space is
-// converted to a separator character (not zero).
+// CPcsKeyMap::GetMappedStringL
 // ----------------------------------------------------------------------------
-HBufC* CPcsKeyMap::GetNumericKeyStringL(const TDesC& aSource,
-                                        TBool aPlainConversion) const
+HBufC* CPcsKeyMap::GetMappedStringL(const TDesC& aSource) const
     {
-    PRINT1(_L("Enter CPcsKeyMap::GetNumericKeyStringL input '%S'"), &aSource);
+    PRINT1(_L("Enter CPcsKeyMap::GetMappedStringL input '%S'"), &aSource);
+
+	QString source((QChar*)aSource.Ptr(), aSource.Length());
+	QString result;
+	TInt err(KErrNone);
+	QT_TRYCATCH_ERROR(err, result = GetMappedString(source));
+	User::LeaveIfError(err);
+
+    HBufC* destination = HBufC::NewL(result.length());
+	destination->Des().Copy(result.utf16());
+
+    PRINT1(_L("End CPcsKeyMap::GetMappedStringL result '%S'"), destination);
+    return destination;
+    }
 
-    TInt length = aSource.Length();
-    HBufC* destination = HBufC::NewL(length);
-    TPtr ptr = destination->Des();
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::GetMappedString
+// ----------------------------------------------------------------------------
+QString CPcsKeyMap::GetMappedString(QString aSource) const
+	{
+#if defined(WRITE_PRED_SEARCH_LOGS)
+	const int KLogLength = 30;
+	TBuf<KLogLength> log(aSource.left(KLogLength).utf16());
+	PRINT1(_L("Enter CPcsKeyMap::GetMappedString input '%S'"), &log);
+#endif
 
-    for (TInt i = 0; i < aSource.Length(); ++i)
+	QString destination;
+	TBool skipHashStar = DetermineSpecialCharBehaviour(aSource);
+	TInt length = aSource.length();
+
+    for (int i = 0; i < length; ++i)
         {
-        if (!aPlainConversion && aSource[i] == KSpaceChar)
+        if (aSource[i] == KSpaceChar)
             {
-            ptr.Append(KSeparator);
+            destination.append(KSeparatorChar);
             }
         else
-            {
+			{
+			QChar ch(0);
 #if defined(USE_ORBIT_KEYMAP)
-            ptr.Append(KeyForCharacter(aSource[i]));
+            ch = MappedKeyForChar(aSource[i]);
 #else
-			TChar a = aSource[i];
-			TChar b = a.GetUpperCase();
-			ptr.Append(GetNumericValueForChar(b));
+            ch = UseHardcodedKeyMap(aSource[i]);            
+#endif
+			if (!ShouldSkipChar(ch, skipHashStar))
+				{
+				destination.append(ch);
+				}
+			}
+		}
+#if defined(WRITE_PRED_SEARCH_LOGS)
+	log = destination.left(KLogLength).utf16();
+	PRINT1(_L("End CPcsKeyMap::GetMappedString result '%S'"), &log);
 #endif
-            }
-        }
+    return destination;
+	}
 
-    PRINT1(_L("End CPcsKeyMap::GetNumericKeyStringL result '%S'"), destination);
-    return destination;
-    }
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::GetNumericLimitsL
+// In order to speed up the execution, caller should convert search pattern
+// with a one call to CPcsKeyMap::GetMappedStringL() and then pass the tokens
+// to CPcsKeyMap::GetNumericLimitsL().
+// So it is expected that aString contains only certain characters.
+// ----------------------------------------------------------------------------
+TInt CPcsKeyMap::GetNumericLimits(QString aString,
+								  QString& aLowerLimit,
+								  QString& aUpperLimit) const
+	{
+	PRINT(_L("CPcsKeyMap::GetNumericLimits"));
+	if (aString.length() > iMaxKeysStoredInDb)
+		{
+		QString truncated = aString.left(iMaxKeysStoredInDb);
+		aString = truncated;
+		}
+
+	TInt err = ComputeValue(aString, EFalse, aLowerLimit);
+	if (err == KErrNone)
+		{
+		err = ComputeValue(aString, ETrue, aUpperLimit);
+		}
+	PRINT1(_L("End CPcsKeyMap::GetNumericLimits ret=%d"), err);
+	return err;
+	}
 
 #if defined(USE_ORBIT_KEYMAP)
 // ----------------------------------------------------------------------------
@@ -162,79 +144,146 @@
     }
 
 // ----------------------------------------------------------------------------
-// CPcsKeyMap::CPcsKeyMap
-// Fill QList with empty strings
+// CPcsKeyMap::SetHardcodedCharacters
+// Default implementation selects only the current default language.
+// ----------------------------------------------------------------------------
+QList<HbInputLanguage> CPcsKeyMap::SelectLanguages()
+	{
+	QList<HbInputLanguage> languages;
+	HbInputLanguage inputLanguage(QLocale::system().language()); 
+	languages << inputLanguage;
+	return languages;
+	}
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::SetHardcodedCharacters
+// Default implementation does nothing
 // ----------------------------------------------------------------------------
-CPcsKeyMap::CPcsKeyMap() :
-    iKeyMapping() 
+void CPcsKeyMap::SetHardcodedCharacters()
+	{
+	}
+#endif // #if defined(USE_ORBIT_KEYMAP)
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::DetermineSpecialCharBehaviour
+// Default implementation
+// ----------------------------------------------------------------------------
+TBool CPcsKeyMap::DetermineSpecialCharBehaviour(QString /*aSource*/) const
 	{
+	return EFalse;
+	}
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::ShouldSkipChar
+// Default implementation
+// ----------------------------------------------------------------------------
+TBool CPcsKeyMap::ShouldSkipChar(QChar /*aChar*/, TBool /*aSkipHashStar*/) const
+	{
+	return EFalse;
 	}
 
 // ----------------------------------------------------------------------------
 // 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, ContructKeyboardMappings());
-    if (err != KErrNone)
+	QT_TRYCATCH_ERROR(err,
+		{
+		InitKeyMappings();
+		SetHardcodedCharacters();
+		ConstructLanguageMappings(aKeyboardType);
+		});
+	if (err != KErrNone)
         {
-        PRINT1(_L("ContructKeyboardMappings threw exception, err=%d"), err);
+        PRINT1(_L("CPcsKeyMap::ConstructL exception, err=%d"), err);
         User::Leave(err);
         }
+#endif
+
+	PRINT(_L("End CPcsKeyMap::ConstructL"));
+	}
+
+// ----------------------------------------------------------------------------
+// CPcsKeyMap::CPcsKeyMap
+// ----------------------------------------------------------------------------
+#if defined(USE_ORBIT_KEYMAP)
+CPcsKeyMap::CPcsKeyMap(TInt aAmountOfKeys,
+					   QChar aPadChar,
+					   TInt aMaxKeysStoredInDb) :
+	iKeyMapping(),
+	iAmountOfKeys(aAmountOfKeys),
+	iPadChar(aPadChar),
+	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.
+// ----------------------------------------------------------------------------
+void CPcsKeyMap::InitKeyMappings()
+	{
+    PRINT(_L("Enter CPcsKeyMap::InitKeyMappings"));
+
+	for (TInt i = 0; i < iAmountOfKeys; ++i)
+        {
+        iKeyMapping << QString("");
+        }
 	}
 
 // ----------------------------------------------------------------------------
-// CPcsKeyMap::ContructKeyboardMappings
-// Fetch keymap for every language/country pair present.
-// Even though most languages map *, + and # to 1-key, they are here mapped to
-// the distinct *-key or #-key of the 12-key ITU-T keypad.
+// CPcsKeyMap::ConstructLanguageMappings
+// Fetch keymap for selected languages.
 // ----------------------------------------------------------------------------
-void CPcsKeyMap::ContructKeyboardMappings()
+void CPcsKeyMap::ConstructLanguageMappings(HbKeyboardType aKeyboardType) 
 	{
-    PRINT(_L("Enter CPcsKeyMap::ContructKeyboardMappings"));
+    PRINT(_L("Enter CPcsKeyMap::ConstructLanguageMappings"));
 
-	for (TInt i = 0; i < KAmountOfKeys; ++i)
-        {
-        iKeyMapping << QString("");
-        }
-	
-	iKeyMapping[EKeyStar].append(KStar);
-	iKeyMapping[EKeyStar].append(KPlus);
-	iKeyMapping[EKeyHash].append(KHash);
-	iHardcodedChars.append(KStar);
-	iHardcodedChars.append(KPlus);
-	iHardcodedChars.append(KHash);
-
-#if defined(_DEBUG)
+#if defined(WRITE_PRED_SEARCH_LOGS)
     TInt count(0);
 #endif
-    QList<HbInputLanguage> languages;
-#if defined(USE_ONLY_DEFAULT_LANG_KEYMAP)
-	HbInputLanguage inputLanguage(QLocale::system().language()); 
-	languages << inputLanguage;
-#else
-    languages = AvailableLanguages();
-#endif
+
+	QList<HbInputLanguage> languages = SelectLanguages();
+    PRINT1(_L("build keymap from %d language(s)"), languages.count());
+
 	TInt languageCount = languages.size();
 	for (TInt lang = 0; lang < languageCount; ++lang)
 		{
         PRINT2(_L("(%d) handle language %d"), lang, languages[lang].language());
 		if (IsLanguageSupported(languages[lang].language()))
 			{
-/*			PRINT2(_L("Constructing keymap for lang=%d,var=%d"),
+			PRINT2(_L("Constructing keymap for lang=%d,var=%d"),
 				   languages[lang].language(),
-				   languages[lang].variant()); */
+				   languages[lang].variant());
 			const HbKeymap* keymap =
 				HbKeymapFactory::instance()->keymap(languages[lang].language(),
                                                     languages[lang].variant());
 			if (keymap)
 			    {
-				for (TInt key = EKey1; key <= ELastKey; ++key) 
+				for (TInt key = 0; key < iAmountOfKeys; ++key)
                     {
-//                    PRINT1(_L("handle key(enum value %d)"), key); // test
-                    const HbMappedKey* mappedKey = keymap->keyForIndex(HbKeyboardVirtual12Key, key);
-					// mappedKey can be NULL, as most languages don't have mapping for EKeyStar, EKeyHash
+                    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.."
@@ -248,13 +297,24 @@
 							if (!iKeyMapping[key].contains(ch) &&
 								!iHardcodedChars.contains(ch))
 								{
-/*								PRINT3(_L("CPcsKeyMap: map key(%d) <-> char='%c'(0x%x)"),
-									   KeyIdToNumber(key),
-									   ch.toAscii(),
-									   ch.toAscii()); */
-#if defined(_DEBUG)
+#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
+#endif // #if defined(WRITE_PRED_SEARCH_LOGS)
 								iKeyMapping[key] += ch;
 								}
 							}
@@ -268,47 +328,12 @@
 			}
 		}
 
-#if defined(_DEBUG)
-    PRINT1(_L("End CPcsKeyMap::ContructKeyboardMappings keymap has %d chars"), count);
+#if defined(WRITE_PRED_SEARCH_LOGS)
+    PRINT1(_L("End CPcsKeyMap::ConstructLanguageMappings keymap has %d chars"), count);
 #endif
 	}
 
 // ----------------------------------------------------------------------------
-// CPcsKeyMap::AvailableLanguages
-// Put default language at the beginning of the language list, so that
-// ContructKeyboardMappingsL handles it first. 
-// ----------------------------------------------------------------------------
-QList<HbInputLanguage> CPcsKeyMap::AvailableLanguages() const
-    {
-    PRINT(_L("Enter CPcsKeyMap::AvailableLanguages"));
-
-	QList<HbInputLanguage> languages = HbKeymapFactory::availableLanguages();
-
-#if 1 // This code would make sure the default language is at the beginning of
-	  // list of available languages. But since there is resource leak, the code
-	  // is currently commented out until the leak is fixed.
-	QLocale::Language currentLanguage = QLocale::system().language();
-    if (!IsLanguageSupported(currentLanguage))
-        {
-        PRINT(_L("current lang not supported, use english")); //test
-        currentLanguage = QLocale::English;
-        }
-    HbInputLanguage defaultLanguage(currentLanguage);    
-    if (languages.contains(defaultLanguage))
-        {
-        PRINT(_L("remove default lang")); //test
-        languages.removeOne(defaultLanguage);
-        }
-    PRINT(_L("insert default lang as first lang")); //test
-    languages.prepend(defaultLanguage); // THIS LEAKS RESOURCES!
-#endif
-
-    PRINT1(_L("End CPcsKeyMap::AvailableLanguages found %d languages"),
-           languages.count());
-    return languages;
-    }
-
-// ----------------------------------------------------------------------------
 // CPcsKeyMap::IsLanguageSupported
 // ----------------------------------------------------------------------------
 TBool CPcsKeyMap::IsLanguageSupported(QLocale::Language aLanguage) const
@@ -317,170 +342,26 @@
 	}
 
 // ----------------------------------------------------------------------------
-// CPcsKeyMap::KeyForCharacter
+// CPcsKeyMap::MappedKeyForChar
 // Loop all QStrings of iKeyMapping to find one containing the character.
-// If the character is not mapped, use the character itself.
+// If the character is not mapped, use pad character.
 // ----------------------------------------------------------------------------
-TChar CPcsKeyMap::KeyForCharacter(const TChar& aChar) const
+const QChar CPcsKeyMap::MappedKeyForChar(const QChar aChar) const
 	{
-    TUint charValue(aChar);
-    QChar ch(charValue);
-    for (TInt index = 0; index < KAmountOfKeys; ++index) 
+    for (TInt index = 0; index < iAmountOfKeys; ++index) 
         {
-        if (iKeyMapping[index].contains(ch))
+        if (iKeyMapping[index].contains(aChar))
             {
-            return ArrayIndexToNumberChar(index);
+			return ArrayIndexToMappedChar(index);
             }
         }
 
-    PRINT2(_L("CPcsKeyMap::KeyForCharacter no mapping for char '%c' (0x%x)"),
-           (TUint)aChar, (TUint)aChar);
-	return KPadChar;
-    }
-
-#if defined(_DEBUG)
-// ----------------------------------------------------------------------------
-// CPcsKeyMap::KeyIdToNumber
-// Map Orbit API's key id to the number that the key results when pressed. 
-// ----------------------------------------------------------------------------
-TInt CPcsKeyMap::KeyIdToNumber(TInt aKeyId) const
-	{
-	switch (aKeyId)
-		{
-		case EKey1:
-		case EKey2:
-		case EKey3:
-		case EKey4:
-		case EKey5:
-		case EKey6:
-		case EKey7:
-		case EKey8:
-		case EKey9:
-		case EKeyStar:
-		case EKeyHash:
-			return aKeyId + 1;
-		case EKey0:
-			return 0;
-		default:
-		    PRINT1(_L("CPcsKeyMap::KeyIdToNumber invalid index %d"), aKeyId);
-			User::Panic(_L("CPcsKeyMap::KeyIdToNumber"), KErrArgument);
-			return 0;
-		}
-	}
+#if _DEBUG
+	TUint ch = aChar.unicode();
+	PRINT2(_L("CPcsKeyMap::MappedKeyForChar no mapping for char '%c' (0x%x)"),
+		   ch, ch);
 #endif
-
-// ----------------------------------------------------------------------------
-// CPcsKeyMap::ArrayIndexToNumberChar
-// Map index of iKeyMapping list, to the number char that the mapping is for.
-// ----------------------------------------------------------------------------
-TChar CPcsKeyMap::ArrayIndexToNumberChar(TInt aArrayIndex) const
-	{
-	__ASSERT_DEBUG(aArrayIndex < KAmountOfKeys,
-				   User::Panic(_L("CPcsKeyMap::ArrayIndexToNumberChar"),
-				   KErrOverflow));
-	switch (aArrayIndex)
-		{
-		case EKey0:
-			return '0';
-		case EKeyStar:
-			return KMappedCharForStar;
-		case EKeyHash:
-			return KMappedCharForHash;
-		default:
-			return aArrayIndex + '1';
-		}
-	}
-#else // #if defined(USE_ORBIT_KEYMAP)
-CPcsKeyMap::CPcsKeyMap()
-	{
-	}
-
-void CPcsKeyMap::ConstructL()
-	{
-	}
-
-TChar CPcsKeyMap::GetNumericValueForChar(TChar input) const
-    {
-	TChar ret = '0';
-    switch (input)
-        {
-        case 'A': 
-        case 'B': 
-        case 'C':
-            ret = '2';
-            break;
-
-        case 'D': 
-        case 'E':
-        case 'F':
-            ret = '3';
-            break;
-            
-        case 'G': 
-        case 'H':
-        case 'I':
-            ret = '4';
-            break;
-
-        case 'J': 
-        case 'K': 
-        case 'L':
-            ret = '5';
-            break;
-
-        case 'M': 
-        case 'N': 
-        case 'O':
-            ret = '6';
-            break;
-      
-        case 'P': 
-        case 'Q':
-        case 'R': 
-        case 'S':
-            ret = '7';
-            break;
-
-        case 'T':
-        case 'U': 
-        case 'V':
-            ret = '8';
-            break;
-
-        case 'W':
-        case 'X':
-        case 'Y': 
-        case 'Z':
-            ret = '9';
-            break;
-
-		case '*':
-		case '+':
-		    ret = KMappedCharForStar;
-		    break;
-		    
-		case '#':
-		    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;    
+	return iPadChar;
     }
 #endif // #if defined(USE_ORBIT_KEYMAP)
 
--- a/phonebookengines/contactsmodel/cntplsql/src/cpplcontacttable.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/src/cpplcontacttable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -443,7 +443,8 @@
     			User::LeaveIfError(stmnt.BindText(KParamIndex, textToSet));
 			    }			}
 		else if (field.StorageType() == KStorageTypeText &&  // the field is textual
-				 field.TextStorage()->Text().Length() )      // ignore empty fields
+				 field.TextStorage()->Text().Length() &&     // ignore empty fields
+				 custFiltFields != NULL)
 			{
 			// the field is not stored in contact table but potentially maps to a hint
 			hint.UpdateHintL(field, *custFiltFields);
--- a/phonebookengines/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,94 +17,38 @@
 
 #include "pltables.h"
 #include "dbsqlconstants.h"
+#include "cpcskeymap.h"
 #include "cntitem.h"
-#include "cpcskeymap.h"
 #include <QStringList>
+#include "predictivesearchlog.h"
 
 
 // How many characters from the beginning of the first name and last name are
 // stored. This only affects how precisely the results are put in alphabetic order.
 const TInt KCharactersFromName = 16;
 
-// Max amount of tokens stored from contact
-const TInt KMaxTokens = 4;
-
-// How many digits are stored at most in the numeric field
-// Since BIGINT is a signed 64-bit integer, store only 15 hexadecimal characters
-// to prevent overflow when comparing upper and lower limits.
-const TInt KMaxDigits = 15;
-
-const quint64 KConversionError = 0xeeeeeeeeeeeeeee;
-
-#define MAPPED_CHAR_FOR_STAR	'a'
-#define MAPPED_CHAR_FOR_HASH	'b'
-
-const QChar KMappedQCharForStar = MAPPED_CHAR_FOR_STAR;
-const QChar KMappedQCharForHash = MAPPED_CHAR_FOR_HASH;
-
-// These must be same as in cpcskeymap.cpp
-const TChar KMappedCharForStar = MAPPED_CHAR_FOR_STAR;
-const TChar KMappedCharForHash = MAPPED_CHAR_FOR_HASH;
-const QChar KPadChar = 'f'; // Pad with hex-digit 0xF
-
-
-/**
-@param aDatabase A handle to the database.
-@param aProperties A contact properties object.
-
-@return A pointer to a new CPplPredictiveSearchTable object.
-*/
-CPplPredictiveSearchTable*
-CPplPredictiveSearchTable::NewL(RSqlDatabase& aDatabase)
-	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::NewL"));
-	CPplPredictiveSearchTable* self = CPplPredictiveSearchTable::NewLC(aDatabase);
-	CleanupStack::Pop(self);
-	RDebug::Print(_L("CPplPredictiveSearchTable::NewL ends"));
-	return self;
-	}
-
-
-/**
-@param aDatabase A handle to the database.
-@param aProperties A contact properties object.
-
-@return A pointer to a new CPplPredictiveSearchTable object.
-*/
-CPplPredictiveSearchTable*
-CPplPredictiveSearchTable::NewLC(RSqlDatabase& aDatabase)
-	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::NewLC"));
-	CPplPredictiveSearchTable* self =
-		new (ELeave) CPplPredictiveSearchTable(aDatabase);
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	RDebug::Print(_L("CPplPredictiveSearchTable::NewLC ends"));
-	return self;
-	}
-
 
 /**
 Destructor
 */
-CPplPredictiveSearchTable::~CPplPredictiveSearchTable()
+CPplPredictiveSearchTableBase::~CPplPredictiveSearchTableBase()
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable dtor"));
+	PRINT(_L("CPplPredictiveSearchTableBase dtor"));
 	delete iInsertStmnt;
 	delete iDeleteStmnt;
 	delete iKeyMap;
-	RDebug::Print(_L("CPplPredictiveSearchTable dtor ends"));
+	PRINT(_L("CPplPredictiveSearchTableBase dtor ends"));
 	}
 
 
 /**
 @param aItem A contact item whose data are added to the table.
 */
-void CPplPredictiveSearchTable::CreateInDbL(CContactItem& aItem)
+void CPplPredictiveSearchTableBase::CreateInDbL(CContactItem& aItem)
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::CreateInDbL"));
+	PRINT(_L("CPplPredictiveSearchTableBase::CreateInDbL"));
 	WriteToDbL(aItem);
-	RDebug::Print(_L("CPplPredictiveSearchTable::CreateInDbL ends"));
+	PRINT(_L("CPplPredictiveSearchTableBase::CreateInDbL ends"));
 	}
 
 
@@ -114,9 +58,9 @@
 
 @param aItem A contact item whose data is updated in the database.
 */
-void CPplPredictiveSearchTable::UpdateL(const CContactItem& aItem)
+void CPplPredictiveSearchTableBase::UpdateL(const CContactItem& aItem)
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::UpdateL"));
+	PRINT(_L("CPplPredictiveSearchTableBase::UpdateL"));
 
 	TBool lowDiskErrorOccurred(EFalse);
 	DeleteFromAllTablesL(aItem.Id(), lowDiskErrorOccurred);
@@ -126,7 +70,7 @@
 	    }
 	WriteToDbL(aItem);
 
-	RDebug::Print(_L("CPplPredictiveSearchTable::UpdateL ends"));
+	PRINT(_L("CPplPredictiveSearchTableBase::UpdateL ends"));
 	}
 
 
@@ -136,160 +80,56 @@
 @param aItem The contact item to be deleted. It contains contact id, but not
              first name or last name fields.
 */
-void CPplPredictiveSearchTable::DeleteL(const CContactItem& aItem,
-										TBool& aLowDiskErrorOccurred)
+void CPplPredictiveSearchTableBase::DeleteL(const CContactItem& aItem,
+											TBool& aLowDiskErrorOccurred)
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::DeleteL"));
+	PRINT(_L("CPplPredictiveSearchTableBase::DeleteL"));
 
 	DeleteFromAllTablesL(aItem.Id(), aLowDiskErrorOccurred); 
 
-	RDebug::Print(_L("CPplPredictiveSearchTable::DeleteL ends"));
+	PRINT(_L("CPplPredictiveSearchTableBase::DeleteL ends"));
 	}
 
 
 /**
-Creates the comm_addr table and its indexes in the database.
+Default implementation returns empty list.
 */
-void CPplPredictiveSearchTable::CreateTableL()
+QStringList CPplPredictiveSearchTableBase::GetTableSpecificFields(
+	const CContactItem& /*aItem*/,
+	TBool& aMandatoryFieldsPresent) const
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::CreateTableL"));
-
-	RDebug::Print(_L("Create 12 tables"));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable0Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable1Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable2Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable3Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable4Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable5Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable6Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable7Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable8Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable9Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable10Stmnt));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable11Stmnt));
+	aMandatoryFieldsPresent = ETrue;
+	QStringList emptyList;
+	return emptyList;
+	}
 
 
-	RDebug::Print(_L("Create indexes"));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable0));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable0));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable0));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable0));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable1));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable1));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable1));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable1));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable2));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable2));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable2));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable2));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable3));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable3));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable3));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable3));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable4));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable4));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable4));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable4));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable5));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable5));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable5));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable5));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable6));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable6));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable6));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable6));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable7));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable7));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable7));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable7));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable8));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable8));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable8));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable8));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable9));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable9));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable9));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable9));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable10));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable10));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable10));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable10));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable11));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable11));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable11));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable11));
-
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable0));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable0));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable1));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable1));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable2));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable2));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable3));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable3));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable4));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable4));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable5));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable5));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable6));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable6));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable7));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable7));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable8));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable8));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable9));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable9));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable10));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable10));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable11));
-	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable11));
-
-	RDebug::Print(_L("CPplPredictiveSearchTable::CreateTableL ends"));
+HBufC* CPplPredictiveSearchTableBase::GetNextTableNameL(QList<QChar>& aTables) const
+	{
+	HBufC* tableName(NULL);
+	if (aTables.count() > 0)
+		{
+		tableName = TableNameL(aTables[0]);
+		aTables.removeFirst();
+//		PRINT1(_L("CPplPredictiveSearchTableBase::GetNextTableNameL '%S'"), tableName);
+        }
+	return tableName;
 	}
 
 
 /**
 Set up the CCntSqlStatement objects held by the class.
 */
-void CPplPredictiveSearchTable::ConstructL()
+void CPplPredictiveSearchTableBase::ConstructL()
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::ConstructL"));
+	PRINT(_L("CPplPredictiveSearchTableBase::ConstructL"));
 
 	// Using dummy table names here
 	TCntSqlStatementType insertType(EInsert, KSqlContactPredSearchTable0);
 	TCntSqlStatementType deleteType(EDelete, KSqlContactPredSearchTable0);
+	iInsertStmnt = TSqlProvider::GetSqlStatementL(insertType);
+	// Details of INSERT are done in subclass
 
-	// Insert new record
-	// INSERT INTO predictivesearchX (X=0..11)
-	//   (contact_id, nbr, nbr2, nbr3, nbr4, first_name, last_name)
-	//   VALUES (contact_id value, nbr value, nbr2 value, nbr3 value, nbr4 value,
-	//			 first_name value, last_name value);
-	iInsertStmnt = TSqlProvider::GetSqlStatementL(insertType);
-	iInsertStmnt->SetParamL(KPredSearchContactId,
-	                        KPredSearchContactIdParam);
-	iInsertStmnt->SetParamL(KPredSearchNameAsNumber,
-							KPredSearchNameAsNumberParam);
-	iInsertStmnt->SetParamL(KPredSearchNameAsNumber2,
-							KPredSearchNameAsNumber2Param);
-	iInsertStmnt->SetParamL(KPredSearchNameAsNumber3,
-							KPredSearchNameAsNumber3Param);
-	iInsertStmnt->SetParamL(KPredSearchNameAsNumber4,
-							KPredSearchNameAsNumber4Param);
-	iInsertStmnt->SetParamL(KPredSearchFirstName,
-							KPredSearchFirstNameParam);
-	iInsertStmnt->SetParamL(KPredSearchLastName,
-							KPredSearchLastNameParam);
 
 	const TInt KWhereContactIdBufSize(
 		KWhereStringEqualsStringFormatText().Size() +
@@ -305,31 +145,47 @@
 	//	WHERE contact_id = [contact id value];
 	iDeleteStmnt = TSqlProvider::GetSqlStatementL(deleteType);
 	iDeleteStmnt->SetConditionL(*whereContactIdClause);
+	CleanupStack::PopAndDestroy(whereContactIdClause);
 
-	CleanupStack::PopAndDestroy(whereContactIdClause);
-		
-	RDebug::Print(_L("CPplPredictiveSearchTable::ConstructL create key map"));
-	iKeyMap = CPcsKeyMap::NewL();
-
-	RDebug::Print(_L("CPplPredictiveSearchTable::ConstructL ends"));
+	PRINT(_L("CPplPredictiveSearchTableBase::ConstructL ends"));
 	}
 
 
 /**
 Constructor
 */
-CPplPredictiveSearchTable::CPplPredictiveSearchTable(RSqlDatabase& aDatabase) :
-	iDatabase(aDatabase)
+CPplPredictiveSearchTableBase::CPplPredictiveSearchTableBase(
+	RSqlDatabase& aDatabase, TInt aMaxTokens, TInt aMaxTokenLength) :
+	iDatabase(aDatabase),
+	iMaxTokens(aMaxTokens),
+	iMaxTokenLength(aMaxTokenLength)
+	{
+	}
+
+
+QList<QChar> CPplPredictiveSearchTableBase::DetermineTables(QStringList aTokens) const
 	{
+	QList<QChar> tables;
+	for (TInt i = aTokens.count() - 1; i >= 0; --i)
+		{
+		QChar ch = aTokens[i][0];
+		__ASSERT_ALWAYS(IsValidChar(ch),
+						User::Panic(_L("DetermineTables"), KErrArgument));
+		if (!tables.contains(ch))
+			{
+			tables.append(ch);
+			}
+		}
+	return tables;
 	}
 
 
 // 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.
-void CPplPredictiveSearchTable::WriteToDbL(const CContactItem& aItem)
+void CPplPredictiveSearchTableBase::WriteToDbL(const CContactItem& aItem)
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::WriteToDbL"));
+	PRINT(_L("CPplPredictiveSearchTableBase::WriteToDbL"));
 
 	HBufC* firstNameAsNbr(NULL); // owned
     HBufC* lastNameAsNbr(NULL);  // owned
@@ -337,12 +193,18 @@
     HBufC* lastName(NULL);  // owned
 	GetFieldsLC(aItem, &firstNameAsNbr, &lastNameAsNbr, &firstName, &lastName);
 
-	QStringList numericTokens;
-	QList<TChar> tables;
+	QStringList tokens;
+	QList<QChar> tables;
 	QT_TRYCATCH_LEAVING({
-		numericTokens = GetNumericTokens(firstNameAsNbr, lastNameAsNbr);
-		tables = DetermineTables(numericTokens);
-	});
+		TBool mandatoryFieldsPresent(EFalse);
+		QStringList tableSpecificFields =
+			GetTableSpecificFields(aItem, mandatoryFieldsPresent);
+		if (mandatoryFieldsPresent)
+			{
+			tokens = GetTokens(tableSpecificFields, firstNameAsNbr, lastNameAsNbr);
+			tables = DetermineTables(tokens);
+			}
+		});
 
 	HBufC* tableName(NULL);
 	while ((tableName = GetNextTableNameL(tables)) != NULL)
@@ -351,26 +213,14 @@
 		iInsertStmnt->SetTableName(tableName);
 		RSqlStatement stmnt;
 		CleanupClosePushL( stmnt ); 
-		RDebug::Print(_L("CPplPredictiveSearchTable::WriteToDbL SQL='%S'"),
-					  &iInsertStmnt->SqlStringL());
+		PRINT1(_L("CPplPredictiveSearchTableBase::WriteToDbL SQL='%S'"),
+			   &iInsertStmnt->SqlStringL());
 		stmnt.PrepareL(iDatabase, iInsertStmnt->SqlStringL());
 
-		const TDesC* paramNames[] = {
-			&KPredSearchNameAsNumberParam,
-			&KPredSearchNameAsNumber2Param,
-			&KPredSearchNameAsNumber3Param,
-			&KPredSearchNameAsNumber4Param};
-		for (TInt i = 0; i < numericTokens.count(); ++i)
-			{
-			quint64 hex(0);
-			QT_TRYCATCH_LEAVING(hex = ConvertToHex(numericTokens[i]));
-			if (hex == KConversionError)
-				{
-				User::Leave(KErrArgument);
-				}
-			User::LeaveIfError(stmnt.BindInt64(
-				User::LeaveIfError(stmnt.ParameterIndex(*paramNames[i])), hex));
-			}
+// TODO: while this works, it is inefficient, since the BIGINT values are
+// computed in every iteration of the while-loop, even though the data is
+// always the same.
+		FillKeyboardSpecificFieldsL(stmnt, tokens);
 
 		User::LeaveIfError(stmnt.BindInt(
 			User::LeaveIfError(stmnt.ParameterIndex(KPredSearchContactIdParam)),
@@ -389,7 +239,7 @@
 				*lastName));
 			}
 
-		RDebug::Print(_L("CPplPredictiveSearchTable::WriteToDbL execute SQL statement"));
+//		PRINT(_L("CPplPredictiveSearchTableBase::WriteToDbL execute SQL statement"));
 		// Execute the SQL statement
 		User::LeaveIfError(stmnt.Exec());
 		CleanupStack::PopAndDestroy(&stmnt);
@@ -400,17 +250,17 @@
 	CleanupStack::PopAndDestroy(firstNameAsNbr);
 	CleanupStack::PopAndDestroy(firstName);
 
-	RDebug::Print(_L("CPplPredictiveSearchTable::WriteToDbL ends"));
+	PRINT(_L("CPplPredictiveSearchTableBase::WriteToDbL ends"));
 	}
 
 
-void CPplPredictiveSearchTable::GetFieldsLC(const CContactItem& aItem,
-											HBufC** aFirstNameAsNbr,
-											HBufC** aLastNameAsNbr,
-											HBufC** aFirstName,
-											HBufC** aLastName) const
+void CPplPredictiveSearchTableBase::GetFieldsLC(const CContactItem& aItem,
+										  	    HBufC** aFirstNameAsNbr,
+											    HBufC** aLastNameAsNbr,
+											    HBufC** aFirstName,
+  											    HBufC** aLastName) const
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::GetFieldsLC"));
+	PRINT(_L("CPplPredictiveSearchTableBase::GetFieldsLC"));
 	__ASSERT_ALWAYS(aFirstNameAsNbr != NULL && *aFirstNameAsNbr == NULL,
 				    User::Leave(KErrArgument));
 	__ASSERT_ALWAYS(aLastNameAsNbr != NULL && *aLastNameAsNbr == NULL,
@@ -429,7 +279,7 @@
             {
             TPtrC firstName = textfield->Text();
 			*aFirstName = firstName.Left(KCharactersFromName).AllocLC();
-			*aFirstNameAsNbr = iKeyMap->GetNumericKeyStringL(firstName, EFalse);
+			*aFirstNameAsNbr = iKeyMap->GetMappedStringL(firstName);
             }
         }
 	// If aFirstName was not pushed to cleanupstack above, do it now
@@ -447,17 +297,17 @@
             {
             TPtrC lastName = textfield->Text();
 			*aLastName = lastName.Left(KCharactersFromName).AllocLC();
-			*aLastNameAsNbr = iKeyMap->GetNumericKeyStringL(lastName, EFalse);
+			*aLastNameAsNbr = iKeyMap->GetMappedStringL(lastName);
             }
         }
 	// If aLastName was not pushed to cleanupstack above, do it now
 	if (*aLastName == NULL)
 		{
-		CleanupStack::PushL(*aLastName);
+		CleanupStack::PushL(*aLastName);	
 		}
 	CleanupStack::PushL(*aLastNameAsNbr);
 
-	RDebug::Print(_L("CPplPredictiveSearchTable::GetFieldsLC id=%d FNnbr='%S' LNnbr='%S' FN='%S' LN='%S'"),
+	PRINT5(_L("CPplPredictiveSearchTableBase::GetFieldsLC id=%d FNnbr='%S' LNnbr='%S' FN='%S' LN='%S'"),
 		aItem.Id(),
 	    *aFirstNameAsNbr ? *aFirstNameAsNbr : &KNullDesC,
 	    *aLastNameAsNbr ? *aLastNameAsNbr : &KNullDesC,
@@ -466,52 +316,42 @@
 	}
 
 
-QList<TChar> CPplPredictiveSearchTable::DetermineTables(QStringList aTokens) const
-	{
-	QList<TChar> tables;
-	for (TInt i = aTokens.count() - 1; i >= 0; --i)
-		{
-		__ASSERT_ALWAYS(IsValidChar(aTokens[i][0]),
-						User::Panic(_L("DetermineTables"), KErrArgument));
-		TChar ch(aTokens[i][0].unicode());
-		if (!tables.contains(ch))
-			{
-			tables.append(ch);
-			}
-		}
-	return tables;
-	}
-
-
 // 1. get first token of LN
 // 2. get first token of FN
 // 3. get second token of LN
 // 4. get second token of FN
 // :
 // :
-// If LN or FN runs out of tokens before KMaxTokens have been found,
+// If LN or FN runs out of tokens before maximum amount of tokens have been found,
 // keep getting tokens from the other field.
-QStringList CPplPredictiveSearchTable::GetNumericTokens(HBufC* aFirstName,
-													    HBufC* aLastName) const
+QStringList
+CPplPredictiveSearchTableBase::GetTokens(QStringList aNonTokenizedFields,
+										 HBufC* aFirstName,
+										 HBufC* aLastName) const
 	{
-	RDebug::Print(_L("CPplPredictiveSearchTable::GetNumericTokens FN='%S',LN='%S'"),
-		aFirstName ? aFirstName : &KNullDesC,
-		aLastName ? aLastName : &KNullDesC);
+	PRINT2(_L("CPplPredictiveSearchTableBase::GetTokens FN='%S',LN='%S'"),
+		   aFirstName ? aFirstName : &KNullDesC,
+		   aLastName ? aLastName : &KNullDesC);
+
+	QStringList tokens;
+	while (tokens.count() < iMaxTokens && !aNonTokenizedFields.isEmpty())
+		{
+		GetNextToken(aNonTokenizedFields, tokens);
+		}
 
 	QStringList firstNameTokens;
 	QStringList lastNameTokens;
 	AddTokens(aFirstName, firstNameTokens);
 	AddTokens(aLastName, lastNameTokens);
-
-	QStringList tokens;
-	while (tokens.count() < KMaxTokens &&
+	
+	while (tokens.count() < iMaxTokens &&
 		   (!firstNameTokens.isEmpty() || !lastNameTokens.isEmpty()))
 		{
 		GetNextToken(lastNameTokens, tokens);
 		GetNextToken(firstNameTokens, tokens);
 		}
-	RDebug::Print(_L("CPplPredictiveSearchTable::GetNumericTokens found %d tokens"),
-                  tokens.count());
+	PRINT1(_L("CPplPredictiveSearchTableBase::GetTokens found %d tokens"),
+           tokens.count());
 	return tokens;
 	}
 
@@ -519,7 +359,7 @@
 // Ignore tokens beginning with invalid (unknown) character.
 // Keep duplicate tokens to support e.g. search "202" when both FN and LN are "23".
 void
-CPplPredictiveSearchTable::AddTokens(HBufC* aString, QStringList& aTokens) const
+CPplPredictiveSearchTableBase::AddTokens(HBufC* aString, QStringList& aTokens) const
 	{
 	if (aString)
 		{
@@ -542,20 +382,12 @@
 	}
 
 
-TBool CPplPredictiveSearchTable::IsValidChar(QChar aChar) const
+void CPplPredictiveSearchTableBase::GetNextToken(QStringList& aSource,
+												 QStringList& aDestination) const
 	{
-	return (aChar >= '0' && aChar <= '9') ||
-			aChar == MAPPED_CHAR_FOR_STAR ||
-			aChar == MAPPED_CHAR_FOR_HASH;
-	}
-
-
-void CPplPredictiveSearchTable::GetNextToken(QStringList& aSource,
-											 QStringList& aDestination) const
-	{
-	if (!aSource.isEmpty() && aDestination.count() < KMaxTokens)
+	if (!aSource.isEmpty() && aDestination.count() < iMaxTokens)
 		{
-        QString padded = aSource[0].left(KMaxDigits);
+        QString padded = aSource[0].left(iMaxTokenLength);
 		aDestination.append(padded);
 		aSource.removeFirst();
 		}
@@ -563,10 +395,10 @@
 
 
 void
-CPplPredictiveSearchTable::DeleteFromAllTablesL(TContactItemId aContactId,
-											    TBool& aLowDiskErrorOccurred) const
+CPplPredictiveSearchTableBase::DeleteFromAllTablesL(TContactItemId aContactId,
+												    TBool& aLowDiskErrorOccurred) const
 	{
-	QList<TChar> tables;
+	QList<QChar> tables;
 	QT_TRYCATCH_LEAVING(tables = FillAllTables());
 
 	HBufC* tableName(NULL);
@@ -577,8 +409,8 @@
 		RSqlStatement stmnt;
 		CleanupClosePushL(stmnt);
 
-		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL SQL='%S'"),
-					  &iDeleteStmnt->SqlStringL());
+		PRINT1(_L("CPplPredictiveSearchTableBase::DeleteFromAllTablesL SQL='%S'"),
+			   &iDeleteStmnt->SqlStringL());
 		stmnt.PrepareL(iDatabase, iDeleteStmnt->SqlStringL());
 	
 		// Contact id was not added with iDeleteStmnt->SetParamL() so it can not be
@@ -586,129 +418,26 @@
 		// It is the first and only parameter in query
 		const TInt KContactIdParamIndex(KFirstIndex);
 		User::LeaveIfError(stmnt.BindInt(KContactIdParamIndex, aContactId));
-		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL execute statement"));
+
 		// Returns the amount of affected rows. As contact is not present each
 		// table, some operations return 0, it is not an error.
 		TInt status = stmnt.Exec();
-		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL rows deleted=%d"), status);
+#if defined(WRITE_PRED_SEARCH_LOGS)
+		if (status != 0)
+			{
+			PRINT1(_L("  rows deleted=%d"), status);
+			}
+#endif
 		CleanupStack::PopAndDestroy(&stmnt);
 
 		if (status == KErrDiskFull)
 			{
-			RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL disk full"));
+			PRINT(_L("CPplPredictiveSearchTableBase::DeleteFromAllTablesL disk full"));
 			aLowDiskErrorOccurred = ETrue;
 			}
 		else
 			{
-			RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL status=%d"), status);
 			User::LeaveIfError(status);
 			}
 		}
 	}
-
-
-QList<TChar> CPplPredictiveSearchTable::FillAllTables() const
-	{
-	QList<TChar> tables;
-
-	const TInt KLargestDigitKey = '9';
-	for (TInt i = '0'; i <= KLargestDigitKey; ++i)
-		{
-		TChar ch = i;
-		tables << ch;
-		}
-	tables << KMappedCharForStar;
-	tables << KMappedCharForHash;
-
-	return tables;
-	}
-
-
-HBufC* CPplPredictiveSearchTable::GetNextTableNameL(QList<TChar>& aTables) const
-	{
-	HBufC* tableName(NULL);
-	if (aTables.count() > 0)
-		{
-        // Enough space for the longest table name
-        tableName = HBufC::NewL(KSqlContactPredSearchTable11().Length());
-        TPtr ptr = tableName->Des();
-		ptr.Append(TableNameL(aTables[0]));
-
-		aTables.removeFirst();
-		RDebug::Print(_L("CPplPredictiveSearchTable::GetNextTableNameL '%S'"), tableName);
-        }
-	return tableName;
-	}
-
-// when qwerty will be supported, keymap prob maps original chars to
-// 0..9, a..z + few capital letters
-const TDesC& CPplPredictiveSearchTable::TableNameL(TChar aCh) const
-	{
-	switch (aCh)
-		{
-		case '0': return KSqlContactPredSearchTable0;
-		case '1': return KSqlContactPredSearchTable1;
-		case '2': return KSqlContactPredSearchTable2;
-		case '3': return KSqlContactPredSearchTable3;
-		case '4': return KSqlContactPredSearchTable4;
-		case '5': return KSqlContactPredSearchTable5;
-		case '6': return KSqlContactPredSearchTable6;
-		case '7': return KSqlContactPredSearchTable7;
-		case '8': return KSqlContactPredSearchTable8;
-		case '9': return KSqlContactPredSearchTable9;
-		case MAPPED_CHAR_FOR_STAR: return KSqlContactPredSearchTable10;
-		case MAPPED_CHAR_FOR_HASH: return KSqlContactPredSearchTable11;
-		default:
-			TUint ch = aCh;
-			RDebug::Print(_L("CPplPredictiveSearchTable::TableName unknown char '%c'"), ch);
-			User::Leave(KErrArgument);
-			return KNullDesC;
-		}
-	}
-
-
-// E.g. aToken = "01230" -> append KPadChar until has KMaxDigits characters
-// -> "01230ffffffffff" -> convert to hexadecimal number -> 0x01230ffffffffff.
-// If this function would leave, causes panic, perhaps because of QString parameter?
-quint64 CPplPredictiveSearchTable::ConvertToHex(QString aToken) const
-	{
-	if (aToken.length() > KMaxDigits)
-		{
-		return KConversionError;
-		}
-    QString padded = aToken.leftJustified(KMaxDigits, KPadChar);
-
-    TBuf<KMaxDigits> log(padded.utf16());
-    RDebug::Print(_L("CPplPredictiveSearchTable::ConvertToHex padded '%S'"), &log);
-
-	// Replace unmapped char and the following characters with KPadChar.
-    QString replaced = padded;
-    bool done(false);
-    for (TInt i = 0; i < KMaxDigits && !done; ++i)
-        {
-        if (!IsValidChar(padded[i]))
-            {
-            // replace() does not work, it puts just one 'a' at end
-            // replaced = padded.replace(i, KMaxDigits - i, KPadChar);
-
-            padded.remove(i, KMaxDigits - i);
-            replaced = padded.leftJustified(KMaxDigits, KPadChar);
-            done = true;
-
-			TBuf<KMaxDigits> log2(replaced.utf16());
-			RDebug::Print(_L("After replacing '%S'"), &log2);
-            }
-        }
-
-    const TInt KHexadecimalBase = 16;
-    bool ok(true);
-    quint64 hex = replaced.toULongLong(&ok, KHexadecimalBase);
-    if (!ok)
-        {
-		RDebug::Print(_L("conv to hex failed"));
-		return KConversionError;
-        }
-    
-    RDebug::Print(_L("CPplPredictiveSearchTable::ConvertToHex result 0x%lx"), hex);
-    return hex;
-	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cpredictivesearchsettingstable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,203 @@
+/*
+* 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: 
+*
+*/
+
+#include "cpredictivesearchsettingstable.h"
+#include "dbsqlconstants.h"
+
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
+
+
+_LIT(KSqlContactPredSearchSettingsTable, "pred_search_settings");
+
+_LIT(KCreatePredSearchSettingsTable, "CREATE TABLE pred_search_settings (language INTEGER);");
+
+_LIT(KPredSearchSettingsLanguage, "language");
+
+// How many characters the decimal representation of enum QLocale::Language
+// requires.
+const TInt KSizeOfLanguageValue = 8;
+
+//_LIT(KInsertFormat, "INSERT INTO pred_search_settings (language) VALUES (%d);");
+// e.g. "INSERT INTO pred_search_settings (language) VALUES (8);"
+_LIT(KInsertFormat, "INSERT INTO %S (%S) VALUES (%d);");
+
+// e.g. "UPDATE pred_search_settings SET language = 9;"
+_LIT(KUpdateFormat, "UPDATE %S SET %S = %d;");
+
+// e.g. "SELECT language FROM pred_search_settings;"
+_LIT(KSelectFormat, "SELECT %S FROM %S;");
+
+
+
+CPredictiveSearchSettingsTable*
+CPredictiveSearchSettingsTable::NewL(RSqlDatabase& aDatabase)
+	{
+	PRINT(_L("CPredictiveSearchSettingsTable::NewL"));
+	CPredictiveSearchSettingsTable* self =
+		CPredictiveSearchSettingsTable::NewLC(aDatabase);
+	CleanupStack::Pop(self);
+	PRINT(_L("CPredictiveSearchSettingsTable::NewL ends"));
+	return self;
+	}
+
+CPredictiveSearchSettingsTable*
+CPredictiveSearchSettingsTable::NewLC(RSqlDatabase& aDatabase)
+	{
+	PRINT(_L("CPredictiveSearchSettingsTable::NewLC"));
+	CPredictiveSearchSettingsTable* self =
+		new (ELeave) CPredictiveSearchSettingsTable(aDatabase);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PRINT(_L("CPredictiveSearchSettingsTable::NewLC ends"));
+	return self;
+	}
+
+CPredictiveSearchSettingsTable::~CPredictiveSearchSettingsTable()
+	{
+	PRINT(_L("CPredictiveSearchSettingsTable dtor"));
+	PRINT(_L("CPredictiveSearchSettingsTable dtor ends"));
+	}
+
+void CPredictiveSearchSettingsTable::CreateInDbL(CContactItem& /*aItem*/)
+	{
+	}
+
+void CPredictiveSearchSettingsTable::UpdateL(const CContactItem& /*aItem*/)
+	{
+	}
+
+void CPredictiveSearchSettingsTable::DeleteL(const CContactItem& /*aItem*/,
+												TBool& /*aLowDiskErrorOccurred*/)
+	{
+	}
+
+// Create table to an empty database, so there is no need to re-generate QWERTY
+// tables.
+void CPredictiveSearchSettingsTable::CreateTableL()
+	{
+	PRINT(_L("CPredictiveSearchSettingsTable::CreateTableL"));
+
+	User::LeaveIfError(iDatabase.Exec(KCreatePredSearchSettingsTable));
+	enum QLocale::Language language = GetCurrentLanguageL();
+	HBufC* insert = HBufC::NewLC(KInsertFormat().Length() +
+								 KSqlContactPredSearchSettingsTable().Length() +
+							 	 KPredSearchSettingsLanguage().Length() +
+							 	 KSizeOfLanguageValue);
+	insert->Des().AppendFormat(KInsertFormat,
+							   &KSqlContactPredSearchSettingsTable,
+							   &KPredSearchSettingsLanguage,
+							   language);
+	User::LeaveIfError(iDatabase.Exec(*insert));
+	CleanupStack::PopAndDestroy(insert);
+
+	PRINT(_L("CPredictiveSearchSettingsTable::CreateTableL ends"));
+	}
+
+QList<QChar> CPredictiveSearchSettingsTable::FillAllTables() const
+	{
+	QList<QChar> tables;
+	tables.append('1'); // Add one character (does not matter what the character is)
+	return tables;
+	}
+
+HBufC* CPredictiveSearchSettingsTable::TableNameL(const QChar /*aCh*/) const
+	{
+	return KSqlContactPredSearchSettingsTable().AllocL();
+	}
+
+TBool CPredictiveSearchSettingsTable::IsLanguageValidL() const
+	{
+	PRINT(_L("CPredictiveSearchSettingsTable::IsLanguageValidL"));
+	return ReadStoredLanguageL() == GetCurrentLanguageL();
+	}
+
+void CPredictiveSearchSettingsTable::StoreCurrentLanguageL() const
+	{
+	PRINT(_L("CPredictiveSearchSettingsTable::StoreCurrentLanguageL"));
+
+	enum QLocale::Language language = GetCurrentLanguageL();
+	HBufC* update = HBufC::NewLC(KUpdateFormat().Length() +
+								 KSqlContactPredSearchSettingsTable().Length() +
+							 	 KPredSearchSettingsLanguage().Length() +
+							 	 KSizeOfLanguageValue);
+	update->Des().AppendFormat(KUpdateFormat,
+							   &KSqlContactPredSearchSettingsTable,
+							   &KPredSearchSettingsLanguage,
+							   language);
+	User::LeaveIfError(iDatabase.Exec(*update));
+	CleanupStack::PopAndDestroy(update);
+
+	PRINT(_L("CPredictiveSearchSettingsTable::StoreCurrentLanguageL ends"));
+	}
+
+void CPredictiveSearchSettingsTable::ConstructL()
+	{
+	}
+
+enum QLocale::Language CPredictiveSearchSettingsTable::GetCurrentLanguageL() const
+	{
+    enum QLocale::Language language(QLocale::C);
+	QT_TRYCATCH_LEAVING(language = QLocale::system().language());
+	PRINT1(_L("CPredictiveSearchSettingsTable::GetCurrentLanguageL ret=%d"), language);
+	return language;
+	}
+
+enum QLocale::Language CPredictiveSearchSettingsTable::ReadStoredLanguageL() const
+	{
+	TInt bufSize = KSelectFormat().Length() +
+				   KPredSearchSettingsLanguage().Length() +
+				   KSqlContactPredSearchSettingsTable().Length();
+	HBufC* select = HBufC::NewLC(bufSize);
+	select->Des().AppendFormat(KSelectFormat,
+		&KPredSearchSettingsLanguage,
+		&KSqlContactPredSearchSettingsTable);
+
+	RSqlStatement stmnt;
+	CleanupClosePushL(stmnt);
+	PRINT1(_L("CPredictiveSearchSettingsTable::ReadStoredLanguageL SQL:%S"), select);
+    stmnt.PrepareL(iDatabase, *select);
+
+	const TInt KLanguageIndex = 0;
+	TInt err = stmnt.Next();
+	enum QLocale::Language language(QLocale::C);
+	if (err == KSqlAtRow)
+        {
+		language = static_cast<QLocale::Language>(stmnt.ColumnInt(KLanguageIndex));
+		PRINT1(_L("read language=%d from DB"), language);
+        }
+	CleanupStack::PopAndDestroy(&stmnt);
+	CleanupStack::PopAndDestroy(select);
+
+    if (err != KSqlAtRow)
+        {
+		PRINT1(_L("CPredictiveSearchSettingsTable::ReadStoredLanguageL err=%d"), err);
+        User::Leave(err);
+        }
+	PRINT1(_L("CPredictiveSearchSettingsTable::ReadStoredLanguageL ret=%d"), language);
+	return language;
+	}
+
+/**
+Constructor
+*/
+CPredictiveSearchSettingsTable::CPredictiveSearchSettingsTable(
+	RSqlDatabase& aDatabase) :
+	CPplPredictiveSearchTableBase(aDatabase, 0, 0)
+	{
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cpredictivesearchsynchronizer.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,337 @@
+/*
+* 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: 
+*
+*/
+
+#include "cpredictivesearchsynchronizer.h"
+#include "c12keypredictivesearchtable.h"
+#include "cqwertypredictivesearchtable.h"
+#include "cpredictivesearchsettingstable.h"
+#include "dbsqlconstants.h"
+
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
+
+_LIT(KFirstQwertyTableName, "qm0");
+
+
+CPredictiveSearchSynchronizer*
+CPredictiveSearchSynchronizer::NewL(RSqlDatabase& aDatabase,
+									C12keyPredictiveSearchTable& a12keyTable,
+									CQwertyPredictiveSearchTable& aQwertyTable,
+									CPredictiveSearchSettingsTable& aSettingsTable)
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer::NewL"));
+	CPredictiveSearchSynchronizer* self =
+		CPredictiveSearchSynchronizer::NewLC(aDatabase, a12keyTable,
+											 aQwertyTable, aSettingsTable);
+	CleanupStack::Pop(self);
+	PRINT(_L("CPredictiveSearchSynchronizer::NewL ends"));
+	return self;
+	}
+
+CPredictiveSearchSynchronizer*
+CPredictiveSearchSynchronizer::NewLC(RSqlDatabase& aDatabase,
+									 C12keyPredictiveSearchTable& a12keyTable,
+									 CQwertyPredictiveSearchTable& aQwertyTable,
+									 CPredictiveSearchSettingsTable& aSettingsTable)
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer::NewLC"));
+	CPredictiveSearchSynchronizer* self =
+		new (ELeave) CPredictiveSearchSynchronizer(aDatabase, a12keyTable,
+												   aQwertyTable, aSettingsTable);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PRINT(_L("CPredictiveSearchSynchronizer::NewLC ends"));
+	return self;
+	}
+
+CPredictiveSearchSynchronizer::~CPredictiveSearchSynchronizer()
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer dtor"));
+	PRINT(_L("CPredictiveSearchSynchronizer dtor ends"));
+	}
+
+void CPredictiveSearchSynchronizer::ConstructL()
+	{
+	}
+
+/**
+Constructor
+*/
+CPredictiveSearchSynchronizer::CPredictiveSearchSynchronizer(
+	RSqlDatabase& aDatabase,
+	C12keyPredictiveSearchTable& a12keyTable,
+	CQwertyPredictiveSearchTable& aQwertyTable,
+	CPredictiveSearchSettingsTable& aSettingsTable) :
+	iDatabase(aDatabase),
+	i12keyTable(a12keyTable),
+	iQwertyTable(aQwertyTable),
+	iSettingsTable(aSettingsTable)
+	{
+	}
+
+// There are 3 cases:
+// - none of the pred.search tables exist
+// - just 12-key pred.search tables exist
+// - all pred.search tables exist (12-key, QWERTY, settings)
+// There is no case where QWERTY tables exist but settings table does not,
+// since such a version was not released.
+void CPredictiveSearchSynchronizer::SynchronizeTablesL()
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer::SynchronizeTablesL"));
+
+	if (CheckIfPredSearchTableExistsL(KSqlContactPredSearchTable0))
+		{
+		if (CheckIfPredSearchTableExistsL(KFirstQwertyTableName))
+			{
+			// All tables exist, check if language has been changed
+			if (!iSettingsTable.IsLanguageValidL())
+				{
+				PRINT(_L("language has changed, re-create QWERTY tables"));
+				DeletePredSearchTableL(iQwertyTable);
+				CreatePredSearchTablesL(EFalse);
+				iSettingsTable.StoreCurrentLanguageL();
+				}
+			}
+		else
+			{
+			PRINT(_L("QWERTY and settings tables missing, re-create all tables"));
+			DeletePredSearchTablesL();
+			CreatePredSearchTablesL();
+			}
+		}
+	else
+		{
+		// All predictive search tables missing, create all
+		CreatePredSearchTablesL();
+		}
+
+	PRINT(_L("CPredictiveSearchSynchronizer::SynchronizeTablesL ends"));
+	}
+
+void CPredictiveSearchSynchronizer::CreatePredSearchTablesL(TBool aAllTables)
+	{
+	PRINT1(_L("CPredictiveSearchSynchronizer::CreatePredSearchTablesL all=%d"), aAllTables);
+
+	if (aAllTables)
+		{
+		i12keyTable.CreateTableL();
+		iSettingsTable.CreateTableL();
+		iSettingsTable.StoreCurrentLanguageL();
+		}
+	iQwertyTable.CreateTableL();
+
+	_LIT(KSelectAllContactsFormat, "SELECT %S,%S,%S FROM %S;");
+	TInt bufSize = KSelectAllContactsFormat().Length() +
+				   KContactId().Length() +
+				   KContactFirstName().Length() +
+				   KContactLastName().Length() +
+				   KSqlContactTableName().Length();
+	HBufC* sqlStatement = HBufC::NewLC(bufSize);
+	sqlStatement->Des().AppendFormat(KSelectAllContactsFormat,
+		&KContactId,
+		&KContactFirstName,
+		&KContactLastName,
+		&KSqlContactTableName);
+
+	RSqlStatement stmnt;
+	CleanupClosePushL(stmnt);
+	PRINT1(_L("CreatePredSearchTablesL prepare SQL statement:%S"), sqlStatement);
+    stmnt.PrepareL(iDatabase, *sqlStatement);
+
+	const TInt KContactIdIndex = 0;
+	const TInt KFirstNameIndex = 1;
+	const TInt KLastNameIndex = 2;
+	TInt err(KErrNone);
+    while ((err = stmnt.Next()) == KSqlAtRow)
+        {
+		PRINT(_L("CreatePredSearchTablesL create CContactItem"));
+
+		TInt id = KUidContactCardValue;
+		TUid uid;
+		uid.iUid = id;
+		CContactItem* contact = CContactItem::NewLC(uid);
+		contact->SetId(stmnt.ColumnInt(KContactIdIndex));
+
+		// If first name exists, write it to contact item
+		TPtrC firstName;
+		if (stmnt.ColumnText(KFirstNameIndex, firstName) == KErrNone)
+			{
+			CContactItemField* field =
+				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
+			CContactTextField* textfield = field->TextStorage();
+			textfield->SetTextL(firstName);
+			contact->AddFieldL(*field); // Takes ownership
+			CleanupStack::Pop(field);
+			}
+
+		TPtrC lastName;
+		if (stmnt.ColumnText(KLastNameIndex, lastName) == KErrNone)
+			{
+			CContactItemField* field =
+				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
+			CContactTextField* textfield = field->TextStorage();
+			textfield->SetTextL(lastName);
+			contact->AddFieldL(*field); // Takes ownership
+			CleanupStack::Pop(field);
+			}
+		PRINT(_L("CreatePredSearchTablesL create entry to tables"));
+		if (aAllTables)
+			{
+			i12keyTable.CreateInDbL(*contact);
+			}
+		if (ReadMailAddressesL(*contact))
+			{
+			iQwertyTable.CreateInDbL(*contact);
+			}
+
+		CleanupStack::PopAndDestroy(contact);
+        }
+
+    // Leave if we didn't complete going through the results properly
+    if (err != KSqlAtEnd)
+        {
+		PRINT1(_L("CreatePredSearchTablesL SQL err=%d"), err);
+        User::Leave(err);
+        }
+    CleanupStack::PopAndDestroy(&stmnt);
+	CleanupStack::PopAndDestroy(sqlStatement);
+
+	PRINT(_L("CPredictiveSearchSynchronizer::CreatePredSearchTablesL ends"));
+	}
+
+void CPredictiveSearchSynchronizer::DeletePredSearchTablesL()
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTablesL"));
+
+	DeletePredSearchTableL(i12keyTable);
+	DeletePredSearchTableL(iQwertyTable);
+	DeletePredSearchTableL(iSettingsTable);
+	
+	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTablesL ends"));
+	}
+
+TBool CPredictiveSearchSynchronizer::CheckIfPredSearchTableExistsL(
+	const TDesC& aTableName) const
+	{
+	PRINT1(_L("CPredictiveSearchSynchronizer::CheckIfPredSearchTableExistsL table='%S'"),
+		   &aTableName);
+
+	_LIT(KSelectFirstTableFormat,
+		 "SELECT name FROM sqlite_master WHERE type='table' AND name='%S';");
+
+	TInt bufSize = KSelectFirstTableFormat().Length() +
+				   aTableName.Length();
+	HBufC* select = HBufC::NewLC(bufSize);
+	select->Des().AppendFormat(KSelectFirstTableFormat, &aTableName);
+	RSqlStatement stmnt;
+	CleanupClosePushL(stmnt);
+    stmnt.PrepareL(iDatabase, *select);
+
+	TBool tableExists = (stmnt.Next() == KSqlAtRow);
+
+	CleanupStack::PopAndDestroy(&stmnt);
+	CleanupStack::PopAndDestroy(select);
+
+	PRINT1(_L("CPredictiveSearchSynchronizer::CheckIfPredSearchTablesExistL return %d"),
+		   tableExists);
+	return tableExists;
+	}
+
+void CPredictiveSearchSynchronizer::DeletePredSearchTableL(CPplPredictiveSearchTableBase& aTable)
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTableL"));
+
+	// IF EXISTS suppresses error that would occur if table does not exist
+	_LIT(KDropTable, "DROP TABLE IF EXISTS %S;");
+
+	QList<QChar> tables;
+	QT_TRYCATCH_LEAVING(tables = aTable.FillAllTables());
+	HBufC* tableName(NULL);
+	while ((tableName = aTable.GetNextTableNameL(tables)) != NULL)
+		{
+		CleanupStack::PushL(tableName);
+		HBufC* dropTable = HBufC::NewLC(KDropTable().Length() + tableName->Length());
+        dropTable->Des().Format(KDropTable, tableName);
+
+		User::LeaveIfError(iDatabase.Exec(*dropTable));
+
+        CleanupStack::PopAndDestroy(dropTable);
+		CleanupStack::PopAndDestroy(tableName);
+		}
+	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTableL ends"));
+	}
+
+TBool CPredictiveSearchSynchronizer::ReadMailAddressesL(CContactItem& aContact)
+	{
+	PRINT(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL"));
+
+	// SELECT value FROM comm_addr
+	//	 WHERE contact_id = [contact id value] AND type = [type value];
+    _LIT(KSelectMailAddrFormat, "SELECT %S FROM %S WHERE %S = %d AND %S = %d;");
+	const TInt KContactIdLength = 10;
+	const TInt KCommAddrTypeLength = 2; // CPplCommAddrTable::EEmailAddress is enum
+	TInt bufSize = KSelectMailAddrFormat().Length() +
+				   KCommAddrValue().Length() +
+				   KSqlContactCommAddrTableName().Length() +
+				   KCommAddrContactId().Length() +
+				   KContactIdLength +
+				   KCommAddrType().Length() +
+				   KCommAddrTypeLength;
+	HBufC* sqlStatement = HBufC::NewLC(bufSize);
+	sqlStatement->Des().AppendFormat(KSelectMailAddrFormat,
+		&KCommAddrValue,
+		&KSqlContactCommAddrTableName,
+		&KCommAddrContactId,
+		aContact.Id(),
+		&KCommAddrType,
+		CPplCommAddrTable::EEmailAddress);
+
+	RSqlStatement stmnt;
+	CleanupClosePushL(stmnt);
+	PRINT1(_L("prepare SQL statement:%S"), sqlStatement);
+    stmnt.PrepareL(iDatabase, *sqlStatement);
+
+	const TInt KValueIndex = 0;
+	TBool foundMailAddress(EFalse);
+	TInt err(KErrNone);
+    while ((err = stmnt.Next()) == KSqlAtRow)
+        {
+		TPtrC value;
+		if (stmnt.ColumnText(KValueIndex, value) == KErrNone)
+			{
+			PRINT2(_L("  id=%d, found mail address=%S"), aContact.Id(), &value);
+			CContactItemField* field =
+				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldEMail);
+			CContactTextField* textfield = field->TextStorage();
+			textfield->SetTextL(value);
+			aContact.AddFieldL(*field); // Takes ownership
+			CleanupStack::Pop(field);
+			foundMailAddress = ETrue;
+			}
+        }
+
+    if (err != KSqlAtEnd)
+        {
+		PRINT1(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL SQL err=%d"), err);
+        User::Leave(err);
+        }
+    CleanupStack::PopAndDestroy(&stmnt);
+	CleanupStack::PopAndDestroy(sqlStatement);
+	PRINT1(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL return %d"), foundMailAddress);
+	return foundMailAddress;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cqwertykeymap.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,324 @@
+/*
+* 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 "cqwertykeymap.h"
+
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
+
+#include <QChar>
+#include <QString>
+
+
+// Largest amount of keypresses that can be stored in QWERTY keyboard's
+// predictive search tables.
+// SQL BIGINT is a 64-bit signed integer and one bit is reserved for sign.
+// QWERTY's keys are identified by TKeyId that needs 6 bits.
+// 63 / 6 = 10
+const TInt KMaxKeysStoredInDb = 10;
+
+// How many bits are needed to represent TKeyId
+const TInt KBitsInKeyId = 6;
+
+
+const QChar KEY_Q_NAME = 'q';
+const QChar KEY_W_NAME = 'w';
+const QChar KEY_E_NAME = 'e';
+const QChar KEY_R_NAME = 'r';
+const QChar KEY_T_NAME = 't';
+const QChar KEY_Y_NAME = 'y';
+const QChar KEY_U_NAME = 'u';
+const QChar KEY_I_NAME = 'i';
+const QChar KEY_O_NAME = 'o';
+const QChar KEY_P_NAME = 'p';
+
+const QChar KEY_A_NAME = 'a';
+const QChar KEY_S_NAME = 's';
+const QChar KEY_D_NAME = 'd';
+const QChar KEY_F_NAME = 'f';
+const QChar KEY_G_NAME = 'g';
+const QChar KEY_H_NAME = 'h';
+const QChar KEY_J_NAME = 'j';
+const QChar KEY_K_NAME = 'k';
+const QChar KEY_L_NAME = 'l';
+
+const QChar KEY_Z_NAME = 'z';
+const QChar KEY_X_NAME = 'x';
+const QChar KEY_C_NAME = 'c';
+const QChar KEY_V_NAME = 'v';
+const QChar KEY_B_NAME = 'b';
+const QChar KEY_N_NAME = 'n';
+const QChar KEY_M_NAME = 'm';
+
+const QChar KEY_COLON_NAME = ',';
+const QChar KEY_DOT_NAME   = '.';
+const QChar KEY_DASH_NAME  = '-';
+const QChar KEY_AT_NAME	   = '@';
+const QChar KEY_QUOTE_NAME = '\'';
+const QChar KEY_QUESTION_MARK_NAME = '?';
+
+const QChar KEY_32_NAME = '1';
+const QChar KEY_33_NAME = '2';
+const QChar KEY_34_NAME = '3';
+const QChar KEY_35_NAME = '4';
+const QChar KEY_36_NAME = '5';
+const QChar KEY_37_NAME = '6';
+const QChar KEY_38_NAME = '7';
+const QChar KEY_39_NAME = '8';
+const QChar KEY_40_NAME = '9';
+const QChar KEY_41_NAME = '0';
+const QChar KEY_42_NAME = '+';
+const QChar KEY_43_NAME = '#';
+
+// Unmapped (unknown) characters are replaced with this
+const QChar PAD_CHAR = '!';
+
+// Must be the first key (EKeyQ) that has internal value 0
+const QChar KLowerLimitPadding = KEY_Q_NAME;
+const QChar KUpperLimitPadding = PAD_CHAR;
+
+
+// ============================== MEMBER FUNCTIONS ============================
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::NewL
+// ----------------------------------------------------------------------------
+CQwertyKeyMap* CQwertyKeyMap::NewL()
+	{
+    PRINT(_L("Enter CQwertyKeyMap::NewL"));
+    
+    CQwertyKeyMap* self = new (ELeave) CQwertyKeyMap();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+
+    PRINT(_L("End CQwertyKeyMap::NewL"));
+    return self;
+	}
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::~CQwertyKeyMap
+// ----------------------------------------------------------------------------
+CQwertyKeyMap::~CQwertyKeyMap()
+    {
+    PRINT(_L("Enter CQwertyKeyMap::~CQwertyKeyMap"));    
+    PRINT(_L("End CQwertyKeyMap::~CQwertyKeyMap"));
+    }
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::ArrayIndexToMappedChar
+// Map index of iKeyMapping list, to the key that the mapping is for.
+// Space is already handled in CPcsKeyMap::GetMappedString(), no need to handle
+// it here.
+// ----------------------------------------------------------------------------
+const QChar CQwertyKeyMap::ArrayIndexToMappedChar(TInt aArrayIndex) const
+	{
+	__ASSERT_DEBUG(aArrayIndex < EAmountOfKeysInQwertyKeypad,
+				   User::Panic(_L("CQwertyKeyMap::ArrayIndexToMappedChar"),
+				   KErrOverflow));
+	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
+// ----------------------------------------------------------------------------
+TInt CQwertyKeyMap::ComputeValue(QString aString,
+								 TBool aUpperLimit,
+								 QString& aValue) const
+	{
+	QString padded;
+	if (aString.length() < KMaxKeysStoredInDb)
+		{
+		padded = aString.leftJustified(KMaxKeysStoredInDb,
+			aUpperLimit ? KUpperLimitPadding : KLowerLimitPadding);
+		}
+	else
+		{
+		padded = aString;
+		}	
+
+#if defined(WRITE_PRED_SEARCH_LOGS)
+	TBuf<KMaxKeysStoredInDb> log(padded.utf16());
+	PRINT1(_L("CQwertyKeyMap::ComputeValue string = '%S'"), &log);
+#endif
+
+	qint64 value(0);
+	for (TInt i = 0; i < KMaxKeysStoredInDb; ++i)
+		{
+        value <<= KBitsInKeyId;
+		value += MapKeyNameToValue(padded[i]);
+		PRINT1(_L("  value now 0x%lx"), value);
+		}
+
+	// In order to write queries using '>' and '<' instead of '>=' and '<=',
+	// expand the limit by one.
+	if (aUpperLimit)
+		{
+		++value;
+		}
+	else
+		{
+		--value;
+		}
+	PRINT2(_L("CQwertyKeyMap::ComputeValue result=0x%lx (%ld decimal)"), value, value);
+	aValue = QString::number(value); // Convert to decimal value
+	return KErrNone;
+	}
+
+#if defined(USE_ORBIT_KEYMAP)
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::MapKeyNameToValue
+// ----------------------------------------------------------------------------
+bool CQwertyKeyMap::IsValidChar(const QChar aChar) const
+	{
+	return iKeyValues.contains(aChar);
+	}
+#endif // #if defined(USE_ORBIT_KEYMAP)
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::MapKeyNameToValue
+// Does the reverse of ArrayIndexToMappedChar()
+// ----------------------------------------------------------------------------
+TInt CQwertyKeyMap::MapKeyNameToValue(const QChar aKeyName) const
+    {
+    return iKeyNames.key(aKeyName, KPadCharValue);
+    }
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::CQwertyKeyMap
+// Fill QList with empty strings
+// ----------------------------------------------------------------------------
+CQwertyKeyMap::CQwertyKeyMap() :
+	CPcsKeyMap(EAmountOfKeysInQwertyKeypad, PAD_CHAR, KMaxKeysStoredInDb)
+	{
+	}
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::ConstructL
+// ----------------------------------------------------------------------------
+void CQwertyKeyMap::ConstructL()
+	{
+	PRINT(_L("Enter CQwertyKeyMap::ConstructL"));
+
+	// CPcsKeyMap::ConstructLanguageMappings() uses ArrayIndexToMappedChar()
+	// that uses iKeyNames, so construct it first
+	TInt err(KErrNone);
+    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"));
+	}
+
+// ----------------------------------------------------------------------------
+// CQwertyKeyMap::ConstructKeyNameMap
+// ----------------------------------------------------------------------------
+void CQwertyKeyMap::ConstructKeyNameMap()
+	{
+	iKeyNames.insert(EKeyQ, KEY_Q_NAME);
+	iKeyNames.insert(EKeyW, KEY_W_NAME);
+	iKeyNames.insert(EKeyE, KEY_E_NAME);
+	iKeyNames.insert(EKeyR, KEY_R_NAME);
+	iKeyNames.insert(EKeyT, KEY_T_NAME);
+	iKeyNames.insert(EKeyY, KEY_Y_NAME);
+	iKeyNames.insert(EKeyU, KEY_U_NAME);
+	iKeyNames.insert(EKeyI, KEY_I_NAME);
+	iKeyNames.insert(EKeyO, KEY_O_NAME);
+	iKeyNames.insert(EKeyP, KEY_P_NAME);
+	iKeyNames.insert(EKeyA, KEY_A_NAME);
+	iKeyNames.insert(EKeyS, KEY_S_NAME);
+	iKeyNames.insert(EKeyD, KEY_D_NAME);
+	iKeyNames.insert(EKeyF, KEY_F_NAME);
+	iKeyNames.insert(EKeyG, KEY_G_NAME);
+	iKeyNames.insert(EKeyH, KEY_H_NAME);
+	iKeyNames.insert(EKeyJ, KEY_J_NAME);
+	iKeyNames.insert(EKeyK, KEY_K_NAME);
+	iKeyNames.insert(EKeyL, KEY_L_NAME);
+	iKeyNames.insert(EKeyZ, KEY_Z_NAME);
+	iKeyNames.insert(EKeyX, KEY_X_NAME);
+	iKeyNames.insert(EKeyC, KEY_C_NAME);
+	iKeyNames.insert(EKeyV, KEY_V_NAME);
+	iKeyNames.insert(EKeyB, KEY_B_NAME);
+	iKeyNames.insert(EKeyN, KEY_N_NAME);
+	iKeyNames.insert(EKeyM, KEY_M_NAME);
+	iKeyNames.insert(EKeyColon, KEY_COLON_NAME);
+	iKeyNames.insert(EKeyDot,   KEY_DOT_NAME);
+	iKeyNames.insert(EKeyDash,  KEY_DASH_NAME);
+	iKeyNames.insert(EKeyAt,	KEY_AT_NAME);
+	iKeyNames.insert(EKeyQuote, KEY_QUOTE_NAME);
+	iKeyNames.insert(EKeyQuestionMark, KEY_QUESTION_MARK_NAME);
+	iKeyNames.insert(EKey32, KEY_32_NAME);
+	iKeyNames.insert(EKey33, KEY_33_NAME);
+	iKeyNames.insert(EKey34, KEY_34_NAME);
+	iKeyNames.insert(EKey35, KEY_35_NAME);
+	iKeyNames.insert(EKey36, KEY_36_NAME);
+	iKeyNames.insert(EKey37, KEY_37_NAME);
+	iKeyNames.insert(EKey38, KEY_38_NAME);
+	iKeyNames.insert(EKey39, KEY_39_NAME);
+	iKeyNames.insert(EKey40, KEY_40_NAME);
+	iKeyNames.insert(EKey41, KEY_41_NAME);
+	iKeyNames.insert(EKey42, KEY_42_NAME);
+	iKeyNames.insert(EKey43, KEY_43_NAME);
+
+
+	// Since reverse lookup in QMap is slow, collect all values into iKeyValues
+	// list, that can be searched.
+	iKeyValues = iKeyNames.values();
+	}
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/cqwertypredictivesearchtable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,360 @@
+/*
+* 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: 
+*
+*/
+
+#include "cqwertypredictivesearchtable.h"
+#include "cqwertykeymap.h"
+#include "dbsqlconstants.h"
+#include <QStringList>
+
+// This macro suppresses own logs
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
+
+
+// Max amount of tokens stored from contact
+const TInt KMaxTokens = 7;
+// Max amount of mail addresses stored from contact
+const TInt KMaxMailAddresses = 3;
+
+// How many characters are stored at most in the tokens
+// Since BIGINT is a signed 64-bit integer, store only 10 characters
+// to prevent overflow when comparing upper and lower limits.
+const TInt KMaxTokenLength = 10;
+
+// Template for table names
+const TInt KMaxTableNameLength = 4;
+_LIT(KTableNameFormat, "qm%d");
+
+// Template for create table commands
+_LIT(KPredSearchCreateQwertyMailTableFormat,
+"CREATE TABLE %S (contact_id INTEGER PRIMARY KEY,\
+ n BIGINT NULL, n2 BIGINT NULL, n3 BIGINT NULL, n4 BIGINT NULL,\
+ n5 BIGINT NULL, n6 BIGINT NULL, n7 BIGINT NULL,\
+ first_name CHAR(16) NULL, last_name CHAR(16) NULL);");
+
+// Template for index names
+// e.g. index0_n2
+_LIT(KIndexNameFormat, "index%d_%S");
+
+// Template for create index commands
+// CREATE INDEX <index name> on <table> (<column>);");
+_LIT(KPredSearchCreateQwertyMailIndexFormat, "CREATE INDEX %S on %S (%S);");
+
+const QString KMailPrefix = "mailto:";
+
+
+/**
+@param aDatabase A handle to the database.
+@param aProperties A contact properties object.
+
+@return A pointer to a new CQwertyPredictiveSearchTable object.
+*/
+CQwertyPredictiveSearchTable*
+CQwertyPredictiveSearchTable::NewL(RSqlDatabase& aDatabase)
+	{
+	PRINT(_L("CQwertyPredictiveSearchTable::NewL"));
+	CQwertyPredictiveSearchTable* self = CQwertyPredictiveSearchTable::NewLC(aDatabase);
+	CleanupStack::Pop(self);
+	PRINT(_L("CQwertyPredictiveSearchTable::NewL ends"));
+	return self;
+	}
+
+
+/**
+@param aDatabase A handle to the database.
+@param aProperties A contact properties object.
+
+@return A pointer to a new CQwertyPredictiveSearchTable object.
+*/
+CQwertyPredictiveSearchTable*
+CQwertyPredictiveSearchTable::NewLC(RSqlDatabase& aDatabase)
+	{
+	PRINT(_L("CQwertyPredictiveSearchTable::NewLC"));
+	CQwertyPredictiveSearchTable* self =
+		new (ELeave) CQwertyPredictiveSearchTable(aDatabase);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	PRINT(_L("CQwertyPredictiveSearchTable::NewLC ends"));
+	return self;
+	}
+
+
+/**
+Destructor
+*/
+CQwertyPredictiveSearchTable::~CQwertyPredictiveSearchTable()
+	{
+	PRINT(_L("CQwertyPredictiveSearchTable dtor"));
+	PRINT(_L("CQwertyPredictiveSearchTable dtor ends"));
+	}
+
+
+/**
+Create the QWERTY tables and its indexes in the database.
+*/
+void CQwertyPredictiveSearchTable::CreateTableL()
+	{
+	PRINT(_L("CQwertyPredictiveSearchTable::CreateTableL"));
+
+	// How many columns have index
+    const TInt KIndexedColumnCount = 9;
+    // Names of columns that have index
+    const TDesC* indexColumns[] = {
+        &KPredSearchQwertyMailNameAsNumber,
+        &KPredSearchQwertyMailNameAsNumber2,
+        &KPredSearchQwertyMailNameAsNumber3,
+        &KPredSearchQwertyMailNameAsNumber4,
+        &KPredSearchQwertyMailNameAsNumber5,
+        &KPredSearchQwertyMailNameAsNumber6,
+        &KPredSearchQwertyMailNameAsNumber7,
+        &KPredSearchQwertyMailFirstName,
+        &KPredSearchQwertyMailLastName};
+    
+    TInt maxColumnLength(0); // Length of longest column name
+    for (TInt column = 0; column < KIndexedColumnCount; ++column)
+        {
+        TInt columnNameLength = indexColumns[column]->Length();
+        if (columnNameLength > maxColumnLength)
+            {
+            maxColumnLength = columnNameLength;
+            }
+        }    
+    
+	// Space needed to represent number CQwertyKeyMap::EAmountOfKeysInQwertyKeypad
+	const TInt KCharsNeededForTableNumber = 2;
+	const TInt KMaxIndexNameLength =
+		KIndexNameFormat().Length() + maxColumnLength + KCharsNeededForTableNumber;
+
+	HBufC* tableName = HBufC::NewLC(KMaxTableNameLength);
+	TPtr ptrTableName = tableName->Des();
+	HBufC* createTableCmd =
+		HBufC::NewLC(KPredSearchCreateQwertyMailTableFormat().Length() +
+					 KMaxTableNameLength);
+	TPtr ptrCreateTableCmd = createTableCmd->Des();
+
+	HBufC* indexName = HBufC::NewLC(KMaxIndexNameLength);
+	TPtr ptrIndexName = indexName->Des();
+	HBufC* createIndexCmd = HBufC::NewLC(KPredSearchCreateQwertyMailIndexFormat().Length() +
+									  KMaxIndexNameLength +
+									  KMaxTableNameLength +
+									  maxColumnLength);
+	TPtr ptrCreateIndexCmd = createIndexCmd->Des();
+
+	for (TInt table = 0; table < CQwertyKeyMap::EAmountOfKeysInQwertyKeypad; ++table)
+		{
+		ptrTableName.Format(KTableNameFormat, table);
+
+		ptrCreateTableCmd.Format(KPredSearchCreateQwertyMailTableFormat, tableName);
+		PRINT1(_L("SQL command: %S"), createTableCmd);
+		User::LeaveIfError(iDatabase.Exec(*createTableCmd));
+
+		// Create indexes for each required column of the current table
+		for (TInt column = 0; column < KIndexedColumnCount; ++column)
+			{
+			ptrIndexName.Format(KIndexNameFormat, table, indexColumns[column]);
+
+			ptrCreateIndexCmd.Format(KPredSearchCreateQwertyMailIndexFormat,
+								     indexName, tableName, indexColumns[column]);
+//			PRINT1(_L("SQL command: %S"), createIndexCmd);
+			User::LeaveIfError(iDatabase.Exec(*createIndexCmd));			
+			}
+		}
+	CleanupStack::PopAndDestroy(createIndexCmd);
+	CleanupStack::PopAndDestroy(indexName);
+	CleanupStack::PopAndDestroy(createTableCmd);
+	CleanupStack::PopAndDestroy(tableName);
+	
+	PRINT(_L("CQwertyPredictiveSearchTable::CreateTableL ends"));
+	}
+
+
+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
+	}
+
+
+HBufC* CQwertyPredictiveSearchTable::TableNameL(const QChar aCh) const
+	{
+	TInt tableNumber = static_cast<CQwertyKeyMap*>(iKeyMap)->MapKeyNameToValue(aCh);
+	if (tableNumber == CQwertyKeyMap::KPadCharValue)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	HBufC* tableName = HBufC::NewL(KMaxTableNameLength);
+	TPtr ptrTableName = tableName->Des();
+	ptrTableName.Format(KTableNameFormat, tableNumber);
+	return tableName;
+	}
+
+
+QList<QChar> CQwertyPredictiveSearchTable::FillAllTables() const
+	{
+	QList<QChar> tables;
+
+	for (TInt key = 0; key < CQwertyKeyMap::EAmountOfKeysInQwertyKeypad; ++key)
+		{
+		tables.append(iKeyMap->ArrayIndexToMappedChar(key));
+		}
+
+	return tables;
+	}
+
+
+void CQwertyPredictiveSearchTable::FillKeyboardSpecificFieldsL(
+	RSqlStatement& aSqlStatement,
+	QStringList aTokens)
+	{
+	const TDesC* paramNames[] = {
+		&KPredSearchQwertyMailNameAsNumberParam,
+		&KPredSearchQwertyMailNameAsNumberParam2,
+		&KPredSearchQwertyMailNameAsNumberParam3,
+		&KPredSearchQwertyMailNameAsNumberParam4,
+		&KPredSearchQwertyMailNameAsNumberParam5,
+		&KPredSearchQwertyMailNameAsNumberParam6,
+		&KPredSearchQwertyMailNameAsNumberParam7};
+	for (TInt i = 0; i < aTokens.count(); ++i)
+		{
+		// TODO: It'd be better to add new fn into CQwertyKeyMap, that computes
+		// the qint64 value like CQwertyKeyMap::ComputeValue().
+		QString dummyLowerLimit;
+		QString upperLimit;
+		User::LeaveIfError(iKeyMap->GetNumericLimits(aTokens[i],
+													 dummyLowerLimit,
+													 upperLimit));
+		bool ok(false);
+		qint64 value(0); // qint64 is same as qlonglong
+		QT_TRYCATCH_LEAVING(value = upperLimit.toLongLong(&ok));
+		if (!ok)
+			{
+			User::Leave(KErrArgument);
+			}
+		// Decrement by one to get the correct value
+		User::LeaveIfError(aSqlStatement.BindInt64(
+			User::LeaveIfError(aSqlStatement.ParameterIndex(*paramNames[i])), --value));
+		}
+	}
+
+
+/**
+* Fetch up to 3 mail addresses
+*/
+QStringList CQwertyPredictiveSearchTable::GetTableSpecificFields(
+	const CContactItem& aItem,
+	TBool& aMandatoryFieldsPresent) const
+	{
+	PRINT(_L("CQwertyPredictiveSearchTable::GetTableSpecificFields"));
+
+	QStringList mailAddresses;
+	
+	// Check that 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;
+		}
+
+	TInt storedAddressCount(0);
+	for (TInt i = aItem.CardFields().Count();
+		 i > 0 && storedAddressCount < KMaxMailAddresses;
+		 --i)
+		{
+		CContactItemField& field = aItem.CardFields()[i - 1];
+		if (field.ContentType().ContainsFieldType(KUidContactFieldEMail) &&
+			field.StorageType() == KStorageTypeText &&
+			field.TextStorage()->IsFull()) // IsFull() returns true if field not empty
+			{
+			TPtrC mailAddress = field.TextStorage()->Text();
+			PRINT2(_L("contact id=%d has mail='%S'"), aItem.Id(), &mailAddress);
+
+			QString wholeAddress((QChar*)mailAddress.Ptr(), mailAddress.Length());
+			QString address = wholeAddress;
+			if (wholeAddress.startsWith(KMailPrefix)) // Skip prefix
+				{
+				address = wholeAddress.mid(KMailPrefix.length());
+#if defined(WRITE_PRED_SEARCH_LOGS)
+				const TInt KLogLength = 40;
+				TBuf<KLogLength> log(address.left(KLogLength).utf16());
+				PRINT1(_L("prefix removed, mail='%S'"), &log);
+#endif
+				}
+			mailAddresses.append(iKeyMap->GetMappedString(address));
+			++storedAddressCount;
+			}
+		}
+	PRINT1(_L("CQwertyPredictiveSearchTable::GetTableSpecificFields found %d mail addrs"),
+		   mailAddresses.count());
+	aMandatoryFieldsPresent = (mailAddresses.count() > 0);
+	return mailAddresses;
+	}
+
+
+/**
+Set up the CCntSqlStatement objects held by the class.
+*/
+void CQwertyPredictiveSearchTable::ConstructL()
+	{
+	PRINT(_L("CQwertyPredictiveSearchTable::ConstructL"));
+
+	CPplPredictiveSearchTableBase::ConstructL();
+
+	// Set details of INSERT
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailContactId,
+	                        KPredSearchQwertyMailContactIdParam);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber,
+							KPredSearchQwertyMailNameAsNumberParam);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber2,
+							KPredSearchQwertyMailNameAsNumberParam2);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber3,
+							KPredSearchQwertyMailNameAsNumberParam3);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber4,
+							KPredSearchQwertyMailNameAsNumberParam4);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber5,
+							KPredSearchQwertyMailNameAsNumberParam5);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber6,
+							KPredSearchQwertyMailNameAsNumberParam6);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailNameAsNumber7,
+							KPredSearchQwertyMailNameAsNumberParam7);
+
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailFirstName,
+							KPredSearchQwertyMailFirstNameParam);
+	iInsertStmnt->SetParamL(KPredSearchQwertyMailLastName,
+							KPredSearchQwertyMailLastNameParam);
+
+	PRINT(_L("CQwertyPredictiveSearchTable::ConstructL create key map"));
+	iKeyMap = CQwertyKeyMap::NewL();
+
+	PRINT(_L("CQwertyPredictiveSearchTable::ConstructL ends"));
+	}
+
+
+/**
+Constructor
+*/
+CQwertyPredictiveSearchTable::CQwertyPredictiveSearchTable(RSqlDatabase& aDatabase) :
+	CPplPredictiveSearchTableBase(aDatabase, KMaxTokens, KMaxTokenLength)
+	{
+	}
--- a/phonebookengines/contactsmodel/cntplsql/src/csqlitelocalview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/src/csqlitelocalview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -644,17 +644,19 @@
 		switch(aEvent.iType)
 			{
 			case EContactDbObserverEventGroupChanged:
-				{
-				//Groups are a special case the base view may not contain the group
-				//but a sub view may be such a group and need to know its changed
-				//Local views can contain groups so this case carries on to the next so no break;
-				event.iEventType=TContactViewEvent::EGroupChanged;
-				event.iContactId=aEvent.iContactId;
-				NotifyObservers(event);
-				}
 			case EContactDbObserverEventContactChanged:
 			case EContactDbObserverEventOwnCardChanged:
-				{// Remove from old position, and notify.
+				{
+				if (aEvent.iType == EContactDbObserverEventGroupChanged)
+				    {
+	    			//Groups are a special case the base view may not contain the group
+    				//but a sub view may be such a group and need to know its changed
+				    event.iEventType=TContactViewEvent::EGroupChanged;
+				    event.iContactId=aEvent.iContactId;
+				    NotifyObservers(event);
+				    }
+				
+				// Remove from old position, and notify.
 				TRAPD(err,event.iInt=RemoveL(aEvent.iContactId));
 
                 if (err == KErrNone && event.iInt != KErrNotFound)
--- a/phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -26,6 +26,11 @@
 #include "cntsqlprovider.h"
 #include "dbsqlconstants.h"
 #include "cntpersistenceutility.h"
+#include "c12keypredictivesearchtable.h"
+#include "cqwertypredictivesearchtable.h"
+#include "cpredictivesearchsettingstable.h"
+#include "cpredictivesearchsynchronizer.h"
+#include "predictivesearchlog.h"
 //#include "cntmetadataoperation.h"
 #include <cntdef.h>
 #include <sqldb.h>
@@ -35,6 +40,9 @@
 // macro. Uncomment the below line to get the table into use.
 #define USE_PRED_SEARCH_TABLE
 
+// If this macro is defined, then pred.search qwerty tables are used
+#define USE_QWERTY_PRED_SEARCH_TABLE
+
 
 /**
 Creates a concrete CPplContactItemManager object 
@@ -63,10 +71,16 @@
 	delete iContactTable;
 	delete iCommAddrTable;
 #if defined(USE_PRED_SEARCH_TABLE)
-	RDebug::Print(_L("delete pred search table"));
-	delete iPredSearchTable;
+	PRINT(_L("delete pred search table objects"));
+	delete iPredictiveSearchSynchronizer;
+	delete iPredSearch12keyTable;
+#if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+	delete iPredSearchQwertyTable;
+	delete iPredSearchSettingsTable;
 #endif
-    delete 	iPresenceTable; 
+	PRINT(_L("delete pred search table objects - done"));
+#endif
+    delete iPresenceTable; 
 	delete iGroupTable;
 	delete iPreferencePersistor;
 	//iColSession.Close();
@@ -129,9 +143,13 @@
 	iGroupTable->CreateInDbL(aItem);	
 	iCommAddrTable->CreateInDbL(aItem);
 #if defined(USE_PRED_SEARCH_TABLE)
-	RDebug::Print(_L("add new contact to pred search table"));
-	iPredSearchTable->CreateInDbL(aItem);
-	RDebug::Print(_L("add new contact to pred search table - done"));
+	PRINT(_L("add new contact to pred search tables"));
+	iPredSearch12keyTable->CreateInDbL(aItem);
+#if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+	iPredSearchQwertyTable->CreateInDbL(aItem);
+	iPredSearchSettingsTable->CreateInDbL(aItem);
+#endif
+	PRINT(_L("add new contact to pred search tables - done"));
 #endif
 
    	TContactItemId groupId = iIccContactStore.CreateInDbL(aItem, aSessionId);
@@ -322,9 +340,13 @@
 	iGroupTable->UpdateL(aItem);	
 	iCommAddrTable->UpdateL(aItem);
 #if defined(USE_PRED_SEARCH_TABLE)
-	RDebug::Print(_L("update contact in pred search table"));
-	iPredSearchTable->UpdateL(aItem);
-	RDebug::Print(_L("update contact in pred search table - done"));
+	PRINT(_L("update contact in pred search tables"));
+	iPredSearch12keyTable->UpdateL(aItem);
+#if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+	iPredSearchQwertyTable->UpdateL(aItem);
+	iPredSearchSettingsTable->UpdateL(aItem);
+#endif
+	PRINT(_L("update contact in pred search tables - done"));
 #endif
 
 	if(controlTransaction)
@@ -376,7 +398,7 @@
 
 	TBool lowDisk = EFalse;
 	CContactItem* savedContactItem = static_cast<CPplContactTable*>(iContactTable)->DeleteLC(aItemId, lowDisk);
-	if(lowDisk) 
+	if (lowDisk) 
 		{
 		CleanupStack::PopAndDestroy(savedContactItem); // this was returned from the first call, but not deleted in the db
 		TInt err = iDatabase.GetReserveAccess();
@@ -398,27 +420,40 @@
 
 	lowDisk = EFalse;	
 	iGroupTable->DeleteL(*savedContactItem, lowDisk);	
-	if(lowDisk) 
+	if (lowDisk) 
 		{
 		DeleteInLowDiskConditionL(iGroupTable, savedContactItem);
 		}
 
 	lowDisk = EFalse;
 	iCommAddrTable->DeleteL(*savedContactItem, lowDisk);	
-	if(lowDisk) 
+	if (lowDisk) 
 		{
 		DeleteInLowDiskConditionL(iCommAddrTable, savedContactItem);
 		}
 
 #if defined(USE_PRED_SEARCH_TABLE)
-	RDebug::Print(_L("delete contact from pred search table"));
+	PRINT(_L("delete contact from pred search tables"));
+	lowDisk = EFalse;
+    iPredSearch12keyTable->DeleteL(*savedContactItem, lowDisk);
+    if (lowDisk) 
+		{
+		DeleteInLowDiskConditionL(iPredSearch12keyTable, savedContactItem);
+		}
 	lowDisk = EFalse;
-    iPredSearchTable->DeleteL(*savedContactItem, lowDisk);
-    if(lowDisk) 
+#if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+	iPredSearchQwertyTable->DeleteL(*savedContactItem, lowDisk);
+    if (lowDisk) 
 		{
-		DeleteInLowDiskConditionL(iPredSearchTable, savedContactItem);
+		DeleteInLowDiskConditionL(iPredSearchQwertyTable, savedContactItem);
 		}
-	RDebug::Print(_L("delete contact from pred search table - done"));
+	iPredSearchSettingsTable->DeleteL(*savedContactItem, lowDisk);
+    if (lowDisk) 
+		{
+		DeleteInLowDiskConditionL(iPredSearchSettingsTable, savedContactItem);
+		}
+#endif
+	PRINT(_L("delete contact from pred search tables - done"));
 #endif
   
     //Fake checking read access to ICCEntry store to keep BC.
@@ -533,11 +568,24 @@
 	iCommAddrTable = CPplCommAddrTable::NewL(iDatabase, iContactProperties);
 	iGroupTable = CPplGroupsTable::NewL(iDatabase);
 	iPreferencePersistor = CPplPreferencesPersistor::NewL(iDatabase);
+
 #if defined(USE_PRED_SEARCH_TABLE)
-	RDebug::Print(_L("create CPplPredictiveSearchTable object"));
-	iPredSearchTable = CPplPredictiveSearchTable::NewL(iDatabase);
-	RDebug::Print(_L("create CPplPredictiveSearchTable object - done"));
-#endif
+	PRINT(_L("create C12keyPredictiveSearchTable object"));
+	iPredSearch12keyTable = C12keyPredictiveSearchTable::NewL(iDatabase);
+#if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+	PRINT(_L("create CQwertyPredictiveSearchTable object"));
+	iPredSearchQwertyTable = CQwertyPredictiveSearchTable::NewL(iDatabase);
+	PRINT(_L("create CPredictiveSearchSettingsTable object"));
+	iPredSearchSettingsTable = CPredictiveSearchSettingsTable::NewL(iDatabase);
+
+	iPredictiveSearchSynchronizer =
+		CPredictiveSearchSynchronizer::NewL(iDatabase,
+											*iPredSearch12keyTable,
+											*iPredSearchQwertyTable,
+											*iPredSearchSettingsTable);
+#endif // #if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+#endif // #if defined(USE_PRED_SEARCH_TABLE)
+
 	iPresenceTable = CPplPresenceTable::NewL(iDatabase); 
 	
 	// Connect to metadata server
@@ -610,7 +658,7 @@
 
 	TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
 	
-	if(controlTransaction)
+	if (controlTransaction)
 		{
 		StartTransactionL(0);
 		}
@@ -620,13 +668,17 @@
 	iCommAddrTable->CreateTableL();
 	iPreferencePersistor->CreateTableL();
 #if defined(USE_PRED_SEARCH_TABLE)
-	RDebug::Print(_L("create pred search table to DB"));	
-	iPredSearchTable->CreateTableL();
-	RDebug::Print(_L("create pred search table to DB - done"));	
+	PRINT(_L("create pred search tables to DB"));	
+	iPredSearch12keyTable->CreateTableL();
+#if defined(USE_QWERTY_PRED_SEARCH_TABLE)
+	iPredSearchQwertyTable->CreateTableL();
+	iPredSearchSettingsTable->CreateTableL();
+#endif
+	PRINT(_L("create pred search tables to DB - done"));	
 #endif
 	iPresenceTable->CreateTableL(); 
 	
-	if(controlTransaction)
+	if (controlTransaction)
 		{
 		CommitTransactionL();
 		}			
@@ -712,12 +764,12 @@
 	const TInt KIdx = iSelectStatement->ParameterIndex(KContactId);
 	
 	TInt err;
-	while((err = selectStatement.Next()) == KSqlAtRow)
+	while ((err = selectStatement.Next()) == KSqlAtRow)
 		{
 		idArray->AddL(selectStatement.ColumnInt(KIdx));	
 		}
 
-	if(err != KSqlAtEnd)
+	if (err != KSqlAtEnd)
 		{
 		User::Leave(err);
 		}
@@ -763,7 +815,7 @@
     stream.WriteInt32L(0);
     stream.Close();
 
-    if(err != KSqlAtEnd)
+    if (err != KSqlAtEnd)
         {
         User::Leave(err);
         }
@@ -775,7 +827,6 @@
     return array;
     }
 
-
 /**
 Utility method used to rthe prefered card template id
 */
@@ -792,162 +843,17 @@
 	iPreferencePersistor->SetPreferredCardTemplateIdL(aCardTemplatePrefId);
 	}
 
-// If predictive search tables do not exist, generate them using data from
-// contacts table.
 void CPplContactItemManager::SynchronizePredSearchTableL()
 	{
-#if !defined(USE_PRED_SEARCH_TABLE)
-	return;
+#if defined(USE_PRED_SEARCH_TABLE)
+	iPredictiveSearchSynchronizer->SynchronizeTablesL();
 #endif
-	RDebug::Print(_L("CPplContactItemManager::SynchronizePredSearchTableL"));
-
-	if (!DoesPredSearchTableExistL())
-		{
-		CreatePredSearchTablesL();
-		}
 	}
 
 void CPplContactItemManager::RecreatePredSearchTablesL()
 	{
-	DeletePredSearchTablesL();
-	CreatePredSearchTablesL();
+#if defined(USE_PRED_SEARCH_TABLE)
+	iPredictiveSearchSynchronizer->DeletePredSearchTablesL();
+	iPredictiveSearchSynchronizer->CreatePredSearchTablesL();
+#endif
 	}
-
-void CPplContactItemManager::CreatePredSearchTablesL()
-	{
-	RDebug::Print(_L("CPplContactItemManager::CreatePredSearchTablesL"));
-
-	iPredSearchTable->CreateTableL();
-	_LIT(KSelectAllContactsFormat, "SELECT %S,%S,%S FROM %S;");
-	TInt bufSize = KSelectAllContactsFormat().Length() +
-				   KContactId().Length() +
-				   KContactFirstName().Length() +
-				   KContactLastName().Length() +
-				   KSqlContactTableName().Length();
-	HBufC* sqlStatement = HBufC::NewLC(bufSize);
-	sqlStatement->Des().AppendFormat(KSelectAllContactsFormat,
-		&KContactId,
-		&KContactFirstName,
-		&KContactLastName,
-		&KSqlContactTableName);
-
-	RSqlStatement stmnt;
-	CleanupClosePushL(stmnt);
-	RDebug::Print(_L("CreatePredSearchTablesL prepare SQL statement"));
-    stmnt.PrepareL(iDatabase, *sqlStatement);
-
-	const TInt KContactIdIndex = 0;
-	const TInt KFirstNameIndex = 1;
-	const TInt KLastNameIndex = 2;
-	TInt err(KErrNone);
-    while ((err = stmnt.Next()) == KSqlAtRow)
-        {
-		RDebug::Print(_L("CreatePredSearchTablesL create CContactItem"));
-
-		TInt id = KUidContactCardValue;
-		TUid uid;
-		uid.iUid = id;
-		CContactItem* contact = CContactItem::NewLC(uid);
-		contact->SetId(stmnt.ColumnInt(KContactIdIndex));
-
-		// If first name exists, write it to contact item
-		TPtrC firstName;
-		if (stmnt.ColumnText(KFirstNameIndex, firstName) == KErrNone)
-			{
-			CContactItemField* field =
-				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
-			CContactTextField* textfield = field->TextStorage();
-			textfield->SetTextL(firstName);
-			contact->AddFieldL(*field); // Takes ownership
-			CleanupStack::Pop(field);
-			}
-
-		TPtrC lastName;
-		if (stmnt.ColumnText(KLastNameIndex, lastName) == KErrNone)
-			{
-			CContactItemField* field =
-				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
-			CContactTextField* textfield = field->TextStorage();
-			textfield->SetTextL(lastName);
-			contact->AddFieldL(*field); // Takes ownership
-			CleanupStack::Pop(field);
-			}
-		RDebug::Print(_L("CreatePredSearchTablesL create entry to tables"));
-		iPredSearchTable->CreateInDbL(*contact);
-		CleanupStack::PopAndDestroy(contact);
-        }
-
-    // Leave if we didn't complete going through the results properly
-    if (err != KSqlAtEnd)
-        {
-		RDebug::Print(_L("CreatePredSearchTablesL SQL err=%d"), err);
-        User::Leave(err);
-        }
-    CleanupStack::PopAndDestroy(&stmnt);
-	CleanupStack::PopAndDestroy(sqlStatement);
-
-	RDebug::Print(_L("CPplContactItemManager::CreatePredSearchTablesL ends"));
-	}
-
-TBool CPplContactItemManager::DoesPredSearchTableExistL() const
-	{
-	RDebug::Print(_L("CPplContactItemManager::DoesPredSearchTableExistL"));
-
-	_LIT(KSelectContactIdsFormat, "SELECT %S FROM %S;");
-	TInt bufSize = KSelectContactIdsFormat().Length() +
-				   KPredSearchContactId().Length() +
-				   KSqlContactPredSearchTable0().Length();
-	HBufC* sqlStatement = HBufC::NewLC(bufSize);
-	sqlStatement->Des().AppendFormat(KSelectContactIdsFormat,
-		&KPredSearchContactId,
-		&KSqlContactPredSearchTable0);
-
-	RSqlStatement stmnt;
-	CleanupClosePushL(stmnt);
-	// If predictive search table does not exist, leaves with -311.
-    // If it exists, does not leave.
-    TRAPD(err, stmnt.PrepareL(iDatabase, *sqlStatement));
-	RDebug::Print(_L("err=%d"), err );
-
-	CleanupStack::PopAndDestroy(&stmnt);
-	CleanupStack::PopAndDestroy(sqlStatement);
-
-	RDebug::Print(_L("CPplContactItemManager::DoesPredSearchTableExistL return %d"),
-				  err == KErrNone );
-	return err == KErrNone;
-	}
-
-void CPplContactItemManager::DeletePredSearchTablesL()
-	{
-	RDebug::Print(_L("CPplContactItemManager::DeletePredSearchTablesL"));
-
-	const TInt KTableCount = 10;
-    const TDesC* KTableNames[KTableCount] =
-        {
-        &KSqlContactPredSearchTable0,
-        &KSqlContactPredSearchTable1,
-        &KSqlContactPredSearchTable2,
-        &KSqlContactPredSearchTable3,
-        &KSqlContactPredSearchTable4,
-        &KSqlContactPredSearchTable5,
-        &KSqlContactPredSearchTable6,
-        &KSqlContactPredSearchTable7,
-        &KSqlContactPredSearchTable8,
-        &KSqlContactPredSearchTable9
-        };
-
-	// IF EXISTS suppresses error that would occur if table does not exist
-	_LIT(KDropTable, "DROP TABLE IF EXISTS %S;");
-    for (TInt i = 0; i < KTableCount; ++i)
-        {
-        HBufC* dropTableCommand = HBufC::NewLC(KDropTable().Length() +
-            // All table names are of same length
-            KTableNames[i]->Length());
-        TPtr ptr = dropTableCommand->Des();
-        ptr.Format(KDropTable, KTableNames[i]);
-
-		User::LeaveIfError(iDatabase.Exec(*dropTableCommand));
-        CleanupStack::PopAndDestroy(dropTableCommand);
-        }
-	RDebug::Print(_L("CPplContactItemManager::DeletePredSearchTablesL ends"));
-	}
--- a/phonebookengines/contactsmodel/cntsrv/inc/CCntFileManagerMsgHandler.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntsrv/inc/CCntFileManagerMsgHandler.h	Wed Jun 23 18:02:44 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.
@@ -46,6 +46,7 @@
 	
 private:
 	CCntFileManagerMsgHandler(CCntSession& aSession);
+	void ConstructL();
 	
 public:
 	// Delegates to the appropriate CCntDbManagerController method.
@@ -66,6 +67,7 @@
 	void FetchTemplateIdsL(const RMessage2& aMessage);
 	void FetchGroupIdListsL(const RMessage2& aMessage);
 	void FetchSearchResultsL(const RMessage2& aMessage); 
+	void FetchPredictiveSearchResultsL(const RMessage2& aMessage);
 	
 	// Non-CRUD file operations
 	void RecoverDbL(const RMessage2& aMessage);
@@ -86,6 +88,9 @@
 
 private:
 	void FileOpenCreateReplaceL(const RMessage2& aMessage, TCntFileMode aMode);
+	
+private:
+	CntPredictiveSearch* predictiveSearch;
 	};
 	
 #endif
--- a/phonebookengines/contactsmodel/cntsrv/inc/CCntIpcCodes.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntsrv/inc/CCntIpcCodes.h	Wed Jun 23 18:02:44 2010 +0300
@@ -38,6 +38,7 @@
 
 // To be removed. Should be defined in a header file
 #define KCntSearchResultList 99
+#define KCntPredictiveSearchList 98
 
 /**
 Contacts database filename maximum length.  Used to police descriptors on Client
@@ -111,7 +112,10 @@
     ECntSearchResultList = KCntSearchResultList,  // Do not change this enum value
                                                   // and do not add anything immediately
                                                   // after this.
-	// ---- Read User Data capability ----
+    ECntPredictiveSearchList = KCntPredictiveSearchList,     // Do not change this enum value
+                                                    // and do not add anything immediately
+                                                    // after this.
+                                                    // ---- Read User Data capability ----
 	ECntOpenDataBase= KCapabilityReadUserData,
 	ECntReOpenDbTables,
 	ECntCreateView,
--- a/phonebookengines/contactsmodel/cntsrv/src/CCntFileManagerMsgHandler.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntsrv/src/CCntFileManagerMsgHandler.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -37,6 +37,7 @@
 #include <cntviewstore.h>
 #include "cntviewprivate.h"
 #include "cviewsubsessions.h"
+#include "cntpredictivesearch.h"
 
 const TInt KCntFileManagerIpcCodes[] =
 	{
@@ -57,6 +58,7 @@
 	ECntFetchTemplateIds,
 	ECntFetchGroupIdLists,
 	ECntSearchResultList,
+	ECntPredictiveSearchList,
 	ECntFilesSize,
 	ECntGetDefinitionsForExistingView
 	};
@@ -73,9 +75,18 @@
 :CCntMsgHandler(aSession)
 	{		
 	}
-	
+
+// ----------------------------------------------------------------------------
+// CntPredictiveSearch::ConstructL
+// ----------------------------------------------------------------------------
+void CCntFileManagerMsgHandler::ConstructL()
+    {
+    predictiveSearch = CntPredictiveSearch::NewL();
+    }
+
 CCntFileManagerMsgHandler::~CCntFileManagerMsgHandler()
 	{
+    delete predictiveSearch;
 	}
 
 /**
@@ -388,7 +399,37 @@
 		}
 	}
 	
+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);
+    
+    CheckForManagerL();
+    HBufC* newPredictiveQuery = predictiveSearch->CreateSQLQueryL(*searchQuery, 1 );
+    CleanupStack::PushL(newPredictiveQuery);
+    CBufSeg* buffer = iManager->GetPersistenceLayer().ContactProperties().DetailsListL(newPredictiveQuery->Des());
+    if (aMessage.GetDesMaxLength(0) >= buffer->Size())
+        {
+        TInt offset = 0;
+        while (offset < buffer->Size())
+            {
+            TPtr8 ptr = buffer->Ptr(offset);
+            aMessage.WriteL(0, ptr, offset);
+            offset += ptr.Size();
+            }
+        aMessage.Complete(KErrNone);
+        }
+    else
+        {
+        aMessage.Complete(buffer->Size());
+        }
 
+    delete buffer;
+    CleanupStack::PopAndDestroy(); //searchQuery*/
+    CleanupStack::PopAndDestroy(); //newPredictiveQuery
+    }
 void CCntFileManagerMsgHandler::FetchSearchResultsL(const RMessage2& aMessage)
     {
     const TInt KSqlQueryMaxLen = aMessage.GetDesLengthL(1); 
--- a/phonebookengines/contactsmodel/cntsrv/src/CCntServer.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntsrv/src/CCntServer.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -366,6 +366,7 @@
 	iMsgLut.InsertL(ECntFetchGroupIdLists,      static_cast<MsgHandlerFptr>(&CCntFileManagerMsgHandler::FetchGroupIdListsL));
 	iMsgLut.InsertL(ECntSearchResultList,  static_cast<MsgHandlerFptr>(&CCntFileManagerMsgHandler::FetchSearchResultsL));
 	
+	iMsgLut.InsertL(ECntPredictiveSearchList,  static_cast<MsgHandlerFptr>(&CCntFileManagerMsgHandler::FetchPredictiveSearchResultsL));
 	iMsgLut.InsertL(ECntFilesSize,          static_cast<MsgHandlerFptr>(&CCntFileManagerMsgHandler::FilesSizeL));
 	
 	iMsgLut.InsertL(ECntGetDefinitionsForExistingView, static_cast<MsgHandlerFptr>(&CCntFileManagerMsgHandler::GetDefinitionsForExistingViewL));
--- a/phonebookengines/contactsmodel/cntsrv/src/CCntStateMachine.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/cntsrv/src/CCntStateMachine.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -2538,20 +2538,26 @@
  @param aPersistenceLayer. The persistence layer that wraps up access to the database.
 */
 void CCntStateMachine::ConstructL(CPersistenceLayer& aPersistenceLayer)
-	{
-	iState = CStateClosed::NewL(*this, aPersistenceLayer);
-	CleanupStack::PushL(iState);
-	// The order in which states are appended must be in sync with
-	// the declaration order of the state enum.
-	iStateArray.AppendL(iState); 
-	CleanupStack::Pop(iState);
-	
-	iStateArray.AppendL(CStateTablesClosed::NewL(*this, aPersistenceLayer)); 
-	iStateArray.AppendL(CStateWritable	  ::NewL(*this, aPersistenceLayer));
-	iStateArray.AppendL(CStateOpening 	  ::NewL(*this, aPersistenceLayer));
-	iStateArray.AppendL(CStateTransaction ::NewL(*this, aPersistenceLayer));
-	iStateArray.AppendL(CStateBackupRestore::NewL(*this, aPersistenceLayer));
-	}
+    {
+    // The order in which states are appended must be in sync with
+    // the declaration order of the state enum.
+    for (TInt i = 0; i < 6; ++i)
+        {
+        CState* state;
+        switch (i)
+            {
+            case 0:  state = CStateClosed::NewL(*this, aPersistenceLayer); iState = state; break;
+            case 1:  state = CStateTablesClosed::NewL(*this, aPersistenceLayer); break;
+            case 2:  state = CStateWritable::NewL(*this, aPersistenceLayer); break;
+            case 3:  state = CStateOpening::NewL(*this, aPersistenceLayer); break;
+            case 4:  state = CStateTransaction::NewL(*this, aPersistenceLayer); break;
+            default: state = CStateBackupRestore::NewL(*this, aPersistenceLayer); 
+            }
+        CleanupStack::PushL(state);
+        iStateArray.AppendL(state); 
+        CleanupStack::Pop(state);
+        }	
+    }
 
 /**
  Get the current active state		
--- a/phonebookengines/contactsmodel/contactsmodel.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/contactsmodel.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -53,7 +53,9 @@
                   inc/cntmodel.rh\
                   inc/cntdef.hrh\
                   inc/cntviewstore.h\
-                  cntvcard/cntvcard.h
+                  inc/cntpredictivesearch.h\
+                  cntvcard/cntvcard.h\
+                 
 
 for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
 
--- a/phonebookengines/contactsmodel/eabi/cntplsqlU.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/eabi/cntplsqlU.def	Wed Jun 23 18:02:44 2010 +0300
@@ -18,4 +18,9 @@
 	_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
 
--- a/phonebookengines/contactsmodel/group/CNTSRV.MMP	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/group/CNTSRV.MMP	Wed Jun 23 18:02:44 2010 +0300
@@ -24,8 +24,9 @@
 
 CAPABILITY   readuserdata  writeuserdata   protserv
 
-UID		0x10004019 0x10003A73
-VENDORID 0x70000001
+UID				0x10004019 0x10003A73
+VENDORID 		0x70000001
+EPOCSTACKSIZE	0x14000
 
 //MACRO __VERBOSE_DEBUG__
 //MACRO __STATE_MACHINE_DEBUG__
@@ -80,6 +81,3 @@
 #else
 LIBRARY		cntpldbms.lib
 #endif
-
-
-
--- a/phonebookengines/contactsmodel/group/COMMON.INF	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/group/COMMON.INF	Wed Jun 23 18:02:44 2010 +0300
@@ -53,13 +53,13 @@
 // Default View Definition store
 ../inc/cntviewstore.h SYMBIAN_APP_LAYER_PLATFORM_EXPORT_PATH(cntviewstore.h)
 
-// Documentation
-../documentation/contacts_connectivityapi.doc	/epoc32/engdoc/cntmodel/contacts_connectivityapi.doc
-../documentation/contacts_current_itemapi.doc	/epoc32/engdoc/cntmodel/contacts_current_itemapi.doc
-../documentation/contacts_group_supportapi.doc		/epoc32/engdoc/cntmodel/contacts_group_supportapi.doc
-../documentation/contacts_multiple_templatesapi.doc	/epoc32/engdoc/cntmodel/contacts_multiple_templatesapi.doc
-../documentation/contacts_own_card_supportapi.doc	/epoc32/engdoc/cntmodel/contacts_own_card_supportapi.doc
-../documentation/contacts_sorting_view_supportapi.doc	/epoc32/engdoc/cntmodel/contacts_sorting_view_supportapi.doc
+// 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
+// ../documentation/contacts_group_supportapi.doc		/epoc32/engdoc/cntmodel/contacts_group_supportapi.doc
+// ../documentation/contacts_multiple_templatesapi.doc	/epoc32/engdoc/cntmodel/contacts_multiple_templatesapi.doc
+// ../documentation/contacts_own_card_supportapi.doc	/epoc32/engdoc/cntmodel/contacts_own_card_supportapi.doc
+// ../documentation/contacts_sorting_view_supportapi.doc	/epoc32/engdoc/cntmodel/contacts_sorting_view_supportapi.doc
 
 PRJ_MMPFILES
 
--- a/phonebookengines/contactsmodel/groupsql/cntplsql.mmp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/groupsql/cntplsql.mmp	Wed Jun 23 18:02:44 2010 +0300
@@ -30,6 +30,8 @@
 
 APP_LAYER_SYSTEMINCLUDE
 
+
+
 // These two SYSTEMINCLUDES are needed as QT headers are used
 SYSTEMINCLUDE		/epoc32/include/mw/QtCore
 SYSTEMINCLUDE		/epoc32/include/stdapis/stlportv5
@@ -65,6 +67,10 @@
 source		cpplgroupstable.cpp
 source		cpplcommaddrtable.cpp
 source		cpplpredictivesearchtable.cpp
+source		c12keypredictivesearchtable.cpp
+source		cqwertypredictivesearchtable.cpp
+source		cpredictivesearchsettingstable.cpp
+source		cpredictivesearchsynchronizer.cpp
 
 source 		pplcontactitemmanager.cpp
 source		rpplicccontactstore.cpp
@@ -83,9 +89,13 @@
 source      cntpplviewmanager.cpp
 source      cntpplviewsession.cpp
 
-source    cpcskeymap.cpp
+source		cpcskeymap.cpp
+source		c12keykeymap.cpp
+source		cqwertykeymap.cpp
 //source		cntmetadataoperation.cpp
-source    cpplpresencetable.cpp
+source		cpplpresencetable.cpp
+source    cntpredictivesearch.cpp
+source    cntsqlsearch.cpp
 
 LIBRARY         euser.lib 
 LIBRARY         efsrv.lib 
@@ -102,6 +112,7 @@
 
 OPTION ARMCC --visibility_inlines_hidden
 
+
 EPOCALLOWDLLDATA
 STDCPP
 SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/inc/cntpredictivesearch.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,66 @@
+/*
+* 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/phonebookengines/contactsmodel/tsrc/cntplsql/group/t_cntplsql.mmp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/group/t_cntplsql.mmp	Wed Jun 23 18:02:44 2010 +0300
@@ -35,18 +35,28 @@
 SOURCEPATH      ../src
 SOURCE          dllmain.cpp
 SOURCE          t_cpcskeymap.cpp
+SOURCE          t_cqwertykeymap.cpp
 SOURCE          t_cpplpredictivesearchtable.cpp
+SOURCE          t_cqwertypredictivesearchtable.cpp
+SOURCE          t_cpredictivesearchsettingstable.cpp
  
 // Code that is tested
 SOURCEPATH      ../../../cntplsql/src
 SOURCE          cpcskeymap.cpp
+SOURCE          c12keykeymap.cpp
+SOURCE          cqwertykeymap.cpp
 SOURCE          cpplpredictivesearchtable.cpp
+SOURCE          c12keypredictivesearchtable.cpp
+SOURCE          cqwertypredictivesearchtable.cpp
+SOURCE          cpredictivesearchsettingstable.cpp
+SOURCE          cpredictivesearchsynchronizer.cpp
 // Other required code
 SOURCE          cntsqlprovider.cpp
 
 USERINCLUDE     ../../../cntplsql/inc
 USERINCLUDE     ../../../cntsrv/inc
 
+
 APP_LAYER_SYSTEMINCLUDE
 #if defined ( OS_LAYER_SYSTEMINCLUDE )
 OS_LAYER_SYSTEMINCLUDE
--- a/phonebookengines/contactsmodel/tsrc/cntplsql/src/dllmain.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/dllmain.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -19,7 +19,10 @@
 #include <digia/eunit/ceunittestsuite.h>
 //  INTERNAL INCLUDES
 #include "t_cpcskeymap.h"
+#include "t_cqwertykeymap.h"
 #include "t_cpplpredictivesearchtable.h"
+#include "t_cqwertypredictivesearchtable.h"
+#include "t_cpredictivesearchsettingstable.h"
 
 /**
  * Test suite factory function.
@@ -28,12 +31,21 @@
     {
     CEUnitTestSuite* rootSuite = CEUnitTestSuite::NewLC(_L("cntplsql unit tests"));
 
-    rootSuite->AddL( UT_CPcsKeyMap::NewLC() );
+    rootSuite->AddL(UT_CPcsKeyMap::NewLC());
     CleanupStack::Pop(); // UT_CPcsKeyMap instance
+
+	rootSuite->AddL(UT_CQwertyKeyMap::NewLC());
+    CleanupStack::Pop(); // UT_CQwertyKeyMap instance
  
-    rootSuite->AddL( UT_CPplPredictiveSearchTable::NewLC() );
+    rootSuite->AddL(UT_CPplPredictiveSearchTable::NewLC());
     CleanupStack::Pop(); // UT_CPplPredictiveSearchTable instance
     
-    CleanupStack::Pop( rootSuite );
+    rootSuite->AddL(UT_CQwertyPredictiveSearchTable::NewLC());
+    CleanupStack::Pop(); // UT_CQwertyPredictiveSearchTable instance
+    
+    rootSuite->AddL(UT_CPredictiveSearchSettingsTable::NewLC());
+    CleanupStack::Pop(); // UT_CPredictiveSearchSettingsTable instance
+
+    CleanupStack::Pop(rootSuite);
     return rootSuite;
     }
--- a/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -11,13 +11,15 @@
 *
 * Contributors:
 *
-* Description:  Unit test class for testing CPcsKeyMap
+* Description:  Unit test class for testing C12keyKeyMap
 *
 */
 
 // INTERNAL INCLUDES
 #include "t_cpcskeymap.h"
-#include "cpcskeymap.h"
+#include "c12keykeymap.h"
+#include <QString>
+#include <QTextCodec>
 
 // SYSTEM INCLUDES
 #include <digia/eunit/eunitmacros.h>
@@ -25,6 +27,39 @@
 #include <hbinputkeymapfactory.h>
 #endif
 
+
+// 10.1 wk12 SDK's Thai keymap does not map anything to *,# keys
+// so must use either a hardcoded keymap, or replace the SDK's keymap
+// with a newer one by copying the keymap file 120.txt to
+// \epoc32\release\winscw\udeb\z\resource\keymaps
+
+/* New Thai keymap, not yet present in the wk12 SDK
+1   x0E01\x0E02\x0E03\x0E04\x0E05\x0031\t\x0E01\x0E02\x0E03\x0E04\x0E05\x0031"
+2   x0E06\x0E07\x0E08\x0E09\x0032\t\x0E06\x0E07\x0E08\x0E09\x0032"
+3   x0E0A\x0E0B\x0E0C\x0E0D\x0033\t\x0E0A\x0E0B\x0E0C\x0E0D\x0033"
+4   x0E0E\x0E0F\x0E10\x0E11\x0E12\x0E13\x0034\t\x0E0E\x0E0F\x0E10\x0E11\x0E12\x0E13\x0034"
+5   x0E14\x0E15\x0E16\x0E17\x0E18\x0035\t\x0E14\x0E15\x0E16\x0E17\x0E18\x0035"
+6   x0E19\x0E1A\x0E1B\x0E1C\x0E1D\x0036\t\x0E19\x0E1A\x0E1B\x0E1C\x0E1D\x0036"
+7   x0E1E\x0E1F\x0E20\x0E21\x0E22\x0037\t\x0E1E\x0E1F\x0E20\x0E21\x0E22\x0037"
+8   x0E23\x0E24\x0E25\x0E26\x0E27\x0E28\x0E29\x0038\t\x0E23\x0E24\x0E25\x0E26\x0E27\x0E28\x0E29\x0038"
+9   x0E2A\x0E2B\x0E2C\x0E2D\x0E2E\x0039\t\x0E2A\x0E2B\x0E2C\x0E2D\x0E2E\x0039"
+0   0\x21B2\t 0\x21B2"
+*   x0E2F\x0E3F\x0E31\x0E34\x0E35\x0E36\x0E37\x0E38\x0E39\x0E46\x0E47\x0E48\x0E49\x0E4A\x0E4B\x0E4C\t\x0E2F\x0E3F\x0E31\x0E34\x0E35\x0E36\x0E37\x0E38\x0E39\x0E46\x0E47\x0E48\x0E49\x0E4A\x0E4B\x0E4C"
+#   x0E30\x0E32\x0E33\x0E40\x0E41\x0E42\x0E43\x0E44\t\x0E30\x0E32\x0E33\x0E40\x0E41\x0E42\x0E43\x0E44" */
+const TChar KThaiChar0 = 0x21B2; // char from key-0
+const TChar KThaiChar1 = 0x0E05; // char from key-1
+const TChar KThaiChar2 = 0x0E06; // char from key-2
+const TChar KThaiChar3 = 0x0E0A; // char from key-3
+const TChar KThaiChar4 = 0x0E0E; // char from key-4
+const TChar KThaiChar5 = 0x0E14; // char from key-5
+const TChar KThaiChar6 = 0x0E19; // char from key-6
+const TChar KThaiChar7 = 0x0E1E; // char from key-7
+const TChar KThaiChar8 = 0x0E23; // char from key-8
+const TChar KThaiChar9 = 0x0E2A; // char from key-9
+const TChar KThaiChar10 = 0x0E34; // char from key-*
+const TChar KThaiChar11 = 0x0E41; // char from key-#
+
+    
 // -----------------------------------------------------------------------------
 // UT_CPcsKeyMap::NewL
 // -----------------------------------------------------------------------------
@@ -78,7 +113,19 @@
     
     
     // When instantiating keymap was moved to here, it removed a resource leak.
-    iKeyMap = CPcsKeyMap::NewL();
+    iKeyMap = C12keyKeyMap::NewL();
+    
+    
+    
+    // EUnit shows that the first call to Thai text codec's canEncode() leaks
+    // 10 cells. That's why we call canEncode() here, so when the actual test
+    // calls canEncode(), the leak no longer happens.
+    const int KThaiLanguage = 2259; // Thai Industrial Standards Institute
+    QTextCodec* thaiCodec = QTextCodec::codecForMib(KThaiLanguage);
+    if (thaiCodec)
+        {
+        thaiCodec->canEncode('a');
+        }
     }
 
 // -----------------------------------------------------------------------------
@@ -93,7 +140,7 @@
     HbKeymapFactory::instance();
 #endif
     }
-    
+
 // -----------------------------------------------------------------------------
 // UT_CPcsKeyMap::Teardown
 // -----------------------------------------------------------------------------
@@ -112,14 +159,12 @@
 void UT_CPcsKeyMap::UT_NewLL()
     {
 #if defined(USE_ORBIT_KEYMAP)
-	// Must be same as in cpcskeymap.cpp
+	// Must be same as in c12keykeymap.cpp
 	const TInt KAmountOfKeys = 12;
-	// Note that * and # keys do not have mappings in most languages
-    const TInt KAmountOfNumberKeys = 10;
 
     // Each numeric key has been mapped
     EUNIT_ASSERT_EQUALS( KAmountOfKeys, iKeyMap->iKeyMapping.count() );
-    for (TInt i = 0; i < KAmountOfNumberKeys; ++i)
+    for (TInt i = 0; i < KAmountOfKeys; ++i)
         {
         EUNIT_ASSERT( iKeyMap->iKeyMapping.at(i).length() > 0 );
         }
@@ -127,14 +172,14 @@
     }
 
 // -----------------------------------------------------------------------------
-// UT_CPcsKeyMap::UT_GetNumericKeyStringL
+// UT_CPcsKeyMap::UT_GetMappedStringL
 // -----------------------------------------------------------------------------
 //
-void UT_CPcsKeyMap::UT_GetNumericKeyStringL()
+void UT_CPcsKeyMap::UT_GetMappedStringL()
 	{
 	_LIT( KAlpha, "abjqmca" );
 	_LIT( KNumeric, "2257622" );
-	HBufC* numericBuf = iKeyMap->GetNumericKeyStringL( KAlpha, ETrue );
+	HBufC* numericBuf = iKeyMap->GetMappedStringL( KAlpha );
 	CleanupStack::PushL( numericBuf );
 	EUNIT_ASSERT_EQUALS( *numericBuf, KNumeric );
 	CleanupStack::PopAndDestroy( numericBuf );
@@ -143,7 +188,7 @@
 	
 	_LIT( KAlphaOneChar, "m" );
 	_LIT( KNumericOneChar, "6" );
-	numericBuf = iKeyMap->GetNumericKeyStringL( KAlphaOneChar, ETrue );
+	numericBuf = iKeyMap->GetMappedStringL( KAlphaOneChar );
 	CleanupStack::PushL( numericBuf );
 	EUNIT_ASSERT_EQUALS( *numericBuf, KNumericOneChar );
 	CleanupStack::PopAndDestroy( numericBuf );
@@ -151,30 +196,30 @@
 	
 
 	_LIT( KAlphaWithSpaces, "kjhgfdsa qwert " );
-	_LIT( KNumericWithSpaces, "554433720793780" );	
-	numericBuf = iKeyMap->GetNumericKeyStringL( KAlphaWithSpaces, ETrue );
+	_LIT( KNumericWithSpaces, "55443372 79378 " );
+	numericBuf = iKeyMap->GetMappedStringL( KAlphaWithSpaces );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumericWithSpaces );
     CleanupStack::PopAndDestroy( numericBuf );
     
     
     _LIT( KAlphaLongString, "adg   1230 0zbzb0 0 e56e101at 00  " );
-    _LIT( KNumericLongString, "2340001230009292000035631012800000" );
-    numericBuf = iKeyMap->GetNumericKeyStringL( KAlphaLongString, ETrue );
+    _LIT( KNumericLongString, "234   1230 092920 0 356310128 00  " );
+    numericBuf = iKeyMap->GetMappedStringL( KAlphaLongString );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumericLongString );
     CleanupStack::PopAndDestroy( numericBuf );
 	}
 
 // -----------------------------------------------------------------------------
-// UT_CPcsKeyMap::UT_GetNumericKeyStringSeparatorL
+// UT_CPcsKeyMap::UT_GetMappedStringSeparatorL
 // -----------------------------------------------------------------------------
 //
-void UT_CPcsKeyMap::UT_GetNumericKeyStringSeparatorL()
+void UT_CPcsKeyMap::UT_GetMappedStringSeparatorL()
     {
     _LIT( KAlpha, "abjqmca" );
     _LIT( KNumeric, "2257622" );
-    HBufC* numericBuf = iKeyMap->GetNumericKeyStringL( KAlpha, EFalse );
+    HBufC* numericBuf = iKeyMap->GetMappedStringL( KAlpha );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumeric );
     CleanupStack::PopAndDestroy( numericBuf );
@@ -183,7 +228,7 @@
 
     _LIT( KAlphaOneChar, "m" );
     _LIT( KNumericOneChar, "6" );
-    numericBuf = iKeyMap->GetNumericKeyStringL( KAlphaOneChar, EFalse );
+    numericBuf = iKeyMap->GetMappedStringL( KAlphaOneChar );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumericOneChar );
     CleanupStack::PopAndDestroy( numericBuf );
@@ -192,7 +237,7 @@
 
     _LIT( KAlphaWithSpaces, " kjh gfdsa qwert " );
     _LIT( KNumericWithSpaces, " 554 43372 79378 " ); // The leading space remains
-    numericBuf = iKeyMap->GetNumericKeyStringL( KAlphaWithSpaces, EFalse );
+    numericBuf = iKeyMap->GetMappedStringL( KAlphaWithSpaces );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumericWithSpaces );
     CleanupStack::PopAndDestroy( numericBuf );
@@ -200,46 +245,165 @@
 
     _LIT( KAlphaLongString, "adg   1230 0zbzb0 0 e56e101at 00  " );
     _LIT( KNumericLongString, "234   1230 092920 0 356310128 00  " );  
-    numericBuf = iKeyMap->GetNumericKeyStringL( KAlphaLongString, EFalse );
+    numericBuf = iKeyMap->GetMappedStringL( KAlphaLongString );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumericLongString );
     CleanupStack::PopAndDestroy( numericBuf );
     }
 
 // -----------------------------------------------------------------------------
-// UT_CPcsKeyMap::UT_GetNumericKeyStringWithNumbersL
+// UT_CPcsKeyMap::UT_GetMappedStringWithNumbersL
 // Source string contains numbers
 // -----------------------------------------------------------------------------
 //
-void UT_CPcsKeyMap::UT_GetNumericKeyStringWithNumbersL()
+void UT_CPcsKeyMap::UT_GetMappedStringWithNumbersL()
     {
     _LIT( KAlpha, "11098" );
     _LIT( KNumeric, "11098" );
-    HBufC* numericBuf = iKeyMap->GetNumericKeyStringL( KAlpha, EFalse );
+    HBufC* numericBuf = iKeyMap->GetMappedStringL( KAlpha );
+    CleanupStack::PushL( numericBuf );
+    EUNIT_ASSERT_EQUALS( *numericBuf, KNumeric );
+    CleanupStack::PopAndDestroy(numericBuf);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPcsKeyMap::UT_GetMappedStringWithSpecialCharactersL
+// Source string contains numbers
+// -----------------------------------------------------------------------------
+//
+void UT_CPcsKeyMap::UT_GetMappedStringWithSpecialCharactersL()
+    {
+	_LIT( KAlpha, " +g-*[#5]?t" );
+	_LIT( KNumeric, " a41afb5f18" );
+    HBufC* numericBuf = iKeyMap->GetMappedStringL( KAlpha );
     CleanupStack::PushL( numericBuf );
     EUNIT_ASSERT_EQUALS( *numericBuf, KNumeric );
     CleanupStack::PopAndDestroy(numericBuf);
     }
 
 // -----------------------------------------------------------------------------
-// UT_CPcsKeyMap::UT_GetNumericKeyStringWithSpecialCharactersL
-// Source string contains numbers
+// UT_CPcsKeyMap::UT_GetMappedStringThaiLanguageOneCharL
+// Source string contains one Thai character.
+// -----------------------------------------------------------------------------
+//
+void UT_CPcsKeyMap::UT_GetMappedStringThaiLanguageOneCharL()
+    {
+    HBufC* thaiText = HBufC::NewLC(1);
+    TPtr16 p = thaiText->Des();
+    p.Append(KThaiChar2);
+    _LIT(KNumeric, "2");
+    HBufC* numericBuf = iKeyMap->GetMappedStringL(*thaiText);
+    CleanupStack::PopAndDestroy(thaiText);
+    CleanupStack::PushL(numericBuf);
+    EUNIT_ASSERT_EQUALS(*numericBuf, KNumeric);
+    CleanupStack::PopAndDestroy(numericBuf);
+    
+    
+    QString source;
+    QChar thaiChar3(KThaiChar3);
+    QChar thaiChar5(KThaiChar5);
+    source.append(thaiChar3);
+    source.append(thaiChar5);
+    QString result = iKeyMap->GetMappedString(source);
+    EUNIT_ASSERT(result == "35");
+    }
+
+
+// -----------------------------------------------------------------------------
+// UT_CPcsKeyMap::UT_GetMappedStringThaiLanguageL
+// Source string is Thai.
 // -----------------------------------------------------------------------------
 //
-void UT_CPcsKeyMap::UT_GetNumericKeyStringWithSpecialCharactersL()
+void UT_CPcsKeyMap::UT_GetMappedStringThaiLanguageL()
+    {
+    HBufC* thaiText = HBufC::NewLC(20);
+    TPtr16 p = thaiText->Des();
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar1);
+    p.Append(KThaiChar2);
+    p.Append(KThaiChar3);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar4);
+    p.Append(KThaiChar5);
+    p.Append(KThaiChar6);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar7);
+    p.Append(KThaiChar8);
+    p.Append(KThaiChar9);
+    p.Append(KThaiChar11);
+    // For some reason, the Thai text codec indicates KThaiChar0 as invalid
+    // character, so that's why it is not used here.
+
+    _LIT(KNumeric, "123456789"); // keys * and # are skipped from result
+    HBufC* numericBuf = iKeyMap->GetMappedStringL(*thaiText);
+    CleanupStack::PopAndDestroy(thaiText);
+    CleanupStack::PushL(numericBuf);
+
+    EUNIT_ASSERT_EQUALS(*numericBuf, KNumeric);
+    CleanupStack::PopAndDestroy(numericBuf);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPcsKeyMap::UT_GetMappedStringThaiLanguageEmptyResultL
+// Input string only contains characters that map to * and # keys.
+// -----------------------------------------------------------------------------
+//
+void UT_CPcsKeyMap::UT_GetMappedStringThaiLanguageEmptyResultL()
     {
-	_LIT( KAlpha, " +g-*[#5]?t" );
-#if defined(USE_ORBIT_KEYMAP)
-	_LIT( KNumeric, " a41afb5f18" );
-#else
-    _LIT( KNumeric, " a4-a[b5]?8" );
-#endif
-    HBufC* numericBuf = iKeyMap->GetNumericKeyStringL( KAlpha, EFalse );
-    CleanupStack::PushL( numericBuf );
-    EUNIT_ASSERT_EQUALS( *numericBuf, KNumeric );
+    HBufC* thaiText = HBufC::NewLC(20);
+    TPtr16 p = thaiText->Des();
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar10);
+    p.Append(KThaiChar11);
+    p.Append(KThaiChar10);
+
+    HBufC* numericBuf = iKeyMap->GetMappedStringL(*thaiText);
+    CleanupStack::PopAndDestroy(thaiText);
+    CleanupStack::PushL(numericBuf);
+
+    EUNIT_ASSERT_EQUALS(*numericBuf, KNullDesC);
     CleanupStack::PopAndDestroy(numericBuf);
     }
 
+// -----------------------------------------------------------------------------
+// UT_CPcsKeyMap::UT_GetNumericLimitsL
+// -----------------------------------------------------------------------------
+//
+void UT_CPcsKeyMap::UT_GetNumericLimitsL()
+	{
+	QString lowerLimit;
+	QString upperLimit;
+	TInt err = iKeyMap->GetNumericLimits("123", lowerLimit, upperLimit);
+	QString expectedLowerLimit("81909218222800895");
+	QString expectedUpperLimit("82190693199511552");
+	EUNIT_ASSERT(lowerLimit == expectedLowerLimit);
+	EUNIT_ASSERT(upperLimit == expectedUpperLimit);
+	}
+
+// -----------------------------------------------------------------------------
+// UT_CPcsKeyMap::UT_GetNumericLimitsLongInputL
+// -----------------------------------------------------------------------------
+//
+void UT_CPcsKeyMap::UT_GetNumericLimitsLongInputL()
+    {
+    QString lowerLimit;
+    QString upperLimit;
+    TInt err = iKeyMap->GetNumericLimits("1234567890ab123456789", lowerLimit, upperLimit);
+    QString expectedLowerLimit("81985529205928226");
+    QString expectedUpperLimit("81985529205928228");
+    EUNIT_ASSERT(lowerLimit == expectedLowerLimit);
+    EUNIT_ASSERT(upperLimit == expectedUpperLimit);
+    }
+
 
 //  TEST TABLE
 
@@ -256,32 +420,67 @@
     SetupL, UT_NewLL, Teardown )
 
 EUNIT_TEST(
-    "GetNumericKeyString - test ",
+    "GetMappedString - test ",
+    "UT_CPcsKeyMap",
+    "GetMappedStringL",
+    "FUNCTIONALITY",
+    SetupL, UT_GetMappedStringL, Teardown )
+
+EUNIT_TEST(
+    "GetMappedString - test separator",
     "UT_CPcsKeyMap",
-    "GetNumericKeyString",
+    "GetMappedStringL",
+    "FUNCTIONALITY",
+    SetupL, UT_GetMappedStringSeparatorL, Teardown )
+
+EUNIT_TEST(
+    "GetMappedString - test numbers",
+    "UT_CPcsKeyMap",
+    "GetMappedStringL",
     "FUNCTIONALITY",
-    SetupL, UT_GetNumericKeyStringL, Teardown )
+    SetupL, UT_GetMappedStringWithNumbersL, Teardown )
+
+EUNIT_TEST(
+    "GetMappedString - test special characters",
+    "UT_CPcsKeyMap",
+    "GetMappedStringL",
+    "FUNCTIONALITY",
+    SetupL, UT_GetMappedStringWithSpecialCharactersL, Teardown )
 
 EUNIT_TEST(
-    "GetNumericKeyString - test separator",
+    "GetMappedString - Thai, test one character input",
     "UT_CPcsKeyMap",
-    "GetNumericKeyString",
+    "GetMappedStringL",
     "FUNCTIONALITY",
-    SetupL, UT_GetNumericKeyStringSeparatorL, Teardown )
+    SetupL, UT_GetMappedStringThaiLanguageOneCharL, Teardown )
+
+EUNIT_TEST(
+    "GetMappedString - test Thai language",
+    "UT_CPcsKeyMap",
+    "GetMappedStringL",
+    "FUNCTIONALITY",
+    SetupL, UT_GetMappedStringThaiLanguageL, Teardown )
 
 EUNIT_TEST(
-    "GetNumericKeyString - test numbers",
+    "GetMappedString - Thai, empty result",
     "UT_CPcsKeyMap",
-    "GetNumericKeyString",
+    "GetMappedStringL",
     "FUNCTIONALITY",
-    SetupL, UT_GetNumericKeyStringWithNumbersL, Teardown )
+    SetupL, UT_GetMappedStringThaiLanguageEmptyResultL, Teardown )
 
 EUNIT_TEST(
-    "GetNumericKeyString - test special characters",
+    "GetNumericLimits",
     "UT_CPcsKeyMap",
-    "GetNumericKeyString",
+    "GetNumericLimits",
     "FUNCTIONALITY",
-    SetupL, UT_GetNumericKeyStringWithSpecialCharactersL, Teardown )
+    SetupL, UT_GetNumericLimitsL, Teardown )
+
+EUNIT_TEST(
+    "GetNumericLimits - too long input",
+    "UT_CPcsKeyMap",
+    "GetNumericLimits",
+    "FUNCTIONALITY",
+    SetupL, UT_GetNumericLimitsLongInputL, Teardown )
 
 EUNIT_END_TEST_TABLE
 
--- a/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpcskeymap.h	Wed Jun 23 18:02:44 2010 +0300
@@ -23,15 +23,15 @@
 #include <digia/eunit/eunitmacros.h>
 
 //  FORWARD DECLARATIONS
-class CPcsKeyMap;
+class C12keyKeyMap;
 
 //  CONSTANTS
 
 //  CLASS DEFINITION
 /**
- * Tester class for CPcsKeyMap.
+ * Tester class for C12keyKeyMap.
  */
-NONSHARABLE_CLASS( UT_CPcsKeyMap ): public CEUnitTestSuiteClass
+NONSHARABLE_CLASS(UT_CPcsKeyMap): public CEUnitTestSuiteClass
     {
     public: // Constructors and destructors
 
@@ -59,14 +59,19 @@
     private: // Test methods
     
         void UT_NewLL();
-        void UT_GetNumericKeyStringL();
-        void UT_GetNumericKeyStringSeparatorL();
-        void UT_GetNumericKeyStringWithNumbersL();
-        void UT_GetNumericKeyStringWithSpecialCharactersL();
+        void UT_GetMappedStringL();
+        void UT_GetMappedStringSeparatorL();
+        void UT_GetMappedStringWithNumbersL();
+        void UT_GetMappedStringWithSpecialCharactersL();
+		void UT_GetMappedStringThaiLanguageOneCharL();
+        void UT_GetMappedStringThaiLanguageL();
+        void UT_GetMappedStringThaiLanguageEmptyResultL();
+        void UT_GetNumericLimitsL();
+		void UT_GetNumericLimitsLongInputL();
 
     private:    // Data
 
-        CPcsKeyMap* iKeyMap;
+        C12keyKeyMap* iKeyMap;
 
         EUNIT_DECLARE_TEST_TABLE;
     };
--- a/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -11,7 +11,7 @@
 *
 * Contributors:
 *
-* Description:  Unit test class for testing CPcsKeyMap
+* Description:  Unit test class for testing 12-key predictive search table
 *
 */
 
@@ -19,32 +19,25 @@
 #include "t_cpplpredictivesearchtable.h"
 #include "pltables.h"
 #include "dbsqlconstants.h"
-#include "cpcskeymap.h" // USE_ORBIT_KEYMAP macro
+#include "c12keykeymap.h"
+#include "c12keypredictivesearchtable.h"
+#include "cqwertypredictivesearchtable.h"
+#include "cpredictivesearchsettingstable.h"
+#include "cpredictivesearchsynchronizer.h"
+#include "t_predictivesearchtabledefs.h"
+#include "predictivesearchlog.h"
 
 //  SYSTEM INCLUDES
 #include <digia/eunit/eunitmacros.h>
-#include <f32file.h> // added for setup2L() 
+#include <f32file.h> // CFileMan
 
 // Used to create HbKeymapFactory singleton to get rid of resource leak
 #include <QLocale>
 #include <hbinputkeymapfactory.h>
 
 
-// Database file
-_LIT(KDBFile, "c:\\unittest.db");
-
-_LIT(KDBFileWithoutPredSearch, "c:\\contacts_without_pred_search_tables.db");
-
-const TContactItemId KTestContactId = 20;
-const TContactItemId KTestContactId2 = 85;
-const TContactItemId KTestContactId3 = 7001;
-const TContactItemId KTestContactId4 = 56030;
-
-_LIT(KTestFirstName, "123");
-_LIT(KTestLastName, "45678");
-
-// Must have same value as KMaxDigits in cpplpredictivesearchtable.cpp
-const TInt KMaxDigits = 15;
+// Must have same value as KMaxTokenLength in c12keypredictivesearchtable.cpp
+const TInt KMaxTokenLength = 15;
 
 
 const TInt KTableCount = 12;
@@ -53,6 +46,8 @@
 const quint64 KConversionError = 0xeeeeeeeeeeeeeee;
     
 
+
+
 // -----------------------------------------------------------------------------
 // UT_CPplPredictiveSearchTable::NewL
 // -----------------------------------------------------------------------------
@@ -135,17 +130,59 @@
     // If this causes KErrAlreadyExists, iDB won't be fully constructed
 	iDB.Create(KDBFile);
 
-	iTable = CPplPredictiveSearchTable::NewL(iDB);
+	iTable = C12keyPredictiveSearchTable::NewL(iDB);
+	iPredSearchQwertyTable = CQwertyPredictiveSearchTable::NewL(iDB);
+	iPredSearchSettingsTable = CPredictiveSearchSettingsTable::NewL(iDB);
 	// Create (empty) predictive search tables to DB
 	iTable->CreateTableL();
+	iPredSearchQwertyTable->CreateTableL();
+    iPredSearchSettingsTable->CreateTableL();
+    
+    iPredictiveSearchSynchronizer =
+        CPredictiveSearchSynchronizer::NewL(iDB,
+                                            *iTable,
+                                            *iPredSearchQwertyTable,
+                                            *iPredSearchSettingsTable);  
+#if defined(USE_ORBIT_KEYMAP)
+    HbKeymapFactory::instance();
+#endif
 	}
     
 // -----------------------------------------------------------------------------
-// UT_CPplPredictiveSearchTable::Setup2L
+// UT_CPplPredictiveSearchTable::SetupSyncL
+// For synchronize tables test case
+// -----------------------------------------------------------------------------
+//
+void UT_CPplPredictiveSearchTable::SetupSyncL()
+    {
+	UseSpecificDbL(KDBFileWithoutPredSearch);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPplPredictiveSearchTable::SetupSyncJust12keyExistsL
 // For synchronize tables test case
 // -----------------------------------------------------------------------------
 //
-void UT_CPplPredictiveSearchTable::Setup2L()
+void UT_CPplPredictiveSearchTable::SetupSyncJust12keyExistsL()
+    {
+	UseSpecificDbL(KDBFile12keyButNoQwerty);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPplPredictiveSearchTable::SetupLanguageChangesL
+// For UT_LanguageChangesL case
+// -----------------------------------------------------------------------------
+//
+void UT_CPplPredictiveSearchTable::SetupLanguageChangesL()
+    {
+	UseSpecificDbL(KDBFileOtherLanguage);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPplPredictiveSearchTable::UseSpecificDbL
+// -----------------------------------------------------------------------------
+//
+void UT_CPplPredictiveSearchTable::UseSpecificDbL(const TDesC& aDbFile)
     {
     // Copy an existing DB file that does not contain predictive search tables
     // to a DB file that will be used in test.
@@ -153,15 +190,23 @@
     User::LeaveIfError(fs.Connect());
     CFileMan* fm = CFileMan::NewL(fs);
     CleanupStack::PushL(fm);
-    
-    _LIT(KSourceFile, "c:\\Copy of contacts_without_pred_search_tables.db");
-    User::LeaveIfError(fm->Copy(KSourceFile, KDBFileWithoutPredSearch));
+
+    User::LeaveIfError(fm->Copy(aDbFile, KDBFile));
     CleanupStack::PopAndDestroy(fm);
     fs.Close();
     
     
-    User::LeaveIfError(iDB.Open(KDBFileWithoutPredSearch));
-    iTable = CPplPredictiveSearchTable::NewL(iDB);
+    User::LeaveIfError(iDB.Open(KDBFile));
+
+    iTable = C12keyPredictiveSearchTable::NewL(iDB);
+    iPredSearchQwertyTable = CQwertyPredictiveSearchTable::NewL(iDB);
+	iPredSearchSettingsTable = CPredictiveSearchSettingsTable::NewL(iDB);
+
+    iPredictiveSearchSynchronizer =
+        CPredictiveSearchSynchronizer::NewL(iDB,
+                                            *iTable,
+                                            *iPredSearchQwertyTable,
+                                            *iPredSearchSettingsTable);
     }
 
 // -----------------------------------------------------------------------------
@@ -170,8 +215,17 @@
 //
 void UT_CPplPredictiveSearchTable::Teardown()
     {
+    delete iPredictiveSearchSynchronizer;
+    iPredictiveSearchSynchronizer = NULL;
+
     delete iTable;
 	iTable = NULL;
+	
+	delete iPredSearchQwertyTable;
+	iPredSearchQwertyTable = NULL;
+
+	delete iPredSearchSettingsTable;
+	iPredSearchSettingsTable = NULL;
 
 	iDB.Close(); // Must close DB before it can be deleted
 	RSqlDatabase::Delete(KDBFile);
@@ -180,7 +234,7 @@
 
 // TEST CASES
 
-// Dummy case to see if the first case always results a resource leak
+// Dummy case to see if the first case always results a resource leak (2 heap cells)
 void UT_CPplPredictiveSearchTable::UT_DummyL()
     {    
     // The first test case that writes to tables, seems to cause resource leak
@@ -196,7 +250,7 @@
     {
     CheckItemCountL(); // all empty
     AddContactL(KTestFirstName, KTestLastName, KTestContactId);
-    CheckItemCountL(0, 1, 0, 0, 1); // table 1 and 4 have one entry
+    CheckItemCountL(0, 1, 0, 0, 1); // Tables 1 and 4 have one entry
     }
 
 // -----------------------------------------------------------------------------
@@ -242,6 +296,17 @@
 	}
 
 // -----------------------------------------------------------------------------
+// UT_CPplPredictiveSearchTable::UT_CreateInDbWithHashAndStarL
+// -----------------------------------------------------------------------------
+//
+void UT_CPplPredictiveSearchTable::UT_CreateInDbWithHashAndStarL()
+    {
+	AddContactL(_L(" # * +"), _L(" +*# **"), KTestContactId);
+	AddContactL(_L("*"), _L("+355"), KTestContactId2); 
+    CheckItemCountL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1);
+	}
+
+// -----------------------------------------------------------------------------
 // UT_CPplPredictiveSearchTable::UT_UpdateLL
 // Update an existing contact
 // -----------------------------------------------------------------------------
@@ -503,7 +568,7 @@
     }
 
 // -----------------------------------------------------------------------------
-// UT_CPplPredictiveSearchTable::UT_DeleteLL
+// UT_CPplPredictiveSearchTable::UT_DeleteContactsL
 // Delete contacts one-by-one from the table that has multiple contacts
 // -----------------------------------------------------------------------------
 //
@@ -614,10 +679,9 @@
     // Create DB, but do not create pred search table in it
     iDB.Create(KDBFile);
 
-    TInt err = CPplContactItemManager_DoesPredSearchTableExistL();
-    EUNIT_ASSERT_EQUALS(-311, err);
+    EUNIT_ASSERT_EQUALS(EFalse,
+        iPredictiveSearchSynchronizer->CheckIfPredSearchTableExistsL(KSqlContactPredSearchTable0));
 
-    
     iDB.Close(); // Must close DB before it can be deleted
     RSqlDatabase::Delete(KDBFile);
     }
@@ -629,8 +693,8 @@
 //
 void UT_CPplPredictiveSearchTable::UT_CheckIfTableExists2L()
     {
-	TInt err = CPplContactItemManager_DoesPredSearchTableExistL();
-	EUNIT_ASSERT_EQUALS(KErrNone, err);
+    EUNIT_ASSERT_EQUALS(ETrue,
+        iPredictiveSearchSynchronizer->CheckIfPredSearchTableExistsL(KSqlContactPredSearchTable0));
     }
 
 
@@ -640,102 +704,32 @@
 // search tables!
 // If Orbit keymap is used, this test case leaks resources,
 // otherwise it does not leak.
-
-/* Create DB and other tables, except pred search table. Add some contacts to DB
-   but do not write them to (non-existing) pred search table.
-   
-   Or just create DB and all tables, then add contacts, and delete pred.search
-   tables.
-   Close database and open it, to see that pred search tables are created. */
 void UT_CPplPredictiveSearchTable::UT_SynchronizeTableL()
     {
-///////// copied from CPplContactItemManager::SynchronizePredSearchTableL ////////
-    iTable->CreateTableL();
-    _LIT(KSelectAllContactsFormat, "SELECT %S,%S,%S FROM %S;");
-    TInt bufSize = KSelectAllContactsFormat().Length() +
-                   KContactId().Length() +
-                   KContactFirstName().Length() +
-                   KContactCompanyName().Length() +
-                   KSqlContactTableName().Length();
-    HBufC* sqlStatement = HBufC::NewLC(bufSize);
-    sqlStatement->Des().AppendFormat(KSelectAllContactsFormat,
-        &KContactId,
-        &KContactFirstName,
-        &KContactLastName,
-        &KSqlContactTableName);
-
-    RSqlStatement stmnt;
-    CleanupClosePushL(stmnt);
-    stmnt.PrepareL(iDB, *sqlStatement);
-
-    const TInt KContactIdIndex = 0;
-    const TInt KFirstNameIndex = 1;
-    const TInt KLastNameIndex = 2;
-    TInt err(KErrNone);
-    while ((err = stmnt.Next()) == KSqlAtRow)
-        {
-        TInt id = KUidContactCardValue;
-        TUid uid;
-        uid.iUid = id;
-        CContactItem* contact = CContactItem::NewLC(uid);
-        contact->SetId(stmnt.ColumnInt(KContactIdIndex));
+	iPredictiveSearchSynchronizer->SynchronizeTablesL();
+    }
 
-        // If first name exists, write it to contact item
-        TPtrC firstName;
-        if (stmnt.ColumnText(KFirstNameIndex, firstName) == KErrNone)
-            {
-            CContactItemField* field =
-                CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
-            CContactTextField* textfield = field->TextStorage();
-            textfield->SetTextL(firstName);
-            contact->AddFieldL(*field); // Takes ownership
-            CleanupStack::Pop(field);
-            }
-
-        TPtrC lastName;
-        if (stmnt.ColumnText(KLastNameIndex, lastName) == KErrNone)
-            {
-            CContactItemField* field =
-                CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
-            CContactTextField* textfield = field->TextStorage();
-            textfield->SetTextL(lastName);
-            contact->AddFieldL(*field); // Takes ownership
-            CleanupStack::Pop(field);
-            }
-        iTable->CreateInDbL(*contact);
-        CleanupStack::PopAndDestroy(contact);
-        }
-
-    // Leave if we didn't complete going through the results properly
-    if (err != KSqlAtEnd)
-        {
-        User::Leave(err);
-        }
-    CleanupStack::PopAndDestroy(&stmnt);
-    CleanupStack::PopAndDestroy(sqlStatement);    
-///////// end - copied from CPplContactItemManager::SynchronizePredSearchTableL //////////
-    
-
-    delete iTable;
-    iTable = NULL;
-	iDB.Close(); // Must close DB before it can be deleted
-
-	RSqlDatabase::Delete(KDBFileWithoutPredSearch);
-    }
+void UT_CPplPredictiveSearchTable::UT_SynchronizeTableJust12keyExistsL()
+	{
+	iPredictiveSearchSynchronizer->SynchronizeTablesL();
+	}
 
 void UT_CPplPredictiveSearchTable::UT_DeleteTablesL()
 	{
 	// Delete tables
-	CPplContactItemManager_DeletePredSearchTablesL();
-
+	iPredictiveSearchSynchronizer->DeletePredSearchTablesL();
 
 	// Check tables have been deleted
-	TInt err = CPplContactItemManager_DoesPredSearchTableExistL();
-	EUNIT_ASSERT_EQUALS(-311, err);
-
+	EUNIT_ASSERT_EQUALS(EFalse,
+        iPredictiveSearchSynchronizer->CheckIfPredSearchTableExistsL(KSqlContactPredSearchTable0));
 
 	// Try to delete tables when they do not exist
-	CPplContactItemManager_DeletePredSearchTablesL();
+	iPredictiveSearchSynchronizer->DeletePredSearchTablesL();
+	}
+
+void UT_CPplPredictiveSearchTable::UT_LanguageChangesL()
+	{
+	iPredictiveSearchSynchronizer->SynchronizeTablesL();
 	}
 
 void UT_CPplPredictiveSearchTable::UT_TokenizeNamesL()
@@ -744,24 +738,36 @@
     _LIT(KLastNames, "12355 987 402");
     HBufC* fn = KFirstNames().AllocLC();
     HBufC* ln = KLastNames().AllocLC();
+    QStringList emptyList;
 
     // This constant must have same value as declared in cpplpredictivesearchtable.cpp
     const TInt KMaxTokens = 4; 
-    QStringList tokens = iTable->GetNumericTokens(fn, ln);
+    QStringList tokens = iTable->GetTokens(emptyList, fn, ln);
     EUNIT_ASSERT_EQUALS(KMaxTokens, tokens.count());
     tokens.clear();
         
-    tokens = iTable->GetNumericTokens(NULL, ln);
+    tokens = iTable->GetTokens(emptyList, NULL, ln);
     EUNIT_ASSERT_EQUALS(3, tokens.count());
     tokens.clear();
     
-    tokens = iTable->GetNumericTokens(fn, NULL);
+    tokens = iTable->GetTokens(emptyList, fn, NULL);
     EUNIT_ASSERT_EQUALS(4, tokens.count());
     tokens.clear();
 
-    tokens = iTable->GetNumericTokens(NULL, NULL);
+    tokens = iTable->GetTokens(emptyList, NULL, NULL);
     EUNIT_ASSERT_EQUALS(0, tokens.count());
     tokens.clear();
+
+    QStringList mailList;
+    mailList << "mail.addr1";
+    mailList << "mail.addr2";
+    tokens = iTable->GetTokens(mailList, NULL, NULL);
+    EUNIT_ASSERT_EQUALS(2, tokens.count());
+    tokens.clear();
+    
+    tokens = iTable->GetTokens(mailList, fn, ln);
+    EUNIT_ASSERT_EQUALS(4, tokens.count());
+    tokens.clear();
     
     CleanupStack::PopAndDestroy(ln);
     CleanupStack::PopAndDestroy(fn);
@@ -954,7 +960,7 @@
 		_LIT(KSearchFormat, "SELECT contact_id FROM %S WHERE \
 (nbr>%ld AND nbr<%ld) OR (nbr2>%ld AND nbr2<%ld) OR (nbr3>%ld AND nbr3<%ld) OR (nbr4>%ld AND nbr4<%ld);");
 		TInt KNbrColumns = 4;
-		TInt KSpaceForLimits = KNbrColumns * 2 * (KMaxDigits + 2); // Two extra for decimal representation of max 15 hex digits
+		TInt KSpaceForLimits = KNbrColumns * 2 * (KMaxTokenLength + 2); // Two extra for decimal representation of max 15 hex digits
 		select = HBufC::NewLC(KSearchFormat().Length() +
 							  KSqlContactPredSearchTable11().Length() +
 							  KSpaceForLimits);
@@ -1032,12 +1038,12 @@
 TInt64 UT_CPplPredictiveSearchTable::ConvertToNbrL(const TDesC& aString,
 												   TChar aPadChar) const
 	{
-	HBufC* nbrBuffer = HBufC::NewLC(KMaxDigits);
-	TPtrC p = aString.Left(KMaxDigits);
+	HBufC* nbrBuffer = HBufC::NewLC(KMaxTokenLength);
+	TPtrC p = aString.Left(KMaxTokenLength);
 	TPtr nbrPtr = nbrBuffer->Des();
 	nbrPtr.Append(p);
-	// Append pad chars until length is KMaxDigits
-	while (nbrPtr.Length() < KMaxDigits)
+	// Append pad chars until length is KMaxTokenLength
+	while (nbrPtr.Length() < KMaxTokenLength)
 		{
 		nbrPtr.Append(aPadChar);
 		}	
@@ -1052,64 +1058,6 @@
 	return nbrValue;
 	}
 
-// This function has code copied from CPplContactItemManager::DoesPredSearchTableExistL
-TInt UT_CPplPredictiveSearchTable::CPplContactItemManager_DoesPredSearchTableExistL()
-	{
-	// SQLite does not have SHOW TABLES command, so try to search from
-    // predictive search table.
-    _LIT(KCheckIfTableExistsFormat, "SELECT %S FROM %S;");
-    TInt bufSize = KCheckIfTableExistsFormat().Length() +
-                   KPredSearchContactId().Length() +
-                   KSqlContactPredSearchTable11().Length();
-    HBufC* sqlStatement = HBufC::NewLC(bufSize);
-    sqlStatement->Des().AppendFormat(KCheckIfTableExistsFormat,
-        &KPredSearchContactId,
-        &KSqlContactPredSearchTable0);
-
-    RSqlStatement stmnt;
-    CleanupClosePushL(stmnt);
-    // If table does not exist, leaves with -311
-    // If table exists, does not leave
-    TRAPD(err, stmnt.PrepareL(iDB, *sqlStatement));    
-    CleanupStack::PopAndDestroy(&stmnt);
-    CleanupStack::PopAndDestroy(sqlStatement);
-	return err;
-	}
-
-// This function has code copied from CPplContactItemManager::DeletePredSearchTablesL
-void UT_CPplPredictiveSearchTable::CPplContactItemManager_DeletePredSearchTablesL()
-	{
-    const TDesC* KTableNames[KTableCount] =
-        {
-        &KSqlContactPredSearchTable0,
-        &KSqlContactPredSearchTable1,
-        &KSqlContactPredSearchTable2,
-        &KSqlContactPredSearchTable3,
-        &KSqlContactPredSearchTable4,
-        &KSqlContactPredSearchTable5,
-        &KSqlContactPredSearchTable6,
-        &KSqlContactPredSearchTable7,
-        &KSqlContactPredSearchTable8,
-        &KSqlContactPredSearchTable9,
-        &KSqlContactPredSearchTable10,
-        &KSqlContactPredSearchTable11
-        };
-
-	// IF EXISTS suppresses error that would occur if table does not exist
-	_LIT(KDropTable, "DROP TABLE IF EXISTS %S;");
-    for (TInt i = 0; i < KTableCount; ++i)
-        {
-        HBufC* dropTableCommand = HBufC::NewLC(KDropTable().Length() +
-            // All table names are of same length
-            KTableNames[i]->Length());
-        TPtr ptr = dropTableCommand->Des();
-        ptr.Format(KDropTable, KTableNames[i]);
-
-		User::LeaveIfError(iDB.Exec(*dropTableCommand));
-        CleanupStack::PopAndDestroy(dropTableCommand);
-        }
-	}
-
 
 //  TEST TABLE
 
@@ -1140,6 +1088,13 @@
     SetupL, UT_CreateInDbManyContactsL, Teardown )
 
 EUNIT_TEST(
+	"CreateInDbL - test contacts with *,+,# characters",
+    "UT_CPplPredictiveSearchTable",
+    "CreateInDbL",
+    "FUNCTIONALITY",
+    SetupL, UT_CreateInDbWithHashAndStarL, Teardown )
+	
+EUNIT_TEST(
     "UpdateL - test updating FN",
     "UT_CPplPredictiveSearchTable",
     "UpdateL",
@@ -1191,32 +1146,46 @@
 EUNIT_TEST(
     "Check if predictive search table exists (table does not exist)",
     "UT_CPplPredictiveSearchTable",
-    "",
+    "DoesPredSearchTableExistL",
     "FUNCTIONALITY",
     SetupL, UT_CheckIfTableExistsL, Teardown )
 
 EUNIT_TEST(
     "Check if predictive search table exists (table exists)",
     "UT_CPplPredictiveSearchTable",
-    "",
+    "DoesPredSearchTableExistL",
     "FUNCTIONALITY",
     SetupL, UT_CheckIfTableExists2L, Teardown )
 
 EUNIT_TEST(
-    "Synchronize table",
+    "Synchronize DB w/o pred.search tables",
     "UT_CPplPredictiveSearchTable",
-    "",
+    "CreatePredSearchTablesL",
     "FUNCTIONALITY",
-    Setup2L, UT_SynchronizeTableL, Teardown )
+    SetupSyncL, UT_SynchronizeTableL, Teardown )
+
+EUNIT_TEST(
+    "Synchronize DB with 12-key, but w/o QWERTY tables",
+    "UT_CPplPredictiveSearchTable",
+    "CreatePredSearchTablesL",
+    "FUNCTIONALITY",
+    SetupSyncJust12keyExistsL, UT_SynchronizeTableJust12keyExistsL, Teardown )
 
 EUNIT_TEST(
     "Delete predictive search tables",
     "UT_CPplPredictiveSearchTable",
-    "CPplContactItemManager::DeletePredSearchTablesL",
+    "DeletePredSearchTablesL",
     "FUNCTIONALITY",
     SetupL, UT_DeleteTablesL, Teardown )
 
 EUNIT_TEST(
+	"Language changes: re-create QWERTY tables",
+    "UT_CPplPredictiveSearchTable",
+    "DeletePredSearchTablesL",
+    "FUNCTIONALITY",
+    SetupLanguageChangesL, UT_LanguageChangesL, Teardown )
+
+EUNIT_TEST(
     "Tokenize names",
     "UT_CPplPredictiveSearchTable",
     "TokenizeNames",
--- a/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpplpredictivesearchtable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -11,7 +11,7 @@
 *
 * Contributors:
 *
-* Description: Unit test class for character to key mappings
+* Description: Unit test class for testing 12-key predictive search table
 *
 */
 
@@ -25,13 +25,19 @@
 #include "cntdef.h" // TContactItemId
 
 //  FORWARD DECLARATIONS
-class CPplPredictiveSearchTable;
+class CPplPredictiveSearchTableBase;
+class C12keyPredictiveSearchTable;
+class CQwertyPredictiveSearchTable;
+class CPredictiveSearchSettingsTable;
+class CPredictiveSearchSynchronizer;
+class CContactItem;
+
 
 //  CONSTANTS
 
 //  CLASS DEFINITION
 /**
- * Tester class for CPcsKeyMap.
+ * Tester class for C12keyPredictiveSearchTable.
  */
 NONSHARABLE_CLASS( UT_CPplPredictiveSearchTable ): public CEUnitTestSuiteClass
     {
@@ -56,7 +62,10 @@
     private: // Test case setup and teardown
 
         void SetupL();
-        void Setup2L();
+        void SetupSyncL();
+		void SetupSyncJust12keyExistsL();
+		void SetupLanguageChangesL();
+		void UseSpecificDbL(const TDesC& aDbFile);
         void Teardown();
 
     private: // Test functions
@@ -64,6 +73,7 @@
 		void UT_DummyL();
         void UT_CreateInDbLL();
         void UT_CreateInDbManyContactsL();
+		void UT_CreateInDbWithHashAndStarL();
         void UT_UpdateLL();
         void UT_UpdateLBothFieldsL();
         void UT_SearchL();
@@ -74,7 +84,9 @@
         void UT_CheckIfTableExistsL();
         void UT_CheckIfTableExists2L();
         void UT_SynchronizeTableL();
+		void UT_SynchronizeTableJust12keyExistsL();
 		void UT_DeleteTablesL();
+		void UT_LanguageChangesL();
         void UT_TokenizeNamesL();
 		void UT_WriteToDbL();
 		void UT_ConvertToHexL();
@@ -114,12 +126,12 @@
 		TInt64 UpperLimitL(const TDesC& aString) const;
 		TInt64 ConvertToNbrL(const TDesC& aString, TChar aPadChar) const;
 
-		TInt CPplContactItemManager_DoesPredSearchTableExistL();
-		void CPplContactItemManager_DeletePredSearchTablesL();
-
     private:    // Data
 
-        CPplPredictiveSearchTable* iTable;
+		C12keyPredictiveSearchTable* iTable; // Owned
+		CQwertyPredictiveSearchTable* iPredSearchQwertyTable; // Owned 
+		CPredictiveSearchSettingsTable* iPredSearchSettingsTable; // Owned
+		CPredictiveSearchSynchronizer* iPredictiveSearchSynchronizer; // Owned
         
         RSqlDatabase iDB;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpredictivesearchsettingstable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,152 @@
+/*
+* 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:  Unit test class for testing 12-key predictive search table
+*
+*/
+
+//  INTERNAL INCLUDES
+#include "t_cpredictivesearchsettingstable.h"
+#include "cpredictivesearchsettingstable.h"
+//#include "dbsqlconstants.h"
+#include "t_predictivesearchtabledefs.h"
+
+//  SYSTEM INCLUDES
+#include <digia/eunit/eunitmacros.h>
+
+// Used to create HbKeymapFactory singleton to get rid of resource leak
+#include <QLocale>
+#include <hbinputkeymapfactory.h>
+    
+
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::NewL
+// -----------------------------------------------------------------------------
+//
+UT_CPredictiveSearchSettingsTable* UT_CPredictiveSearchSettingsTable::NewL()
+    {
+    UT_CPredictiveSearchSettingsTable* self =
+		UT_CPredictiveSearchSettingsTable::NewLC();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::NewLC
+// -----------------------------------------------------------------------------
+//
+UT_CPredictiveSearchSettingsTable* UT_CPredictiveSearchSettingsTable::NewLC()
+    {
+    UT_CPredictiveSearchSettingsTable* self =
+		new ( ELeave ) UT_CPredictiveSearchSettingsTable();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::~UT_CPredictiveSearchSettingsTable
+// -----------------------------------------------------------------------------
+//
+UT_CPredictiveSearchSettingsTable::~UT_CPredictiveSearchSettingsTable()
+    {
+    delete iTable;
+    iTable = NULL;
+    
+    iDB.Close(); // Must close DB before it can be deleted
+    RSqlDatabase::Delete(KDBFile);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::UT_CPredictiveSearchSettingsTable
+// -----------------------------------------------------------------------------
+//
+UT_CPredictiveSearchSettingsTable::UT_CPredictiveSearchSettingsTable()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::ConstructL
+// -----------------------------------------------------------------------------
+//
+void UT_CPredictiveSearchSettingsTable::ConstructL()
+    {
+    // The ConstructL from the base class CEUnitTestSuiteClass must be called.
+    // It generates the test case table.
+    CEUnitTestSuiteClass::ConstructL();
+    }
+    
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::SetupL
+// Must start with an empty DB file for each test case
+// -----------------------------------------------------------------------------
+//
+void UT_CPredictiveSearchSettingsTable::SetupL()
+    {
+    // Ignore error
+	RSqlDatabase::Delete(KDBFile);
+    // If this causes KErrAlreadyExists, iDB won't be fully constructed
+	iDB.Create(KDBFile);
+
+	iTable = CPredictiveSearchSettingsTable::NewL(iDB);
+	// Create (empty) predictive search tables to DB
+	iTable->CreateTableL();
+	}
+    
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::Teardown
+// -----------------------------------------------------------------------------
+//
+void UT_CPredictiveSearchSettingsTable::Teardown()
+    {
+    delete iTable;
+	iTable = NULL;
+
+	iDB.Close(); // Must close DB before it can be deleted
+	RSqlDatabase::Delete(KDBFile);
+    }
+
+
+// TEST CASES
+
+// -----------------------------------------------------------------------------
+// UT_CPredictiveSearchSettingsTable::UT_CreateTableLL
+// -----------------------------------------------------------------------------
+//
+void UT_CPredictiveSearchSettingsTable::UT_CreateTableLL()
+    {
+	// Check that when starting w/o DB file, the settings table is created and
+	// filled correctly.
+    enum QLocale::Language currLang = iTable->GetCurrentLanguageL();
+    enum QLocale::Language storedLang = iTable->ReadStoredLanguageL();
+    EUNIT_ASSERT_EQUALS(currLang, storedLang);
+    }
+
+    
+//  TEST TABLE
+
+EUNIT_BEGIN_TEST_TABLE(
+    UT_CPredictiveSearchSettingsTable,
+    "UT_CPredictiveSearchSettingsTable",
+    "UNIT" )
+        
+EUNIT_TEST(
+    "CreateInDbL - test",
+    "UT_CPredictiveSearchSettingsTable",
+    "CreateTableL",
+    "FUNCTIONALITY",
+    SetupL, UT_CreateTableLL, Teardown )
+
+EUNIT_END_TEST_TABLE
+
+//  END OF FILE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cpredictivesearchsettingstable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,75 @@
+/*
+* 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: Unit test class for QWERTY tables
+*
+*/
+
+#ifndef __UT_CPREDICTIVESEARCHSETTINGSTABLE_H__
+#define __UT_CPREDICTIVESEARCHSETTINGSTABLE_H__
+
+//  EXTERNAL INCLUDES
+#include <digia/eunit/ceunittestsuiteclass.h>
+#include <digia/eunit/eunitmacros.h>
+#include <sqldb.h>
+
+//  FORWARD DECLARATIONS
+class CPredictiveSearchSettingsTable;
+
+//  CONSTANTS
+
+//  CLASS DEFINITION
+/**
+ * Tester class for CPredictiveSearchSettingsTable.
+ */
+NONSHARABLE_CLASS( UT_CPredictiveSearchSettingsTable ): public CEUnitTestSuiteClass
+    {
+    public: // Constructors and destructors
+
+        /**
+         * Two phase construction
+         */
+        static UT_CPredictiveSearchSettingsTable* NewL();
+        static UT_CPredictiveSearchSettingsTable* NewLC();
+        
+        /**
+         * Destructor
+         */
+        ~UT_CPredictiveSearchSettingsTable();
+
+    private: // Constructors
+
+        UT_CPredictiveSearchSettingsTable();
+        void ConstructL();
+        
+    private: // Test case setup and teardown
+
+        void SetupL();
+        void Teardown();
+
+    private: // Test functions
+
+        void UT_CreateTableLL();
+
+    private:    // Data
+
+		CPredictiveSearchSettingsTable* iTable;
+        
+        RSqlDatabase iDB;
+
+        EUNIT_DECLARE_TEST_TABLE;
+    };
+
+#endif      //  __UT_CPREDICTIVESEARCHSETTINGSTABLE_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,242 @@
+/*
+* 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:  Unit test class for testing CQwertyKeyMap
+*
+*/
+
+// INTERNAL INCLUDES
+#include "t_cqwertykeymap.h"
+#include "cqwertykeymap.h"
+#include <QString>
+
+// SYSTEM INCLUDES
+#include <digia/eunit/eunitmacros.h>
+#if defined(USE_ORBIT_KEYMAP)
+#include <hbinputkeymapfactory.h>
+#endif
+
+    
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::NewL
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyKeyMap* UT_CQwertyKeyMap::NewL()
+    {
+    UT_CQwertyKeyMap* self = UT_CQwertyKeyMap::NewLC();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::NewLC
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyKeyMap* UT_CQwertyKeyMap::NewLC()
+    {
+    UT_CQwertyKeyMap* self = new (ELeave) UT_CQwertyKeyMap();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::~UT_CQwertyKeyMap
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyKeyMap::~UT_CQwertyKeyMap()
+    {
+    delete iKeyMap;
+    iKeyMap = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::UT_CQwertyKeyMap
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyKeyMap::UT_CQwertyKeyMap()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::ConstructL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::ConstructL()
+    {
+    // The ConstructL from the base class CEUnitTestSuiteClass must be called.
+    // It generates the test case table.
+    CEUnitTestSuiteClass::ConstructL();
+    
+    
+    // When instantiating keymap was moved to here, it removed a resource leak.
+    iKeyMap = CQwertyKeyMap::NewL();
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::SetupL
+// -----------------------------------------------------------------------------
+//
+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
+    }
+    
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::Teardown
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::Teardown()
+    {
+    }
+
+
+// TEST CASES
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::UT_NewLL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::UT_NewLL()
+    {
+#if defined(USE_ORBIT_KEYMAP)
+    // Check each key has been mapped
+	EUNIT_ASSERT_EQUALS(CQwertyKeyMap::EAmountOfKeysInQwertyKeypad,
+					    iKeyMap->iKeyMapping.count());
+
+	const TInt KAmountOfKeysInUse = 32;
+	// Note: depending on the language, the keymaps have 32..36 keys.
+	// So far no language has the full 44 keys.
+    for (TInt i = 0; i < KAmountOfKeysInUse; ++i)
+        {
+        EUNIT_ASSERT(iKeyMap->iKeyMapping.at(i).length() > 0);
+        }
+#endif
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::UT_GetMappedStringL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::UT_GetMappedStringL()
+	{
+	_LIT(KAlpha, "AbCQWe");
+	_LIT(KNumeric, "abcqwe");
+	HBufC* numericBuf = iKeyMap->GetMappedStringL( KAlpha );
+	CleanupStack::PushL( numericBuf );
+	EUNIT_ASSERT_EQUALS( *numericBuf, KNumeric );
+	CleanupStack::PopAndDestroy( numericBuf );
+	numericBuf = NULL;
+	}
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::UT_GetNumericLimitsL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::UT_GetNumericLimitsL()
+    {
+    QString lowerLimit;
+    QString upperLimit;
+    TInt err = iKeyMap->GetNumericLimits("we", lowerLimit, upperLimit);
+    QString expectedLowerLimit("18577348462903295");
+    QString expectedUpperLimit("18858823439613952");
+    EUNIT_ASSERT(lowerLimit == expectedLowerLimit);
+    EUNIT_ASSERT(upperLimit == expectedUpperLimit);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::UT_GetNumericLimitsBeginsByFirstKeyL
+// Input string begins by the first key (key Q)
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::UT_GetNumericLimitsBeginsByFirstKeyL()
+    {
+    QString lowerLimit;
+    QString upperLimit;
+    TInt err = iKeyMap->GetNumericLimits("qwe", lowerLimit, upperLimit);
+    QString expectedLowerLimit("290271069732863");
+    QString expectedUpperLimit("294669116243968");
+    EUNIT_ASSERT(lowerLimit == expectedLowerLimit);
+    EUNIT_ASSERT(upperLimit == expectedUpperLimit);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyKeyMap::UT_GetNumericLimitsLongValueL
+// Input string has more than maximum characters
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyKeyMap::UT_GetNumericLimitsLongValueL()
+    {
+    QString lowerLimit;
+    QString upperLimit;
+    // "aaqqsswwddee" => "ee" is ignored, rest are as binary:
+    // 001010 001010 000000 000000 001011 001011 000001 000001 001100 001100
+    // =
+    // 0010 1000 1010 0000 0000 0000 0010 1100 1011 0000 0100 0001 0011 0000 1100
+    // as hex = 28A0002CB04130C, as decimal = 182958746857902860
+    TInt err = iKeyMap->GetNumericLimits("aaqqsswwddee", lowerLimit, upperLimit);
+    QString expectedLowerLimit("182958746857902859");
+    QString expectedUpperLimit("182958746857902861");
+    EUNIT_ASSERT(lowerLimit == expectedLowerLimit);
+    EUNIT_ASSERT(upperLimit == expectedUpperLimit);
+    }
+    
+//  TEST TABLE
+
+EUNIT_BEGIN_TEST_TABLE(
+    UT_CQwertyKeyMap,
+    "UT_CQwertyKeyMap",
+    "UNIT" )
+
+EUNIT_TEST(
+    "NewL - test ",
+    "UT_CQwertyKeyMap",
+    "NewL",
+    "FUNCTIONALITY",
+    SetupL, UT_NewLL, Teardown )
+
+EUNIT_TEST(
+    "GetMappedString - test ",
+    "UT_CQwertyKeyMap",
+    "GetMappedStringL",
+    "FUNCTIONALITY",
+    SetupL, UT_GetMappedStringL, Teardown )
+
+EUNIT_TEST(
+    "GetNumericLimits",
+    "UT_CQwertyKeyMap",
+    "GetNumericLimits",
+    "FUNCTIONALITY",
+    SetupL, UT_GetNumericLimitsL, Teardown )
+
+EUNIT_TEST(
+    "GetNumericLimits - begins by first key",
+    "UT_CQwertyKeyMap",
+    "GetNumericLimits",
+    "FUNCTIONALITY",
+    SetupL, UT_GetNumericLimitsBeginsByFirstKeyL, Teardown )
+    
+EUNIT_TEST(
+    "GetNumericLimits - long input",
+    "UT_CQwertyKeyMap",
+    "GetNumericLimits",
+    "FUNCTIONALITY",
+    SetupL, UT_GetNumericLimitsLongValueL, Teardown )
+    
+EUNIT_END_TEST_TABLE
+
+//  END OF FILE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertykeymap.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,76 @@
+/*
+* 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: Unit test class for character to key mappings
+*
+*/
+
+#ifndef __UT_CQWERTYKEYMAP_H__
+#define __UT_CQWERTYKEYMAP_H__
+
+//  EXTERNAL INCLUDES
+#include <digia/eunit/ceunittestsuiteclass.h>
+#include <digia/eunit/eunitmacros.h>
+
+//  FORWARD DECLARATIONS
+class CQwertyKeyMap;
+
+//  CONSTANTS
+
+//  CLASS DEFINITION
+/**
+ * Tester class for CQwertyKeyMap.
+ */
+NONSHARABLE_CLASS(UT_CQwertyKeyMap): public CEUnitTestSuiteClass
+    {
+    public: // Constructors and destructors
+
+        /**
+         * Two phase construction
+         */
+        static UT_CQwertyKeyMap* NewL();
+        static UT_CQwertyKeyMap* NewLC();
+        
+        /**
+         * Destructor
+         */
+        ~UT_CQwertyKeyMap();
+
+    private: // Constructors
+
+        UT_CQwertyKeyMap();
+        void ConstructL();
+        
+    private: // Test case setup and teardown
+
+        void SetupL();
+        void Teardown();
+
+    private: // Test methods
+    
+        void UT_NewLL();
+        void UT_GetMappedStringL();
+		void UT_GetNumericLimitsL();
+		void UT_GetNumericLimitsBeginsByFirstKeyL();
+		void UT_GetNumericLimitsLongValueL();
+
+    private:    // Data
+
+        CQwertyKeyMap* iKeyMap;
+
+        EUNIT_DECLARE_TEST_TABLE;
+    };
+
+#endif      //  __UT_CQWERTYKEYMAP_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,403 @@
+/*
+* 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:  Unit test class for testing 12-key predictive search table
+*
+*/
+
+//  INTERNAL INCLUDES
+#include "t_cqwertypredictivesearchtable.h"
+#include "cqwertypredictivesearchtable.h"
+#include "dbsqlconstants.h"
+#include "cqwertykeymap.h"
+#include "t_predictivesearchtabledefs.h"
+
+//  SYSTEM INCLUDES
+#include <digia/eunit/eunitmacros.h>
+
+// Used to create HbKeymapFactory singleton to get rid of resource leak
+#include <QLocale>
+#include <hbinputkeymapfactory.h>
+    
+
+_LIT(KFirstName, "qfirstname r");
+_LIT(KFirstName2, "otherFirstName");
+_LIT(KLastName, "elastname");
+_LIT(KLastName2, "anotherLastName");
+_LIT(KMail, "tmail1");
+_LIT(KMail2, "ymail2");
+_LIT(KMail3, "imail3");
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::NewL
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyPredictiveSearchTable* UT_CQwertyPredictiveSearchTable::NewL()
+    {
+    UT_CQwertyPredictiveSearchTable* self = UT_CQwertyPredictiveSearchTable::NewLC();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::NewLC
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyPredictiveSearchTable* UT_CQwertyPredictiveSearchTable::NewLC()
+    {
+    UT_CQwertyPredictiveSearchTable* self =
+		new( ELeave ) UT_CQwertyPredictiveSearchTable();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::~UT_CQwertyPredictiveSearchTable
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyPredictiveSearchTable::~UT_CQwertyPredictiveSearchTable()
+    {
+    delete iTable;
+    iTable = NULL;
+    
+    iDB.Close(); // Must close DB before it can be deleted
+    RSqlDatabase::Delete(KDBFile);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::UT_CQwertyPredictiveSearchTable
+// -----------------------------------------------------------------------------
+//
+UT_CQwertyPredictiveSearchTable::UT_CQwertyPredictiveSearchTable()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::ConstructL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::ConstructL()
+    {
+    // 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
+    }
+    
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::SetupL
+// Must start with an empty DB file for each test case
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::SetupL()
+    {
+    // Ignore error
+	RSqlDatabase::Delete(KDBFile);
+    // If this causes KErrAlreadyExists, iDB won't be fully constructed
+	iDB.Create(KDBFile);
+
+	iTable = CQwertyPredictiveSearchTable::NewL(iDB);
+	// Create (empty) predictive search tables to DB
+	iTable->CreateTableL();
+	}
+    
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::Teardown
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::Teardown()
+    {
+    delete iTable;
+	iTable = NULL;
+
+	iDB.Close(); // Must close DB before it can be deleted
+	RSqlDatabase::Delete(KDBFile);
+    }
+
+
+// TEST CASES
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::UT_CreateInDbLL
+// The first test case shows resource leak if Orbit keymap is used. If harcoded
+// keymap is used, there is no resource leak.
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::UT_CreateInDbLL()
+    {
+	// Initially all tables are empty
+	CheckItemCountL(InitTableVector());
+
+	AddContactL(KTestContactId, KFirstName, KLastName, KMail, KMail2, KMail3);
+    
+	QVector<TInt> result = InitTableVector();
+	result[0] = 1;
+	result[2] = 1;
+	result[3] = 1;
+	result[4] = 1;
+	result[5] = 1;
+	result[7] = 1;
+	CheckItemCountL(result);
+
+	AddContactL(KTestContactId2, KNullDesC, KNullDesC, KNullDesC, KMail);
+	++result[4];
+	CheckItemCountL(result);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::UT_UpdateLL
+// Update couple of fields, including mail address and adding a new mail
+// addresses
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::UT_UpdateLL()
+	{
+	_LIT(KNewMailAddress, "uNew.mail@add.ress");
+	_LIT(KNewFirstName, "tNewFn");
+    
+    AddContactL(KTestContactId, KFirstName, KLastName, KMail);
+
+	QVector<TInt> result = InitTableVector();
+	result[0] = 1;
+	result[2] = 1;
+	result[3] = 1;
+	result[4] = 1;
+	CheckItemCountL(result);
+
+	CContactItem* contact =
+		FillContactItemLC(KTestContactId, KNewFirstName, KLastName,
+                          KNewMailAddress, KMail2, KMail);
+    iTable->UpdateL(*contact);
+    CleanupStack::PopAndDestroy(contact);
+
+    result = InitTableVector();
+	result[2] = 1;
+	result[4] = 1;
+	result[5] = 1;
+	result[6] = 1;
+	CheckItemCountL(result);
+	}
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::UT_DeleteLL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::UT_DeleteLL()
+    {
+    // Try to delete a non-existing item
+    CContactItem* contact =
+        FillContactItemLC(KTestContactId, KFirstName, KLastName, KMail2);
+    TBool lowDiskErrorOccurred(EFalse);
+    iTable->DeleteL(*contact, lowDiskErrorOccurred);
+    
+    // Add two contacts
+    iTable->CreateInDbL(*contact);
+    CContactItem* contact2 =
+        FillContactItemLC(KTestContactId2, KFirstName2, KLastName2, KMail3);
+    iTable->CreateInDbL(*contact2);
+
+    QVector<TInt> result = InitTableVector();
+    result[0] = 1;
+    result[2] = 1;
+    result[3] = 1;
+    result[5] = 1;
+    result[7] = 1;
+    result[8] = 1;
+    result[10] = 1;
+    CheckItemCountL(result);
+    
+    iTable->DeleteL(*contact2, lowDiskErrorOccurred);
+    CleanupStack::PopAndDestroy(contact2);
+    
+    result = InitTableVector();
+    result[0] = 1;
+    result[2] = 1;
+    result[3] = 1;
+    result[5] = 1;
+    CheckItemCountL(result);
+
+    iTable->DeleteL(*contact, lowDiskErrorOccurred);
+    CleanupStack::PopAndDestroy(contact);
+    
+    CheckItemCountL(InitTableVector());
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::InitTableVector
+// -----------------------------------------------------------------------------
+//
+QVector<TInt> UT_CQwertyPredictiveSearchTable::InitTableVector() const
+	{
+	QVector<TInt> allTablesAreEmpty(CQwertyKeyMap::EAmountOfKeysInQwertyKeypad, 0);
+	return allTablesAreEmpty;
+	}
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::AddContactL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::AddContactL(TContactItemId aContactId,
+                                                  const TDesC& aFirstName,
+                                                  const TDesC& aLastName,
+                                                  const TDesC& aMail,
+                                                  const TDesC& aMail2,
+                                                  const TDesC& aMail3)
+    {
+	CContactItem* contact = FillContactItemLC(aContactId,
+                                              aFirstName,
+                                              aLastName,
+                                              aMail,
+                                              aMail2,
+                                              aMail3);
+	iTable->CreateInDbL(*contact);
+	CleanupStack::PopAndDestroy(contact);
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::FillContactItemLC
+// -----------------------------------------------------------------------------
+//
+CContactItem*
+UT_CQwertyPredictiveSearchTable::FillContactItemLC(TContactItemId aContactId,
+                                                   const TDesC& aFirstName,
+                                                   const TDesC& aLastName,
+                                                   const TDesC& aMail,
+                                                   const TDesC& aMail2,
+                                                   const TDesC& aMail3) const
+    {
+    CContactItem* contact = CContactItem::NewLC(KUidContactCard);
+    contact->SetId(aContactId);
+
+    if (aFirstName.Length() > 0)
+        {
+        CContactItemField* field =
+            CContactItemField::NewL(KStorageTypeText, KUidContactFieldGivenName);
+        CContactTextField* textfield = field->TextStorage();
+        CleanupStack::PushL(field);
+        textfield->SetTextL(aFirstName);
+        contact->AddFieldL(*field); // Takes ownership
+        CleanupStack::Pop(field);
+        }
+    
+    if (aLastName.Length() > 0)
+        {
+        CContactItemField* field =
+            CContactItemField::NewL(KStorageTypeText, KUidContactFieldFamilyName);
+        CleanupStack::PushL(field);
+        field->TextStorage()->SetTextL(aLastName);
+        contact->AddFieldL(*field); // Takes ownership
+        CleanupStack::Pop(field);
+        }
+
+    if (aMail.Length() > 0)
+        {
+        CContactItemField* field =
+            CContactItemField::NewL(KStorageTypeText, KUidContactFieldEMail);
+        CleanupStack::PushL(field);
+        field->TextStorage()->SetTextL(aMail);
+        contact->AddFieldL(*field); // Takes ownership
+        CleanupStack::Pop(field);
+        }
+    
+    if (aMail2.Length() > 0)
+        {
+        CContactItemField* field =
+            CContactItemField::NewL(KStorageTypeText, KUidContactFieldEMail);
+        CleanupStack::PushL(field);
+        field->TextStorage()->SetTextL(aMail2);
+        contact->AddFieldL(*field); // Takes ownership
+        CleanupStack::Pop(field);
+        }
+    
+    if (aMail3.Length() > 0)
+        {
+        CContactItemField* field =
+            CContactItemField::NewL(KStorageTypeText, KUidContactFieldEMail);
+        CleanupStack::PushL(field);
+        field->TextStorage()->SetTextL(aMail3);
+        contact->AddFieldL(*field); // Takes ownership
+        CleanupStack::Pop(field);
+        }    
+	return contact;
+    }
+
+// -----------------------------------------------------------------------------
+// UT_CQwertyPredictiveSearchTable::CheckItemCountL
+// -----------------------------------------------------------------------------
+//
+void UT_CQwertyPredictiveSearchTable::CheckItemCountL(
+	QVector<TInt> aCountInTables)
+    {
+	const TInt KMaxTableNameLength = 4;
+
+    HBufC* s = HBufC::NewLC(KCountSelect().Length() + KMaxTableNameLength);
+	TPtr ptr = s->Des();
+
+	QList<QChar> tables;
+	QT_TRYCATCH_LEAVING(tables = iTable->FillAllTables());
+	HBufC* tableName(NULL);
+	TInt tableNumber(0);
+	while ((tableName = iTable->GetNextTableNameL(tables)) != NULL)
+		{
+		ptr.Format(KCountSelect, tableName);
+		delete tableName;
+		tableName = NULL;
+        TSqlScalarFullSelectQuery scalarQuery(iDB);
+    
+        TInt rowCount = scalarQuery.SelectIntL(ptr);
+        
+		EUNIT_ASSERT_EQUALS(aCountInTables.at(tableNumber), rowCount);
+		++tableNumber;
+        }
+
+    CleanupStack::PopAndDestroy(s);
+	}
+    
+//  TEST TABLE
+
+EUNIT_BEGIN_TEST_TABLE(
+    UT_CQwertyPredictiveSearchTable,
+    "UT_CQwertyPredictiveSearchTable",
+    "UNIT" )
+        
+EUNIT_TEST(
+    "CreateInDbL - test",
+    "UT_CQwertyPredictiveSearchTable",
+    "CreateInDbL",
+    "FUNCTIONALITY",
+    SetupL, UT_CreateInDbLL, Teardown )
+
+EUNIT_TEST(
+    "UpdateL - test update mail address",
+    "UT_CQwertyPredictiveSearchTable",
+    "UpdateL",
+    "FUNCTIONALITY",
+    SetupL, UT_UpdateLL, Teardown )
+
+EUNIT_TEST(
+    "Delete - test",
+    "UT_CQwertyPredictiveSearchTable",
+    "DeleteL",
+    "FUNCTIONALITY",
+    SetupL, UT_DeleteLL, Teardown )
+
+EUNIT_END_TEST_TABLE
+
+//  END OF FILE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_cqwertypredictivesearchtable.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,99 @@
+/*
+* 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: Unit test class for QWERTY tables
+*
+*/
+
+#ifndef __UT_CQWERTYPREDICTIVESEARCHTABLE_H__
+#define __UT_CQWERTYPREDICTIVESEARCHTABLE_H__
+
+//  EXTERNAL INCLUDES
+#include <digia/eunit/ceunittestsuiteclass.h>
+#include <digia/eunit/eunitmacros.h>
+#include <sqldb.h>
+#include "cntdef.h" // TContactItemId
+#include <QVector>
+
+//  FORWARD DECLARATIONS
+class CQwertyPredictiveSearchTable;
+class CContactItem;
+
+//  CONSTANTS
+
+//  CLASS DEFINITION
+/**
+ * Tester class for CQwertyPredictiveSearchTable.
+ */
+NONSHARABLE_CLASS( UT_CQwertyPredictiveSearchTable ): public CEUnitTestSuiteClass
+    {
+    public: // Constructors and destructors
+
+        /**
+         * Two phase construction
+         */
+        static UT_CQwertyPredictiveSearchTable* NewL();
+        static UT_CQwertyPredictiveSearchTable* NewLC();
+        
+        /**
+         * Destructor
+         */
+        ~UT_CQwertyPredictiveSearchTable();
+
+    private: // Constructors
+
+        UT_CQwertyPredictiveSearchTable();
+        void ConstructL();
+        
+    private: // Test case setup and teardown
+
+        void SetupL();
+        void Teardown();
+
+    private: // Test functions
+
+        void UT_CreateInDbLL();
+		void UT_UpdateLL();
+		void UT_DeleteLL();
+        
+    private: // New functions
+        QVector<TInt> InitTableVector() const;
+        
+        void AddContactL(TContactItemId aContactId,
+                        const TDesC& aFirstName = KNullDesC,
+                        const TDesC& aLastName = KNullDesC,
+                        const TDesC& aMail = KNullDesC,
+                        const TDesC& aMail2 = KNullDesC,
+                        const TDesC& aMail3 = KNullDesC);
+
+		CContactItem* FillContactItemLC(TContactItemId aContactId,
+                                      const TDesC& aFirstName = KNullDesC,
+                                      const TDesC& aLastName = KNullDesC,
+                                      const TDesC& aMail = KNullDesC,
+                                      const TDesC& aMail2 = KNullDesC,
+                                      const TDesC& aMail3 = KNullDesC) const;
+
+        void CheckItemCountL(QVector<TInt> aCountInTables);
+
+    private:    // Data
+
+		CQwertyPredictiveSearchTable* iTable;
+        
+        RSqlDatabase iDB;
+
+        EUNIT_DECLARE_TEST_TABLE;
+    };
+
+#endif      //  __UT_CQWERTYPREDICTIVESEARCHTABLE_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql/src/t_predictivesearchtabledefs.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,43 @@
+/*
+* 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: Common definitions for test code for predictive search tables
+*
+*/
+
+#ifndef __UT_PREDICTIVESEARCHTABLEDEFS_H__
+#define __UT_PREDICTIVESEARCHTABLEDEFS_H__
+
+//  EXTERNAL INCLUDES
+#include "cntdef.h" // TContactItemId
+
+
+// Database file
+_LIT(KDBFile, "c:\\unittest.db");
+
+_LIT(KDBFileWithoutPredSearch, "c:\\contacts_without_pred_search_tables.db");
+_LIT(KDBFile12keyButNoQwerty, "c:\\contacts_just_12key_tables.db");
+_LIT(KDBFileOtherLanguage, "c:\\contacts_language_45.db");
+
+
+const TContactItemId KTestContactId = 20;
+const TContactItemId KTestContactId2 = 85;
+const TContactItemId KTestContactId3 = 7001;
+const TContactItemId KTestContactId4 = 56030;
+
+_LIT(KTestFirstName, "123");
+_LIT(KTestLastName, "45678");
+
+#endif      //  __UT_PREDICTIVESEARCHTABLEDEFS_H__
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql_qt/main.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 "testrunner.h"
+#include "ut_cntsqlsearch.h"
+
+#include <QtTest/QtTest>
+
+int main(int argc, char *argv[]) 
+{
+    bool promptOnExit(true);
+    for (int i=0; i<argc; i++) {
+        if (QString(argv[i]) == "-noprompt")
+            promptOnExit = false;
+    }
+    printf("Running tests...\n");
+            
+    QApplication app(argc, argv);
+    
+    TestRunner testRunner("ut_symbian");
+    
+    UT_CntSqlSearch ut_sqlSearch;
+    testRunner.runTests(ut_sqlSearch);
+    
+    testRunner.printResults();
+
+    /*if (promptOnExit) {
+        printf("Press any key...\n");
+        getchar(); 
+    }*/
+    return 0;   
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql_qt/runtest.cmd	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,6 @@
+call qmake
+call sbs reallyclean
+call qmake
+call sbs -c winscw_udeb
+call copy \epoc32\release\winscw\udeb\ut_cntsqlsearch.exe \epoc32\release\winscw\udeb\z\sys\bin\test.exe 
+call epoc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,1520 @@
+/*
+* 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:
+*
+*/
+
+#include <QtTest/QtTest>
+#include <QStringList>
+#include <QLocale>
+
+#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);
+    LOG2(QString("Reference"), reference);
+    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));
+
+    pattern = QString("20");
+#if defined(USE_DEMORGAN)
+        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<148618787703226368) AND NOT(nbr2>144115188075855871 AND nbr2<148618787703226368) AND NOT(nbr3>144115188075855871 AND nbr3<148618787703226368) AND NOT(nbr4>144115188075855871 AND nbr4<148618787703226368)))) ORDER BY first_name, 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("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;");
+#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("#");
+#if defined(USE_DEMORGAN)
+        reference = QString("SELECT contact_id FROM predictivesearch11 ORDER BY first_name, 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("#22");
+#if defined(USE_DEMORGAN)
+    reference = QString("SELECT contact_id FROM predictivesearch11 WHERE (NOT(NOT(nbr>802203683625369599 AND nbr<802485158602080256) AND NOT(nbr2>802203683625369599 AND nbr2<802485158602080256) AND NOT(nbr3>802203683625369599 AND nbr3<802485158602080256) AND NOT(nbr4>802203683625369599 AND nbr4<802485158602080256))) ORDER BY first_name, 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("#0*");
+#if defined(USE_DEMORGAN)
+    reference = QString("SELECT contact_id FROM predictivesearch11 WHERE NOT(NOT(NOT(NOT(nbr>795448284184313855 AND nbr<795729759161024512) AND NOT(nbr2>795448284184313855 AND nbr2<795729759161024512) AND NOT(nbr3>795448284184313855 AND nbr3<795729759161024512) AND NOT(nbr4>795448284184313855 AND nbr4<795729759161024512))) AND NOT(NOT(NOT(nbr2>720575940379279359 AND nbr2<792633534417207296 AND nbr>792633534417207295 AND nbr<864691128455135232) AND NOT(nbr3>720575940379279359 AND nbr3<792633534417207296 AND nbr>792633534417207295 AND nbr<864691128455135232) AND NOT(nbr3>720575940379279359 AND nbr3<792633534417207296 AND nbr2>792633534417207295 AND nbr2<864691128455135232) AND NOT(nbr4>720575940379279359 AND nbr4<792633534417207296 AND nbr>792633534417207295 AND nbr<864691128455135232) AND NOT(nbr4>720575940379279359 AND nbr4<792633534417207296 AND nbr2>792633534417207295 AND nbr2<864691128455135232) AND NOT(nbr4>720575940379279359 AND nbr4<792633534417207296 AND nbr3>792633534417207295 AND nbr3<864691128455135232))) AND NOT(NOT(NOT(nbr2>792633534417207295 AND nbr2<864691128455135232 AND nbr>720575940379279359 AND nbr<792633534417207296) AND NOT(nbr3>792633534417207295 AND nbr3<864691128455135232 AND nbr>720575940379279359 AND nbr<792633534417207296) AND NOT(nbr3>792633534417207295 AND nbr3<864691128455135232 AND nbr2>720575940379279359 AND nbr2<792633534417207296) AND NOT(nbr4>792633534417207295 AND nbr4<864691128455135232 AND nbr>720575940379279359 AND nbr<792633534417207296) AND NOT(nbr4>792633534417207295 AND nbr4<864691128455135232 AND nbr2>720575940379279359 AND nbr2<792633534417207296) AND NOT(nbr4>792633534417207295 AND nbr4<864691128455135232 AND nbr3>720575940379279359 AND nbr3<792633534417207296)))) ORDER BY predictivesearch11.first_name, predictivesearch11.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("qz") + QChar(30) + QString("vqwerty");
+    reference = QString("SELECT contact_id FROM qm0 WHERE (NOT(NOT(n>5348024557502463 AND n<5629499534213120) AND NOT(n2>5348024557502463 AND n2<5629499534213120) AND NOT(n3>5348024557502463 AND n3<5629499534213120) AND NOT(n4>5348024557502463 AND n4<5629499534213120) AND NOT(n5>5348024557502463 AND n5<5629499534213120) AND NOT(n6>5348024557502463 AND n6<5629499534213120) AND NOT(n7>5348024557502463 AND n7<5629499534213120))) ORDER BY first_name, last_name ASC;");
+    result = mCntSqlSearch->CreatePredictiveSearch(pattern);   
+    LOG2(pattern, result);
+    //qDebug() << pattern << " -> result" << result;
+    QVERIFY(!result.compare(reference));
+    
+    TEST_PASSED_LOG("testPredictiveSearch");
+}
+
+void UT_CntSqlSearch::testSelectQweryTable()
+    {
+    TEST_BEGIN_LOG("testSelectQweryTable");
+    QString pattern("q");
+    QString result = mCntSqlSearch->selectQweryTable(pattern);
+    QVERIFY(result == "qm0" );
+    
+    pattern = QString("000");
+    result = mCntSqlSearch->selectQweryTable(pattern);
+    //QVERIFY(result == "qm0" );
+    
+    pattern = QString("9");
+    result = mCntSqlSearch->selectQweryTable(pattern);
+    //QVERIFY(result == "qm9" );
+    TEST_PASSED_LOG("testSelectQweryTable");
+    }
+
+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) );
+
+    pattern = QString("B");
+    reference = QString("predictivesearch11");
+    result = mCntSqlSearch->SelectTable(pattern);
+    QVERIFY( !result.compare( reference) );
+
+    pattern = QString("A");
+    reference = QString("predictivesearch10");
+    result = mCntSqlSearch->SelectTable(pattern);
+    QVERIFY( !result.compare( reference) );
+
+    pattern = QString("A0");
+    reference = QString("predictivesearch10");
+    result = mCntSqlSearch->SelectTable(pattern);
+    QVERIFY( !result.compare( reference) );
+
+     pattern = QString("A10");
+    reference = QString("predictivesearch10");
+    result = mCntSqlSearch->SelectTable(pattern);
+    QVERIFY( !result.compare( reference) );
+
+    pattern = QString("0A");
+    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);
+    //qDebug() << pattern << " -> result" << result << " -> reference" << reference;
+    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::testCreateQwertyQuery()
+    {
+    TEST_BEGIN_LOG("testCreateQwertyQuery");
+    QString pattern = QString("s") + QChar(30) + QString("vqwerty");
+    QString reference("SELECT contact_id FROM qm11 ORDER BY first_name, last_name ASC;");
+    QString result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    pattern = QString("s ya") + QChar(30) + QString("vqwerty");
+    reference = QString("SELECT contact_id FROM qm11 WHERE NOT(NOT(NOT(NOT(n>215914052579233922 AND n<215914052579233924) AND NOT(n2>215914052579233922 AND n2<215914052579233924) AND NOT(n3>215914052579233922 AND n3<215914052579233924) AND NOT(n4>215914052579233922 AND n4<215914052579233924) AND NOT(n5>215914052579233922 AND n5<215914052579233924) AND NOT(n6>215914052579233922 AND n6<215914052579233924) AND NOT(n7>215914052579233922 AND n7<215914052579233924))) AND NOT(NOT(NOT(n2>92886742314516479 AND n2<93168217291227136 AND n>198158383604301823 AND n<216172782113783808) AND NOT(n3>92886742314516479 AND n3<93168217291227136 AND n>198158383604301823 AND n<216172782113783808) AND NOT(n3>92886742314516479 AND n3<93168217291227136 AND n2>198158383604301823 AND n2<216172782113783808) AND NOT(n4>92886742314516479 AND n4<93168217291227136 AND n>198158383604301823 AND n<216172782113783808) AND NOT(n4>92886742314516479 AND n4<93168217291227136 AND n2>198158383604301823 AND n2<216172782113783808) AND NOT(n4>92886742314516479 AND n4<93168217291227136 AND n3>198158383604301823 AND n3<216172782113783808))) AND NOT(NOT(NOT(n2>198158383604301823 AND n2<216172782113783808 AND n>92886742314516479 AND n<93168217291227136) AND NOT(n3>198158383604301823 AND n3<216172782113783808 AND n>92886742314516479 AND n<93168217291227136) AND NOT(n3>198158383604301823 AND n3<216172782113783808 AND n2>92886742314516479 AND n2<93168217291227136) AND NOT(n4>198158383604301823 AND n4<216172782113783808 AND n>92886742314516479 AND n<93168217291227136) AND NOT(n4>198158383604301823 AND n4<216172782113783808 AND n2>92886742314516479 AND n2<93168217291227136) AND NOT(n4>198158383604301823 AND n4<216172782113783808 AND n3>92886742314516479 AND n3<93168217291227136)))) ORDER BY qm11.first_name, qm11.last_name ASC;");
+    result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    pattern = QString("syadira") + QChar(30) + QString("vqwerty");
+    reference = QString("SELECT contact_id FROM qm11 WHERE (NOT(NOT(n>199610571155832831 AND n<199610571156094976) AND NOT(n2>199610571155832831 AND n2<199610571156094976) AND NOT(n3>199610571155832831 AND n3<199610571156094976) AND NOT(n4>199610571155832831 AND n4<199610571156094976) AND NOT(n5>199610571155832831 AND n5<199610571156094976) AND NOT(n6>199610571155832831 AND n6<199610571156094976) AND NOT(n7>199610571155832831 AND n7<199610571156094976))) ORDER BY first_name, last_name ASC;");
+    result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    pattern = QString("qz") + QChar(30) + QString("vqwerty");
+    reference = QString("SELECT contact_id FROM qm0 WHERE (NOT(NOT(n>5348024557502463 AND n<5629499534213120) AND NOT(n2>5348024557502463 AND n2<5629499534213120) AND NOT(n3>5348024557502463 AND n3<5629499534213120) AND NOT(n4>5348024557502463 AND n4<5629499534213120) AND NOT(n5>5348024557502463 AND n5<5629499534213120) AND NOT(n6>5348024557502463 AND n6<5629499534213120) AND NOT(n7>5348024557502463 AND n7<5629499534213120))) ORDER BY first_name, last_name ASC;");
+    result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    pattern = QString("qz df") + QChar(30) + QString("vqwerty");
+    reference = QString("SELECT contact_id FROM qm0 WHERE NOT(NOT(NOT(NOT(n>5625941142798401 AND n<5625941142798403) AND NOT(n2>5625941142798401 AND n2<5625941142798403) AND NOT(n3>5625941142798401 AND n3<5625941142798403) AND NOT(n4>5625941142798401 AND n4<5625941142798403) AND NOT(n5>5625941142798401 AND n5<5625941142798403) AND NOT(n6>5625941142798401 AND n6<5625941142798403) AND NOT(n7>5625941142798401 AND n7<5625941142798403))) AND NOT(NOT(NOT(n2>219831956811022335 AND n2<220113431787732992 AND n>5348024557502463 AND n<5629499534213120) AND NOT(n3>219831956811022335 AND n3<220113431787732992 AND n>5348024557502463 AND n<5629499534213120) AND NOT(n3>219831956811022335 AND n3<220113431787732992 AND n2>5348024557502463 AND n2<5629499534213120) AND NOT(n4>219831956811022335 AND n4<220113431787732992 AND n>5348024557502463 AND n<5629499534213120) AND NOT(n4>219831956811022335 AND n4<220113431787732992 AND n2>5348024557502463 AND n2<5629499534213120) AND NOT(n4>219831956811022335 AND n4<220113431787732992 AND n3>5348024557502463 AND n3<5629499534213120))) AND NOT(NOT(NOT(n2>5348024557502463 AND n2<5629499534213120 AND n>219831956811022335 AND n<220113431787732992) AND NOT(n3>5348024557502463 AND n3<5629499534213120 AND n>219831956811022335 AND n<220113431787732992) AND NOT(n3>5348024557502463 AND n3<5629499534213120 AND n2>219831956811022335 AND n2<220113431787732992) AND NOT(n4>5348024557502463 AND n4<5629499534213120 AND n>219831956811022335 AND n<220113431787732992) AND NOT(n4>5348024557502463 AND n4<5629499534213120 AND n2>219831956811022335 AND n2<220113431787732992) AND NOT(n4>5348024557502463 AND n4<5629499534213120 AND n3>219831956811022335 AND n3<220113431787732992)))) ORDER BY qm0.first_name, qm0.last_name ASC;");
+    result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    pattern = QString("") + QChar(30) + QString("vqwerty");
+    reference = QString("");
+    result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    pattern = QString("levis.augu_whatever") + QChar(30) + QString("vqwerty");
+    reference = QString("SELECT contact_id FROM qm18 WHERE (NOT(NOT(n>324919373450470277 AND n<324919373450470279) AND NOT(n2>324919373450470277 AND n2<324919373450470279) AND NOT(n3>324919373450470277 AND n3<324919373450470279) AND NOT(n4>324919373450470277 AND n4<324919373450470279) AND NOT(n5>324919373450470277 AND n5<324919373450470279) AND NOT(n6>324919373450470277 AND n6<324919373450470279) AND NOT(n7>324919373450470277 AND n7<324919373450470279))) ORDER BY first_name, last_name ASC;");
+    result = mCntSqlSearch->CreateQwertyQuery(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    LOG2(pattern, result);
+    QVERIFY( !result.compare( reference) );
+    TEST_PASSED_LOG("testCreateQwertyQuery");
+    }
+
+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::testExactMatchSearchQwerty()
+    {
+    TEST_BEGIN_LOG("testExactMatchSearchQwerty");
+
+        QString pattern("wt");
+    #if defined(USE_DEMORGAN)
+        QString reference("(NOT(NOT(n>19140298416324607 AND n<19421773393035264) AND NOT(n2>19140298416324607 AND n2<19421773393035264) AND NOT(n3>19140298416324607 AND n3<19421773393035264) AND NOT(n4>19140298416324607 AND n4<19421773393035264) AND NOT(n5>19140298416324607 AND n5<19421773393035264) AND NOT(n6>19140298416324607 AND n6<19421773393035264) AND NOT(n7>19140298416324607 AND n7<19421773393035264)))");
+    #else // #if defined(USE_DEMORGAN)
+        QString reference("(NOT(NOT(n>19140298416324607 AND n<19421773393035264) AND NOT(n2>19140298416324607 AND n2<19421773393035264) AND NOT(n3>19140298416324607 AND n3<19421773393035264) AND NOT(n4>19140298416324607 AND n4<19421773393035264) AND NOT(n5>19140298416324607 AND n5<19421773393035264) AND NOT(n6>19140298416324607 AND n6<19421773393035264) AND NOT(n7>19140298416324607 AND n7<19421773393035264)))");
+    #endif // #if defined(USE_DEMORGAN)
+        QString result = mCntSqlSearch->ExactMatchQwerty(pattern);
+        LOG2(pattern, result);
+        QVERIFY(result == reference);
+    TEST_PASSED_LOG("testExactMatchSearchQwerty");
+    }
+        
+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);
+    LOG2("result", result);
+    QVERIFY( !result.compare( reference) );
+    
+    TEST_PASSED_LOG("testIntersectionSearch");
+}
+void UT_CntSqlSearch::testSearchTokensFromOneTable()
+    {
+    TEST_BEGIN_LOG("testSearchTokensFromOneTable");
+    QString pattern("205");
+    QStringList tokens;
+    tokens << "2" << "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->SearchTokensFromOneTable(pattern, tokens);  
+    QVERIFY( !result.compare( reference) );
+   
+    pattern = QString("e p");
+    tokens.clear();
+    tokens << "e" << "p";
+    reference = QString("SELECT contact_id FROM qm2 WHERE NOT(NOT(NOT(NOT(n>53801302970335231 AND n<53805701016846336) AND NOT(n2>53801302970335231 AND n2<53805701016846336) AND NOT(n3>53801302970335231 AND n3<53805701016846336) AND NOT(n4>53801302970335231 AND n4<53805701016846336) AND NOT(n5>53801302970335231 AND n5<53805701016846336) AND NOT(n6>53801302970335231 AND n6<53805701016846336) AND NOT(n7>53801302970335231 AND n7<53805701016846336))) AND NOT(NOT(NOT(n2>162129586585337855 AND n2<180143985094819840 AND n>36028797018963967 AND n<54043195528445952) AND NOT(n3>162129586585337855 AND n3<180143985094819840 AND n>36028797018963967 AND n<54043195528445952) AND NOT(n3>162129586585337855 AND n3<180143985094819840 AND n2>36028797018963967 AND n2<54043195528445952) AND NOT(n4>162129586585337855 AND n4<180143985094819840 AND n>36028797018963967 AND n<54043195528445952) AND NOT(n4>162129586585337855 AND n4<180143985094819840 AND n2>36028797018963967 AND n2<54043195528445952) AND NOT(n4>162129586585337855 AND n4<180143985094819840 AND n3>36028797018963967 AND n3<54043195528445952))) AND NOT(NOT(NOT(n2>36028797018963967 AND n2<54043195528445952 AND n>162129586585337855 AND n<180143985094819840) AND NOT(n3>36028797018963967 AND n3<54043195528445952 AND n>162129586585337855 AND n<180143985094819840) AND NOT(n3>36028797018963967 AND n3<54043195528445952 AND n2>162129586585337855 AND n2<180143985094819840) AND NOT(n4>36028797018963967 AND n4<54043195528445952 AND n>162129586585337855 AND n<180143985094819840) AND NOT(n4>36028797018963967 AND n4<54043195528445952 AND n2>162129586585337855 AND n2<180143985094819840) AND NOT(n4>36028797018963967 AND n4<54043195528445952 AND n3>162129586585337855 AND n3<180143985094819840)))) ORDER BY qm2.first_name, qm2.last_name ASC;");
+    result = mCntSqlSearch->SearchTokensFromOneTable(pattern, tokens, CntSqlSearch::QwertyEmail);
+    //qDebug() << pattern << " -> result" << result;
+    QVERIFY( !result.compare( reference) );
+    TEST_PASSED_LOG("testSearchTokensFromOneTable");
+    }
+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::testExactMatchQwerty()
+{
+    TEST_BEGIN_LOG("testExactMatchQwerty");
+
+    QString pattern("25");
+#if defined(USE_DEMORGAN)
+    QString reference("(NOT(NOT(n>604608249974489087 AND n<604889724951199744) AND NOT(n2>604608249974489087 AND n2<604889724951199744) AND NOT(n3>604608249974489087 AND n3<604889724951199744) AND NOT(n4>604608249974489087 AND n4<604889724951199744) AND NOT(n5>604608249974489087 AND n5<604889724951199744) AND NOT(n6>604608249974489087 AND n6<604889724951199744) AND NOT(n7>604608249974489087 AND n7<604889724951199744)))");
+#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->ExactMatchQwerty(pattern);
+    LOG2(pattern, result);
+    QVERIFY(!result.compare(reference));
+
+    TEST_PASSED_LOG("testExactMatchQwerty");
+}
+
+void UT_CntSqlSearch::testCreateJoinTableSearch()
+{
+    TEST_BEGIN_LOG("testCreateJoinTableSearch");
+    
+    QString pattern("5606");
+    QStringList tokens;
+    tokens << "56" << "6";
+    QString reference;
+    QString result;
+#if defined(USE_DEMORGAN)
+    reference = QString("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)
+    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::testCompareTwoQwertyColumns()
+    {
+    TEST_BEGIN_LOG("testChangeStringPadings");
+    QString pattern("234");
+    QString result;
+    QString reference("");
+    //result = mCntSqlSearch->CompareTwoQwertyColumns(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    //QVERIFY( result == reference );
+    TEST_PASSED_LOG("testCreateJoinTableSearch");
+    }
+void UT_CntSqlSearch::testChangeStringPadings()
+{
+    TEST_BEGIN_LOG("testChangeStringPadings");
+
+    QString pattern("234");
+    QString result;
+    QString reference("234");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+    //qDebug() << pattern << " -> result" << result;
+    QVERIFY( result == reference );
+
+    pattern = QString("*");
+    reference = QString("A");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("+");
+    reference = QString("A");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("p");
+    reference = QString("A");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("w");
+    reference = QString("A");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("#");
+    reference = QString("B");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("0#0");
+    reference = QString("0B0");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("#00");
+    reference = QString("B00");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("*#");
+    reference = QString("AB");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("1*2#3");
+    reference = QString("1A2B3");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    //Thai tests
+    QLocale::setDefault(QLocale::Thai);
+    pattern = QString("*");
+    reference = QString("");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("+");
+    reference = QString("");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("p");
+    reference = QString("");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("w");
+    reference = QString("");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("#");
+    reference = QString("");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("0#0");
+    reference = QString("00");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("#00");
+    reference = QString("00");
+
+    pattern = QString("00*");
+    reference = QString("00");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    pattern = QString("*#");
+    reference = QString("");
+    result = mCntSqlSearch->ChangeStringPadings(pattern);
+
+    TEST_PASSED_LOG("testChangeStringPadings");
+}
+
+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 );
+
+    // Pattern contains 0xA and 0xB digits
+    pattern = QString("AB0B9A");
+    reference = QString("770319633126260735");
+    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");
+    }
+
+void UT_CntSqlSearch::testTestPattern()
+    {
+    TEST_BEGIN_LOG("testTestPattern");
+    QString pattern("000");
+    int result;
+    int reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("0");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("20");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("202");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("200");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("2000");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("020002");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("A0");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+
+    pattern = QString("");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+    TEST_PASSED_LOG("testTestPattern");
+
+    pattern = QString("232");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("232");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("2320");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("2302");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("23020");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("023020");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("02320");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("02302");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("0232");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("00232");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("0");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("00");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("1");
+    reference = false;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+    
+    pattern = QString("05");
+    reference = true;
+    result = mCntSqlSearch->TestPattern(pattern, CntSqlSearch::ZeroIsFirstNumber);
+    QCOMPARE( result, reference );
+     
+    TEST_PASSED_LOG("testTestPattern");
+    }
+
+void UT_CntSqlSearch::testIsQwerty()
+    {
+    TEST_BEGIN_LOG("testTestIsQwerty");
+    QString pattern = QString("s") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString(" ") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString("") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString("p a") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString("&") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString("6") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString("6") + QChar(30) + QString("vqwerty");
+    QVERIFY(mCntSqlSearch->isQwerty(pattern));
+    pattern = QString("vqwerty");
+    QVERIFY(!mCntSqlSearch->isQwerty(pattern));
+    pattern = QChar(30);
+    QVERIFY(!mCntSqlSearch->isQwerty(pattern));
+    TEST_PASSED_LOG("testIsQwerty");
+    }
+void UT_CntSqlSearch::testQwertyTokens()
+    {
+    TEST_BEGIN_LOG("testQwertyTokens");
+    QString pattern = QString("") + QChar(30) + QString("vqwerty");
+    QStringList tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 1);
+    QVERIFY(tokens.at(0) == "");
+    
+    pattern = QString("a") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 1);
+    QVERIFY(tokens.at(0) == "a");
+  
+    pattern = QString("a a") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 2);
+    QVERIFY(tokens.at(0) == "a");
+    QVERIFY(tokens.at(1) == "a");
+    
+    pattern = QString("abc") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 1);
+    QVERIFY(tokens.at(0) == "abc");
+
+    pattern = QString("abc  d") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 2);
+    QVERIFY(tokens.at(0) == "abc");
+    QVERIFY(tokens.at(1) == "d");
+    
+    pattern = QString(" abc  d") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 2);
+    QVERIFY(tokens.at(0) == "abc");
+    QVERIFY(tokens.at(1) == "d");
+    
+    pattern = QString("abc  d") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 2);
+    QVERIFY(tokens.at(0) == "abc");
+    QVERIFY(tokens.at(1) == "d");
+    
+    pattern = QString(" 1234  5 ") + QChar(30) + QString("vqwerty");
+    tokens = mCntSqlSearch->qwertyTokens(pattern);
+    QVERIFY(tokens.count() == 2);
+    //QVERIFY(tokens.at(0) == "1234");
+    //QVERIFY(tokens.at(1) == "5");
+     
+    TEST_PASSED_LOG("TestQwertyTokens");
+    }
+#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_APPLESS_MAIN(UT_CntSqlSearch)
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#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 testSelectQweryTable();
+    void testSelectTableView();
+    void testCreateQuery();
+    void testCreateQwertyQuery();
+    void testExactMatchSearch();
+    void testExactMatchSearchQwerty();
+    void testIntersectionSearch();
+    void testSearchTokensFromOneTable();
+    void testExactMatch();
+    void testExactMatchQwerty();
+    void testCreateJoinTableSearch();
+    void testCompareTwoQwertyColumns();
+    void testChangeStringPadings();
+    void testUpperLimit();
+    void testLowerLimit();
+    void testGetTokens();
+    void testTestPattern();
+    void testIsQwerty();
+    void testQwertyTokens();
+    
+    
+private:
+ 
+    CntSqlSearch* mCntSqlSearch;  
+};
+
+#endif // UT_CNTSQLSEARCH_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/cntplsql_qt/ut_cntsqlsearch.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,54 @@
+#                                                                    
+# 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:                                                        
+#                                                                     
+#
+TEMPLATE = app
+TARGET = 
+QT += testlib
+CONFIG += hb
+
+
+DEPENDPATH += .
+INCLUDEPATH += ./
+INCLUDEPATH += ./inc
+INCLUDEPATH += ../../inc
+INCLUDEPATH += ../../../cntplsql/inc/
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$SYMBIAN_PATHS
+INCLUDEPATH += /orbit/include
+
+SOURCES += 		$$SYMBIAN_HEADERS \
+				ut_cntsqlsearch.cpp\			
+        		../../cntplsql/src/cntsqlsearch.cpp\
+				../../cntplsql/src/cpcskeymap.cpp\
+				../../cntplsql/src/cqwertykeymap.cpp\
+				../../cntplsql/src/c12keykeymap.cpp
+
+# Input
+HEADERS += 		$$SYMBIAN_SOURCES \
+				ut_cntsqlsearch.h\
+        		../../cntplsql/inc/cntsqlsearch.h\
+        		../../cntplsql/inc/cpcskeymap.h\
+        		../../cntplsql/inc/cqwertykeymap.h\
+        		../../cntplsql/inc/c12keykeymap.h
+        		
+symbian: {
+    TARGET.UID2 = 0x100039CE
+    TARGET.UID3 = 0xEb768fff
+    TARGET.CAPABILITY = ALL -TCB
+    TARGET.EPOCALLOWDLLDATA = 1
+    LIBS += -lxqservice  -lxqserviceutil
+}
+
--- a/phonebookengines/eabi/cntlistmodelu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/eabi/cntlistmodelu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -4,34 +4,36 @@
 	_ZN12CntListModel11handleAddedERK5QListIjE @ 3 NONAME
 	_ZN12CntListModel11qt_metacallEN11QMetaObject4CallEiPPv @ 4 NONAME
 	_ZN12CntListModel11qt_metacastEPKc @ 5 NONAME
-	_ZN12CntListModel13handleChangedERK5QListIjE @ 6 NONAME
-	_ZN12CntListModel13handleRemovedERK5QListIjE @ 7 NONAME
-	_ZN12CntListModel14initializeDataEv @ 8 NONAME
-	_ZN12CntListModel16staticMetaObjectE @ 9 NONAME DATA 16
-	_ZN12CntListModel19getStaticMetaObjectEv @ 10 NONAME
-	_ZN12CntListModel19handleMyCardChangedERKjS1_ @ 11 NONAME
-	_ZN12CntListModel21setFilterAndSortOrderERKN10QtMobility14QContactFilterERK5QListINS0_17QContactSortOrderEE @ 12 NONAME
-	_ZN12CntListModel21updateContactIdsArrayEv @ 13 NONAME
-	_ZN12CntListModel24handleContactInfoUpdatedEj @ 14 NONAME
-	_ZN12CntListModelC1EPN10QtMobility15QContactManagerERKNS0_14QContactFilterERK5QListINS0_17QContactSortOrderEEbP7QObject @ 15 NONAME
-	_ZN12CntListModelC1ERKN10QtMobility14QContactFilterERK5QListINS0_17QContactSortOrderEEbP7QObject @ 16 NONAME
-	_ZN12CntListModelC2EPN10QtMobility15QContactManagerERKNS0_14QContactFilterERK5QListINS0_17QContactSortOrderEEbP7QObject @ 17 NONAME
-	_ZN12CntListModelC2ERKN10QtMobility14QContactFilterERK5QListINS0_17QContactSortOrderEEbP7QObject @ 18 NONAME
-	_ZN12CntListModelD0Ev @ 19 NONAME
-	_ZN12CntListModelD1Ev @ 20 NONAME
-	_ZN12CntListModelD2Ev @ 21 NONAME
-	_ZNK12CntListModel10metaObjectEv @ 22 NONAME
-	_ZNK12CntListModel10validRowIdEi @ 23 NONAME
-	_ZNK12CntListModel12myCardStatusEv @ 24 NONAME
-	_ZNK12CntListModel14contactManagerEv @ 25 NONAME
-	_ZNK12CntListModel14indexOfContactERKN10QtMobility8QContactE @ 26 NONAME
-	_ZNK12CntListModel18dataForDisplayRoleEi @ 27 NONAME
-	_ZNK12CntListModel4dataERK11QModelIndexi @ 28 NONAME
-	_ZNK12CntListModel5rowIdERKj @ 29 NONAME
-	_ZNK12CntListModel7contactERK11QModelIndex @ 30 NONAME
-	_ZNK12CntListModel7contactEi @ 31 NONAME
-	_ZNK12CntListModel8myCardIdEv @ 32 NONAME
-	_ZNK12CntListModel8rowCountERK11QModelIndex @ 33 NONAME
-	_ZTI12CntListModel @ 34 NONAME
-	_ZTV12CntListModel @ 35 NONAME
+	_ZN12CntListModel12refreshModelEv @ 6 NONAME
+	_ZN12CntListModel12setSortOrderEv @ 7 NONAME
+	_ZN12CntListModel13handleChangedERK5QListIjE @ 8 NONAME
+	_ZN12CntListModel13handleRemovedERK5QListIjE @ 9 NONAME
+	_ZN12CntListModel14initializeDataEv @ 10 NONAME
+	_ZN12CntListModel16staticMetaObjectE @ 11 NONAME DATA 16
+	_ZN12CntListModel19getStaticMetaObjectEv @ 12 NONAME
+	_ZN12CntListModel19handleMyCardChangedERKjS1_ @ 13 NONAME
+	_ZN12CntListModel21updateContactIdsArrayEv @ 14 NONAME
+	_ZN12CntListModel24handleContactInfoUpdatedEj @ 15 NONAME
+	_ZN12CntListModel9setFilterERKN10QtMobility14QContactFilterE @ 16 NONAME
+	_ZN12CntListModelC1EPN10QtMobility15QContactManagerERKNS0_14QContactFilterEbP7QObject @ 17 NONAME
+	_ZN12CntListModelC1ERKN10QtMobility14QContactFilterEbP7QObject @ 18 NONAME
+	_ZN12CntListModelC2EPN10QtMobility15QContactManagerERKNS0_14QContactFilterEbP7QObject @ 19 NONAME
+	_ZN12CntListModelC2ERKN10QtMobility14QContactFilterEbP7QObject @ 20 NONAME
+	_ZN12CntListModelD0Ev @ 21 NONAME
+	_ZN12CntListModelD1Ev @ 22 NONAME
+	_ZN12CntListModelD2Ev @ 23 NONAME
+	_ZNK12CntListModel10metaObjectEv @ 24 NONAME
+	_ZNK12CntListModel10validRowIdEi @ 25 NONAME
+	_ZNK12CntListModel12myCardStatusEv @ 26 NONAME
+	_ZNK12CntListModel14contactManagerEv @ 27 NONAME
+	_ZNK12CntListModel14indexOfContactERKN10QtMobility8QContactE @ 28 NONAME
+	_ZNK12CntListModel18dataForDisplayRoleEi @ 29 NONAME
+	_ZNK12CntListModel4dataERK11QModelIndexi @ 30 NONAME
+	_ZNK12CntListModel5rowIdERKj @ 31 NONAME
+	_ZNK12CntListModel7contactERK11QModelIndex @ 32 NONAME
+	_ZNK12CntListModel7contactEi @ 33 NONAME
+	_ZNK12CntListModel8myCardIdEv @ 34 NONAME
+	_ZNK12CntListModel8rowCountERK11QModelIndex @ 35 NONAME
+	_ZTI12CntListModel @ 36 NONAME
+	_ZTV12CntListModel @ 37 NONAME
 
--- a/phonebookengines/eabi/cntmaptileserviceu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/eabi/cntmaptileserviceu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -1,4 +1,20 @@
 EXPORTS
-	_ZN17CntMapTileService15getMapTileImageEiNS_18ContactAddressTypeE @ 1 NONAME
-	_ZN17CntMapTileService24isLocationFeatureEnabledEv @ 2 NONAME
+	_ZN17CntMapTileService11qt_metacallEN11QMetaObject4CallEiPPv @ 1 NONAME
+	_ZN17CntMapTileService11qt_metacastEPKc @ 2 NONAME
+	_ZN17CntMapTileService12publishValueEiNS_18ContactAddressTypeEi @ 3 NONAME
+	_ZN17CntMapTileService15getMapTileImageEiNS_18ContactAddressTypeER7QString @ 4 NONAME
+	_ZN17CntMapTileService16setMaptileStatusEv @ 5 NONAME
+	_ZN17CntMapTileService16staticMetaObjectE @ 6 NONAME DATA 16
+	_ZN17CntMapTileService19getStaticMetaObjectEv @ 7 NONAME
+	_ZN17CntMapTileService24isLocationFeatureEnabledEv @ 8 NONAME
+	_ZN17CntMapTileService27maptileFetchingStatusUpdateEiii @ 9 NONAME
+	_ZN17CntMapTileService28readEntryFromMaptileDataBaseEiNS_18ContactAddressTypeER11TLookupItemRi @ 10 NONAME
+	_ZN17CntMapTileServiceC1Ev @ 11 NONAME
+	_ZN17CntMapTileServiceC2Ev @ 12 NONAME
+	_ZN17CntMapTileServiceD0Ev @ 13 NONAME
+	_ZN17CntMapTileServiceD1Ev @ 14 NONAME
+	_ZN17CntMapTileServiceD2Ev @ 15 NONAME
+	_ZNK17CntMapTileService10metaObjectEv @ 16 NONAME
+	_ZTI17CntMapTileService @ 17 NONAME
+	_ZTV17CntMapTileService @ 18 NONAME
 
--- a/phonebookengines/eabi/cntsimutilityu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/eabi/cntsimutilityu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -9,20 +9,22 @@
 	_ZN13CntSimUtility15startGetSimInfoEv @ 8 NONAME
 	_ZN13CntSimUtility16RequestCompletedEi @ 9 NONAME
 	_ZN13CntSimUtility16staticMetaObjectE @ 10 NONAME DATA 16
-	_ZN13CntSimUtility18getAvailableStoresERi @ 11 NONAME
-	_ZN13CntSimUtility19adnCacheStatusReadyERNS_11CacheStatusEi @ 12 NONAME
-	_ZN13CntSimUtility19getStaticMetaObjectEv @ 13 NONAME
-	_ZN13CntSimUtility20availableStoresReadyERNS_15AvailableStoresEi @ 14 NONAME
-	_ZN13CntSimUtility20notifyAdnCacheStatusEv @ 15 NONAME
-	_ZN13CntSimUtility23startGetAvailableStoresEv @ 16 NONAME
-	_ZN13CntSimUtilityC1ENS_9StoreTypeERiP7QObject @ 17 NONAME
-	_ZN13CntSimUtilityC2ENS_9StoreTypeERiP7QObject @ 18 NONAME
-	_ZN13CntSimUtilityD0Ev @ 19 NONAME
-	_ZN13CntSimUtilityD1Ev @ 20 NONAME
-	_ZN13CntSimUtilityD2Ev @ 21 NONAME
-	_ZNK13CntSimUtility10metaObjectEv @ 22 NONAME
-	_ZNK13CntSimUtility13isSimInsertedEv @ 23 NONAME
-	_ZNK13CntSimUtility17ParseServiceTableEPNS_15AvailableStoresE @ 24 NONAME
-	_ZTI13CntSimUtility @ 25 NONAME
-	_ZTV13CntSimUtility @ 26 NONAME
+	_ZN13CntSimUtility17getLastImportTimeERi @ 11 NONAME
+	_ZN13CntSimUtility17setLastImportTimeERi @ 12 NONAME
+	_ZN13CntSimUtility18getAvailableStoresERi @ 13 NONAME
+	_ZN13CntSimUtility19adnCacheStatusReadyERNS_11CacheStatusEi @ 14 NONAME
+	_ZN13CntSimUtility19getStaticMetaObjectEv @ 15 NONAME
+	_ZN13CntSimUtility20availableStoresReadyERNS_15AvailableStoresEi @ 16 NONAME
+	_ZN13CntSimUtility20notifyAdnCacheStatusEv @ 17 NONAME
+	_ZN13CntSimUtility23startGetAvailableStoresEv @ 18 NONAME
+	_ZN13CntSimUtilityC1ENS_9StoreTypeERiP7QObject @ 19 NONAME
+	_ZN13CntSimUtilityC2ENS_9StoreTypeERiP7QObject @ 20 NONAME
+	_ZN13CntSimUtilityD0Ev @ 21 NONAME
+	_ZN13CntSimUtilityD1Ev @ 22 NONAME
+	_ZN13CntSimUtilityD2Ev @ 23 NONAME
+	_ZNK13CntSimUtility10metaObjectEv @ 24 NONAME
+	_ZNK13CntSimUtility13isSimInsertedEv @ 25 NONAME
+	_ZNK13CntSimUtility17ParseServiceTableEPNS_15AvailableStoresE @ 26 NONAME
+	_ZTI13CntSimUtility @ 27 NONAME
+	_ZTV13CntSimUtility @ 28 NONAME
 
--- a/phonebookengines/phonebookengines.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookengines/phonebookengines.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -31,7 +31,5 @@
 SUBDIRS += cntmaptileservice
 SUBDIRS += cntsimutility
 SUBDIRS += cntimageutility
-	
-#SUBDIRS += cntlistmodel/tsrc/mt_mobcntmodel
 
 CONFIG += ordered
--- a/phonebookui/bwins/cnthistorymodelu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/bwins/cnthistorymodelu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -34,4 +34,5 @@
 	?findIndices@CntHistoryModel@@AAE?AV?$QList@V?$QList@H@@@@ABV?$QList@H@@@Z @ 33 NONAME ; class QList<class QList<int> > CntHistoryModel::findIndices(class QList<int> const &)
 	??_ECntHistoryModel@@UAE@I@Z @ 34 NONAME ; CntHistoryModel::~CntHistoryModel(unsigned int)
 	?displayRoleData@CntHistoryModel@@ABE?AVQVariant@@ABVHistoryItem@@@Z @ 35 NONAME ; class QVariant CntHistoryModel::displayRoleData(class HistoryItem const &) const
+	?handleLogsReset@CntHistoryModel@@AAEXXZ @ 36 NONAME ; void CntHistoryModel::handleLogsReset(void)
 
--- a/phonebookui/bwins/pbkcommonuiu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/bwins/pbkcommonuiu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -118,4 +118,6 @@
 	?removeCurrentView@CntDefaultViewManager@@AAEXXZ @ 117 NONAME ; void CntDefaultViewManager::removeCurrentView(void)
 	?viewId@CntContactCardView@@UBEHXZ @ 118 NONAME ; int CntContactCardView::viewId(void) const
 	?removeEffect@CntViewNavigator@@QAEXABH@Z @ 119 NONAME ; void CntViewNavigator::removeEffect(int const &)
+	?cleanup@CntDefaultViewManager@@AAEXXZ @ 120 NONAME ; void CntDefaultViewManager::cleanup(void)
+	?closeApp@CntDefaultViewManager@@MAEXXZ @ 121 NONAME ; void CntDefaultViewManager::closeApp(void)
 
--- a/phonebookui/cnthistorymodel/cnthistorymodel.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/cnthistorymodel/cnthistorymodel.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -36,10 +36,6 @@
 
 INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
 INCLUDEPATH += inc
-INCLUDEPATH += ../inc
-INCLUDEPATH += ../../logsui/logsengine/inc
-#INCLUDEPATH += /sf/app/messaging/msg_plat/msg_conversation_model_api/inc
-
 
 INTERNAL_PUBLIC_HEADERS += \
     inc/cnthistorymodelglobal.h \
@@ -62,3 +58,10 @@
 
 # This is for new exporting system coming in garden
 for(header, headers.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$headers.path/$$basename(header)"
+defBlock = \      
+	"$${LITERAL_HASH}if defined(EABI)" \
+		"DEFFILE  ../eabi/cnthistorymodel.def" \
+    "$${LITERAL_HASH}else" \
+        "DEFFILE  ../bwins/cnthistorymodel.def" \
+	"$${LITERAL_HASH}endif"
+MMP_RULES += defBlock
--- a/phonebookui/cnthistorymodel/inc/cnthistorymodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/cnthistorymodel/inc/cnthistorymodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -19,10 +19,15 @@
 
 #include <QAbstractListModel>
 #include <QSharedData>
-#include <qtcontacts.h>
+#include <qmobilityglobal.h>
+#include <qcontactid.h>
 
 #include "cnthistorymodelglobal.h"
 
+QTM_BEGIN_NAMESPACE
+class QContactManager;
+QTM_END_NAMESPACE
+
 QTM_USE_NAMESPACE
 
 class CntHistoryModelData;
@@ -104,6 +109,7 @@
     void logsRowsInserted(const QModelIndex& parent, int first, int last);
     void logsRowsRemoved(const QModelIndex& parent, int first, int last);
     void logsDataChanged(const QModelIndex& first, const QModelIndex& last);
+    void handleLogsReset();
     
     // Messaging model slots
     void messagesReady(QList<MsgItem>& msgs);
--- a/phonebookui/cnthistorymodel/inc/cnthistorymodel_p.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/cnthistorymodel/inc/cnthistorymodel_p.h	Wed Jun 23 18:02:44 2010 +0300
@@ -22,7 +22,7 @@
 #include <QSharedPointer>
 #include <QMap>
 #include <QDateTime>
-#include <qcontactmanager.h>
+#include <qtcontacts.h>
 
 #ifdef PBK_UNIT_TEST
 #include "stub_classes.h"
--- a/phonebookui/cnthistorymodel/src/cnthistorymodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/cnthistorymodel/src/cnthistorymodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -321,6 +321,7 @@
             this, SLOT(logsRowsRemoved(const QModelIndex &, int, int)));
     connect(d->m_AbstractLogsModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), 
                 this, SLOT(logsDataChanged(const QModelIndex &, const QModelIndex &)));
+    connect(d->m_AbstractLogsModel, SIGNAL(modelReset()), this, SLOT(handleLogsReset()));
 
 }
 
@@ -474,6 +475,36 @@
     }
 }
 
+/*
+ * Clear all call logs after receiving a reset model
+ * signal from logs model
+ */
+void CntHistoryModel::handleLogsReset()
+{
+    // Remove all call logs
+    QList<HItemPointer> values = d->m_logsMap.values();
+    foreach(HItemPointer p, values) {
+        d->m_List.removeOne( p );
+    }
+    
+    d->m_logsMap.clear();
+    
+    //read first call events if any and start listening for more 
+    for ( int i = 0; i < d->m_AbstractLogsModel->rowCount(); ++i ) {
+        LogsEvent* event = qVariantValue<LogsEvent*>(
+                d->m_AbstractLogsModel->data(d->m_AbstractLogsModel->index(i, 0), LogsModel::RoleFullEvent) );
+        
+        if ( event ) {
+            HItemPointer item = HItemPointer(new HistoryItem());
+            readLogEvent(event, *item);
+            d->m_logsMap.insert(i, item);
+            d->m_List.append( item );
+        }
+    }
+    
+    sortAndRefresh();
+}
+
 /*!
  * Check whether an idex is out of bound of our list
  *
--- a/phonebookui/cnthistorymodel/tsrc/mt_cnthistorymodel/mt_cnthistorymodel.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/cnthistorymodel/tsrc/mt_cnthistorymodel/mt_cnthistorymodel.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -27,7 +27,7 @@
 INCLUDEPATH += .
 INCLUDEPATH += ../inc
 
-INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 	
 # Input
 HEADERS += mt_cnthistorymodel.h \
--- a/phonebookui/conf/contacts.confml	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/conf/contacts.confml	Wed Jun 23 18:02:44 2010 +0300
@@ -2,21 +2,54 @@
 <configuration xmlns="http://www.s60.com/xml/confml/1" name="Contacts" version="1">
   <feature ref="KCRUiContacts" name="Contacts app ui settings">
     <desc>Contacts app ui settings</desc>
-    <setting ref="KNameOrdering" name="Name ordering in lists" type="selection">
+    <setting ref="KCntNameOrdering" name="Name ordering in lists" type="selection">
       <desc>Displays name label order in names lists</desc>
       <option name="name order Lastname Firstname" value="0"/>
       <option name="name order Lastname, Firstname" value="1"/>
       <option name="name order Firstname Lastname" value="2"/>
     </setting>
   </feature>
+  
+  <feature ref="KSimImport" name="">
+    <setting ref="KImportSim1Imsi" name="Sim1 IMSI" type="string"/>
+    <setting ref="KImportSim1Date" name="Sim1 import date" type="int"/>
+    <setting ref="KImportSim2Imsi" name="Sim2 IMSI" type="string"/>
+    <setting ref="KImportSim2Date" name="Sim2 import date" type="int"/>
+    <setting ref="KImportSim3Imsi" name="Sim3 IMSI" type="string"/>
+    <setting ref="KImportSim3Date" name="Sim3 import date" type="int"/>
+    <setting ref="KImportSim4Imsi" name="Sim4 IMSI" type="string"/>
+    <setting ref="KImportSim4Date" name="Sim4 import date" type="int"/>
+    <setting ref="KImportSim5Imsi" name="Sim5 IMSI" type="string"/>
+    <setting ref="KImportSim5Date" name="Sim5 import date" type="int"/>
+  </feature>
+  
   <data>
     <KCRUiContacts>
-      <KNameOrdering>0</KNameOrdering>
+      <KCntNameOrdering>2</KCntNameOrdering>
     </KCRUiContacts>
+    <KSimImport>
+      <KImportSim1Date>0</KImportSim1Date>
+      <KImportSim2Date>0</KImportSim2Date>
+      <KImportSim3Date>0</KImportSim3Date>
+      <KImportSim4Date>0</KImportSim4Date>
+      <KImportSim5Date>0</KImportSim5Date>
+    </KSimImport>
   </data>
   <rfs>
     <KCRUiContacts>
-      <KNameOrdering>true</KNameOrdering>
+      <KCntNameOrdering>true</KCntNameOrdering>
     </KCRUiContacts>
+    <KSimImport>
+      <KImportSim1Imsi>false</KImportSim1Imsi>
+      <KImportSim1Date>false</KImportSim1Date>
+      <KImportSim2Imsi>false</KImportSim2Imsi>
+      <KImportSim2Date>false</KImportSim2Date>
+      <KImportSim3Imsi>false</KImportSim3Imsi>
+      <KImportSim3Date>false</KImportSim3Date>
+      <KImportSim4Imsi>false</KImportSim4Imsi>
+      <KImportSim4Date>false</KImportSim4Date>
+      <KImportSim5Imsi>false</KImportSim5Imsi>
+      <KImportSim5Date>false</KImportSim5Date>
+    </KSimImport>
   </rfs>
-</configuration>
\ No newline at end of file
+</configuration>
--- a/phonebookui/conf/contacts_2002FF54.crml	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/conf/contacts_2002FF54.crml	Wed Jun 23 18:02:44 2010 +0300
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="KCRUiContacts" uidValue="0x2002FF54" owner="0x20022EF9">
   <access type="R" capabilities="AlwaysPass"/>
-  <key ref="KCRUiContacts/KNameOrdering" backup="true" name="Name ordering in lists" int="0x00000001" type="int">
+  <key ref="KCRUiContacts/KCntNameOrdering" backup="true" name="Name ordering in lists" int="0x00000001" type="int">
     <access type="R" capabilities="AlwaysPass"/>
     <access type="W" capabilities="WriteDeviceData"/>
   </key>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/conf/contacts_200315A8.crml	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="KSimImport" uidValue="0x200315A8" owner="0x20022EF9">
+  <access type="R" capabilities="ReadDeviceData"/>
+  <access type="W" capabilities="WriteDeviceData"/>
+  <key ref="KSimImport/KImportSim1Imsi" backup="true" name="Sim1 IMSI" int="0x00000001" type="string"/>
+  <key ref="KSimImport/KImportSim1Date" backup="true" name="Sim1 import date" int="0x00000002" type="int"/>
+  <key ref="KSimImport/KImportSim2Imsi" backup="true" name="Sim2 IMSI" int="0x00000003" type="string"/>
+  <key ref="KSimImport/KImportSim2Date" backup="true" name="Sim2 import date" int="0x00000004" type="int"/>
+  <key ref="KSimImport/KImportSim3Imsi" backup="true" name="Sim3 IMSI" int="0x00000005" type="string"/>
+  <key ref="KSimImport/KImportSim3Date" backup="true" name="Sim3 import date" int="0x00000006" type="int"/>
+  <key ref="KSimImport/KImportSim4Imsi" backup="true" name="Sim4 IMSI" int="0x00000007" type="string"/>
+  <key ref="KSimImport/KImportSim4Date" backup="true" name="Sim4 import date" int="0x00000008" type="int"/>
+  <key ref="KSimImport/KImportSim5Imsi" backup="true" name="Sim5 IMSI" int="0x00000009" type="string"/>
+  <key ref="KSimImport/KImportSim5Date" backup="true" name="Sim5 import date" int="0x0000000A" type="int"/>
+</repository>
\ No newline at end of file
--- a/phonebookui/eabi/cnthistorymodelu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/eabi/cnthistorymodelu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -34,4 +34,5 @@
 	_ZNK15CntHistoryModel8rowCountERK11QModelIndex @ 33 NONAME
 	_ZTI15CntHistoryModel @ 34 NONAME
 	_ZTV15CntHistoryModel @ 35 NONAME
+	_ZN15CntHistoryModel15handleLogsResetEv @ 36 NONAME
 
--- a/phonebookui/eabi/pbkcommonuiu.def	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/eabi/pbkcommonuiu.def	Wed Jun 23 18:02:44 2010 +0300
@@ -144,4 +144,6 @@
 	_ZThn8_NK18CntContactCardView9isDefaultEv @ 143 NONAME
 	_ZThn8_NK20CntBaseSelectionView4viewEv @ 144 NONAME
 	_ZThn8_NK20CntBaseSelectionView9isDefaultEv @ 145 NONAME
+	_ZN21CntDefaultViewManager7cleanupEv @ 146 NONAME
+	_ZN21CntDefaultViewManager8closeAppEv @ 147 NONAME
 
--- a/phonebookui/inc/cntdebug.h	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-/*
-* 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:  Trace macro declarations.
-*
-*/
-
-
-#ifndef CNTDEBUG_H
-#define CNTDEBUG_H
-
-#include <QDebug>   // QDebug
-#include <QtGlobal> // qDebug()
-
-/*!
-    \def CNT_UNUSED(name)
-    \brief Declares a single variable as unused when tracing is disabled.
-
-    CNT_UNUSED allows variables (usually method parameters) to be declared as used only if
-    tracing is enabled. Without this variables that are included in trace macros, but not otherwise
-    used, would cause unused variable warnings on compilation. If tracing is enabled, CNT_UNUSED
-    has no effect.
-
-    Consider the following class method where the parameter number is not used at all, except for
-    tracing its value on entry:
-
-    \code
-    #include <cntdebug.h>
-
-    void MyClass::myMethod(int number)
-    {
-        CNT_UNUSED(number)
-        CNT_ENTRY("number =" << number)
-
-        // ...some more code where the parameter number is not used.
-
-        CNT_EXIT
-    }
-    \endcode
-
-    Compiling this method with tracing completely disabled at compile time would cause an unused
-    variable warning to be issued unless the CNT_UNUSED macro is used to declare the variable as
-    trace-only.
-
-    \param name The name of the variable to declare as unused if tracing is disabled. To mark
-    several variables as trace-only, add a separate CNT_UNUSED statement for each.
-    \sa CNT_STATIC_ENTRY_ARGS(args), CNT_ENTRY_ARGS(args).
-*/
-
-/*!
-    \def CNT_STATIC_ENTRY
-    \brief A method entry trace macro for static class methods or global functions.
-
-    Invoking CNT_STATIC_ENTRY outputs a timestamp followed by the scope in which the macro
-    was invoked and the word "entry".
-
-    CNT_STATIC_ENTRY is intended to be used as the first line of static class methods or
-    global functions. There is a corresponding exit macro, CNT_EXIT.
-
-    The following example shows proper usage of the CNT_STATIC_ENTRY macro. Assuming a class
-    has been declared with a static method that is implemented like this:
-
-    \code
-    #include <cntdebug.h>
-
-    void MyClass::myStaticMethod()
-    {
-        CNT_STATIC_ENTRY
-
-        int i = 1;
-        i++;
-
-        CNT_EXIT
-    }
-    \endcode
-
-    calling MyClass::myStaticMethod() generates output lines of the following format:
-
-    \code
-    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() entry
-    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() exit
-    \endcode
-
-    \sa CNT_STATIC_ENTRY_ARGS(args), CNT_EXIT.
-*/
-
-/*!
-    \def CNT_STATIC_ENTRY_ARGS(args)
-    \brief A method entry trace macro with arguments for static class methods or global functions.
-
-    CNT_STATIC_ENTRY_ARGS(args) is similar to CNT_STATIC_ENTRY but it allows arguments to be
-    output on the same line without needing to resort to a separate CNT_LOG_ARGS call. This is
-    especially handy for outputting the parameters of the method call.
-
-    The following example shows proper usage of the CNT_STATIC_ENTRY_ARGS(args) macro. Assuming
-    a class has been declared with a static method that is implemented like this:
-
-    \code
-    #include <QString>
-    #include <cntdebug.h>
-
-    void MyClass::myStaticMethod(const QString &text, int number)
-    {
-        CNT_STATIC_ENTRY_ARGS("text =" << text << "number =" << number);
-
-        int i = 1;
-        i++;
-
-        CNT_EXIT
-    }
-    \endcode
-
-    calling MyClass::myStaticMethod(QString("foo"), 74) generates output lines of the following
-    format:
-
-    \code
-    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) entry, text = "foo" number = 74
-    2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) exit
-    \endcode
-
-    \param args Any number of arguments that can be streamed into a QTextStream, joined together
-    by the streaming operator <<.
-    \sa CNT_STATIC_ENTRY.
-*/
-
-/*!
-    \def CNT_ENTRY
-    \brief A method entry trace macro for class methods.
-
-    Invoking CNT_ENTRY outputs a timestamp followed by the scope in which the macro
-    was invoked, the word "entry" and the this pointer value of the instance invoking the
-    macro.
-
-    The this pointer value included in the debug output can help make the output more readable, as
-    it allows different instances of the same class to be distinguished from each other.
-
-    CNT_ENTRY is intended to be used as the first line of class methods. There is a corresponding
-    exit macro, CNT_EXIT.
-
-    The following example shows proper usage of the CNT_ENTRY macro. Assuming a class has been
-    declared with a non-static method that is implemented like this:
-
-    \code
-    #include <cntdebug.h>
-
-    void MyClass::myMethod()
-    {
-        CNT_ENTRY
-
-        int i = 1;
-        i++;
-
-        CNT_EXIT
-    }
-    \endcode
-
-    calling myMethod() on an instance of MyClass generates output lines of the following format:
-
-    \code
-    2009-03-25 11:00:50.171 : void MyClass::myMethod() this 0x6cdab90 entry
-    2009-03-25 11:00:50.171 : void MyClass::myMethod() exit
-    \endcode
-
-    \sa CNT_ENTRY_ARGS(args), CNT_EXIT.
-*/
-
-/*!
-    \def CNT_ENTRY_ARGS(args)
-    \brief A method entry trace macro with arguments for class methods.
-
-    CNT_ENTRY_ARGS(args) is similar to CNT_ENTRY but it allows arguments to be output on the
-    same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially
-    handy for outputting the parameters of the method call.
-
-    The following example shows proper usage of the CNT_ENTRY_ARGS(args)) macro. Assuming a
-    class has been declared with a non-static method that is implemented like this:
-
-    \code
-    #include <QString>
-    #include <cntdebug.h>
-
-    void MyClass::myMethod(const QString &text, int number)
-    {
-        CNT_ENTRY_ARGS("text =" << text << "number =" << number);
-
-        int i = 1;
-        i++;
-
-        CNT_EXIT
-    }
-    \endcode
-
-    calling myMethod(QString("foo"), 74) on an instance of MyClass generates output lines of the
-    following format:
-
-    \code
-    2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) this 0x6cdab90 entry, text = "foo" number = 74
-    2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) exit
-    \endcode
-
-    \param args Any number of arguments that can be streamed into a QTextStream, joined together
-    by the streaming operator <<.
-    \sa CNT_ENTRY, CNT_EXIT.
-*/
-
-/*!
-    \def CNT_EXIT
-    \brief A method exit trace macro for class methods or global functions.
-
-    Invoking CNT_EXIT outputs a timestamp followed by the scope in which the macro
-    was invoked and the word "exit".
-
-    CNT_EXIT is intended to be used as the last line of class methods and global functions,
-    just before the return statement, if any. There are two corresponding entry macros,
-    CNT_ENTRY and CNT_STATIC_ENTRY, depending on whether the method being traced is a
-    non-static or a static class method. CNT_EXIT makes no distinction between these two types
-    of methods and is to be used for both.
-
-    See CNT_ENTRY or CNT_STATIC_ENTRY for an example of how to use CNT_EXIT.
-
-    \sa CNT_EXIT_ARGS(args), CNT_ENTRY, CNT_STATIC_ENTRY.
-*/
-
-/*!
-    \def CNT_EXIT_ARGS(args)
-    \brief A method exit trace macro with arguments for class methods or global functions.
-
-    CNT_EXIT_ARGS(args) is similar to CNT_EXIT but it allows arguments to be output on the
-    same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially
-    handy for outputting the return value of the method call.
-
-    The following example shows proper usage of the CNT_EXIT_ARGS(args) macro. Assuming a
-    class has been declared with a static method that is implemented like this:
-
-    \code
-    #include <QString>
-    #include <cntdebug.h>
-
-    int MyClass::myStaticMethod(const QString &text)
-    {
-        CNT_STATIC_ENTRY_ARGS("text =" << text);
-
-        int length = text.length();
-
-        CNT_EXIT_ARGS("length" << length);
-
-        return length;
-    }
-    \endcode
-
-    calling MyClass::myStaticMethod(QString("foo")) generates output lines of the following format:
-
-    \code
-    2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) entry, text = "foo"
-    2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) exit, length 3
-    \endcode
-
-    Although the example above is a static method, CNT_EXIT_ARGS(args) works identically for
-    non-static class methods and global functions.
-
-    \param args Any number of arguments that can be streamed into a QTextStream, joined together
-    by the streaming operator <<.
-    \sa CNT_EXIT
-*/
-
-/*!
-    \def CNT_LOG
-    \brief A trace macro for class methods or global functions.
-
-    Invoking CNT_LOG outputs a timestamp followed by the scope in which the macro
-    was invoked and the this pointer value of the instance invoking the
-    macro.
-
-    CNT_LOG is similar to CNT_ENTRY but it is especially handy for marking calls to methods that
-    cannot fail, such as an empty constructor, without needing to resort to a separate CNT_EXIT call.
-
-    The following example shows proper usage of the CNT_LOG(args) macro. Assuming a
-    class has been declared with a static method that is implemented like this:
-
-    \code
-    #include <QString>
-    #include <cntdebug.h>
-
-    MyClass::MyClass()
-    {
-        CNT_LOG
-    }
-    \endcode
-
-    calling new MyClass() generates output lines of the following format:
-
-    \code
-    2009-03-25 13:20:36.448 : MyClass::MyClass() this 0x6cdab90
-    \endcode
-
-    \sa CNT_LOG_ARGS
-*/
-
-/*!
-    \def CNT_LOG_ARGS(args)
-    \brief A generic trace macro with arguments for class methods or global functions.
-
-    The following example shows how to produce arbitrary debug output:
-
-    \code
-    #include <QString>
-    #include <cntdebug.h>
-
-    void MyClass::myMethod()
-    {
-        CNT_ENTRY
-
-        QString myString("This is a string.");
-        int myValue = 109;
-
-        CNT_LOG_ARGS("this is a debug message, myString =" << myString << "myValue =" << myValue)
-
-        CNT_EXIT
-    }
-    \endcode
-
-    calling myMethod() on an instance of MyClass generates output lines of the following format:
-
-    \code
-    2009-03-25 13:45:22.083 : void MyClass::myMethod() this 0x6cdab90 entry
-    2009-03-25 13:45:22.083 : void MyClass::myMethod() this is a debug message, myString = "This is a string." myValue = 109
-    2009-03-25 13:45:22.083 : void MyClass::myMethod() exit
-    \endcode
-
-    Any number of arguments may be printed by chaining them together with the streaming operator
-    <<. Notice that a single space character is automatically added between each streamed
-    argument, hence the hardcoded strings in the example above, such as "myValue =", do not have
-    a space at the beginning and end of the string. This automatic space addition is a feature
-    of qDebug() streaming and cannot be disabled.
-
-    \param args Any number of arguments that can be streamed into a QTextStream, joined together
-    by the streaming operator <<.
-*/
-
-
-#ifdef _DEBUG
-    #define CNT_UNUSED(name)
-    #define CNT_STATIC_ENTRY qDebug() << __PRETTY_FUNCTION__ << "entry";
-    #define CNT_STATIC_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "entry," << args;
-    #define CNT_ENTRY qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry";
-    #define CNT_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry," << args;
-    #define CNT_EXIT qDebug() << __PRETTY_FUNCTION__ << "exit";
-    #define CNT_EXIT_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "exit," << args;
-    #define CNT_LOG qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this;
-    #define CNT_LOG_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << args;
-#else
-    #define CNT_UNUSED(name) Q_UNUSED(name)
-    #define CNT_STATIC_ENTRY
-    #define CNT_STATIC_ENTRY_ARGS(args)
-    #define CNT_ENTRY
-    #define CNT_ENTRY_ARGS(args)
-    #define CNT_EXIT
-    #define CNT_EXIT_ARGS(args)
-    #define CNT_LOG
-    #define CNT_LOG_ARGS(args)
-#endif // _DEBUG
-
-#endif // CNTDEBUG_H
--- a/phonebookui/inc/cntglobal.h	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
-* Copyright (c) 2008-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:
-*
-*/
-
-
-#ifndef CNTGLOBAL_H
-#define CNTGLOBAL_H
-
-#include <QtGlobal>
-
-#ifdef PBK_UNIT_TEST
-#define QTPBK_EXPORT
-#else
-#ifdef BUILD_QTPBK
-#define QTPBK_EXPORT Q_DECL_EXPORT
-#else
-#define QTPBK_EXPORT Q_DECL_IMPORT
-#endif
-#endif
-
-
-// Format: qtcontacts:<managerid>:<key>=<value>&<key>=<value>
-const QString SYMBIAN_BACKEND     = "qtcontacts:symbian:";
-const QString SIM_BACKEND         = "qtcontacts:symbiansim:";
-const QString SIM_BACKEND_ADN     = "qtcontacts:symbiansim:store=ADN";
-const QString SIM_BACKEND_SDN     = "qtcontacts:symbiansim:store=SDN";
-
-
-#endif // CNTGLOBAL_H
--- a/phonebookui/pbkcommonui/inc/cntaddressmodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntaddressmodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -22,6 +22,7 @@
 #include <hbdataformmodelitem.h>
 #include <qtcontacts.h>
 #include "cntglobal.h"
+#include <cntmaptileservice.h>
 
 QTM_BEGIN_NAMESPACE
 class QContact;
@@ -42,18 +43,17 @@
     
 private:
     void createAddressItems( HbDataFormModelItem* aGroup, QContactAddress* aAddress );
-    void saveAddressItems( HbDataFormModelItem* aGroup, QContactAddress* aAddress );
+    bool saveAddressItems( HbDataFormModelItem* aGroup, QContactAddress* aAddress );
     bool isAddressEmpty( QContactAddress* aAddress ) const;
 private:
     QContactAddress *mAddress;
     QContactAddress *mAddressHome;
     QContactAddress *mAddressWork;
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 protected:
-#endif
     bool mIsLocationPickerEnabled;
+    CntMapTileService* mMaptileInterface;
+	
+    friend class T_AddressEditorTest;
     };
 #endif /* CNTDETAILADDRESSEDITORMODEL_H_ */
--- a/phonebookui/pbkcommonui/inc/cntaddressviewitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntaddressviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -32,11 +32,7 @@
     CntAddressViewItem( QGraphicsItem* aParent = 0 );
     ~CntAddressViewItem();
 
-#ifdef PBK_UNIT_TEST
-public slots:
-#else
 private slots:
-#endif    
     void launchLocationPicker();
     
 public:
@@ -45,13 +41,10 @@
     
     bool canSetModelIndex( const QModelIndex &index ) const;
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif    
     void handleLocationChange(const QVariant& aValue );
 
+    friend class T_AddressEditorTest;
 };
 
 #endif /* CNTADDRESSVIEWITEM_H_ */
--- a/phonebookui/pbkcommonui/inc/cntbaseselectionview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntbaseselectionview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -18,8 +18,8 @@
 #ifndef CNTBASESELECTIONVIEW_H
 #define CNTBASESELECTIONVIEW_H
 
-#include "cntabstractviewmanager.h"
-#include "cntabstractview.h"
+#include <cntabstractviewmanager.h>
+#include <cntabstractview.h>
 #include "cntglobal.h"
 
 class HbListView;
--- a/phonebookui/pbkcommonui/inc/cntcollectionlistmodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntcollectionlistmodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -22,6 +22,7 @@
 #include <QAbstractListModel>
 #include <qmobilityglobal.h>
 #include <cntuigroupsupplier.h>
+#include <xqsettingsmanager.h>
 
 class CntExtensionManager;
 
@@ -73,6 +74,7 @@
     CntExtensionManager&                       mExtensionManager;
     QSharedDataPointer<CntCollectionListData>  mDataPointer;
     QContactManager                           *mContactManager;
+    XQSettingsManager                          mSettings;
     int                                        mFavoriteGroupId;
     
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/inc/cntcommondetailviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,43 @@
+/*
+* 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:
+*
+*/
+
+#ifndef CntCommonDetailViewItem_H
+#define CntCommonDetailViewItem_H
+
+#include "hbwidget.h"
+
+class HbComboBox;
+class HbLineEdit;
+
+class CntCommonDetailViewItem : public HbWidget
+{
+    Q_OBJECT
+    
+public:
+    CntCommonDetailViewItem(QGraphicsItem *aParent = 0);
+    
+    HbComboBox* comboBox() const;
+    HbLineEdit* editor() const;
+
+private:
+    HbComboBox*   mPhoneTypeSelector;
+    HbLineEdit*   mDataEditor;
+    
+    friend class T_CommonDetailViewItemTest;
+};
+
+#endif // CntCommonDetailViewItem_H
--- a/phonebookui/pbkcommonui/inc/cntcontactcarddatacontainer.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntcontactcarddatacontainer.h	Wed Jun 23 18:02:44 2010 +0300
@@ -20,7 +20,7 @@
 
 #include <QSharedData>
 #include <qtcontacts.h>
-
+#include <cntmaptileservice.h>
 #include "cntstringmapper.h"
 
 class CntContactCardDataItem;
@@ -30,7 +30,8 @@
     Q_OBJECT    
 
 public:
-    CntContactCardDataContainer(QContact* contact, QObject *parent = 0, bool myCard = false);
+    CntContactCardDataContainer(QContact* contact, QObject *parent = 0, bool myCard = false,
+            CntMapTileService* maptile = NULL );
     virtual ~CntContactCardDataContainer();
 
 public:
@@ -61,7 +62,7 @@
     int                             mSeparatorIndex;
     CntStringMapper                 mStringMapper;
     bool                            mLocationFeatureEnabled;
-
+    CntMapTileService*              mMaptileInterface;
 };
 
 #endif /* CNTCOMMLAUNCHERLISTMODEL_H_ */
--- a/phonebookui/pbkcommonui/inc/cntcontactcarddataitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntcontactcarddataitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -128,10 +128,10 @@
     QString                     mTitle;
     QString                     mValueText;
     QString                     mAction;
+    QContactActionDescriptor    mActionDescriptor;
     QContactDetail              mDetail;
     Qt::TextElideMode           mValueTextElideMode;
     bool                        mIsFocusable;
-    QContactActionDescriptor    mActionDescriptor;
     QString                     mLongPressText;
     
 public:
--- a/phonebookui/pbkcommonui/inc/cntcontactcarddetailitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntcontactcarddetailitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -48,6 +48,9 @@
     void recreatePrimitives();
     void updatePrimitives();
     void setDetails(CntContactCardDataItem* aDataItem);
+    //To update the secondary icon item. Used for
+    //maptile progress icon updation.
+    void setSecondaryIconItem( HbIcon aIcon );
     int index();
 
 public slots:
@@ -63,11 +66,7 @@
     HbIcon getIcon() const { return icon; }
     HbIcon getSecondaryIcon() const { return secondaryIcon; }
 
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
     HbIconItem              *mIcon;
     HbIconItem              *mSecondaryIcon;
     HbTextItem              *mFirstLineText;
@@ -84,7 +83,8 @@
     QString                 valueText;
     HbIcon                  icon;
     HbIcon                  secondaryIcon;
+    
+friend class TestCntContactCardDetailItem;
 };
 
 #endif // CNTCOMMLAUNCHERDETAILITEM_H
-
--- a/phonebookui/pbkcommonui/inc/cntcontactcardheadingitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntcontactcardheadingitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -31,13 +31,17 @@
 
 QTM_BEGIN_NAMESPACE
 class QContact;
+class QContactName;
 QTM_END_NAMESPACE
 
 QTM_USE_NAMESPACE
 
 class CntContactCardHeadingItem : public HbWidget
 {
+    friend class TestCntContactCardHeadingItem;
+    
     Q_OBJECT
+    
     Q_PROPERTY( QString first_line_text READ getFirstLineText )
     Q_PROPERTY( QString primary_text READ getPrimaryText )
     Q_PROPERTY( QString second_line_text READ getSecondLineText )
@@ -57,7 +61,7 @@
     void setDetails(const QContact* contact);
     void setIcon(const HbIcon newIcon);
     void setGroupDetails(const QContact* contact);
-    void setSecondaryIcon(bool favoriteContact);
+    void setFavoriteStatus(bool favoriteContact);
 
 signals:
     void clicked();
@@ -67,6 +71,7 @@
 public slots:
     void processLongPress(const QPointF &point);
     void processShortPress(const QPointF &point);
+    void setOnlineStatus(bool online);
 
 protected:
     void gestureEvent(QGestureEvent* event);
@@ -78,11 +83,8 @@
 private:
     void initGesture();
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
-private:
-#endif
+    void setSecondaryIcon();
+
     bool isNickName(const QContact* contact);
     bool isCompanyName(const QContact* contact);
 
@@ -94,12 +96,9 @@
 
     HbIcon getIcon() const { return icon; }
     HbIcon getSecondaryIcon() const { return secondaryIcon; }
+    QString createNameText(const QContactName name);
 
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
     HbIconItem              *mIcon;
     HbIconItem              *mSecondaryIcon;
     HbTextItem              *mFirstLineText;
@@ -117,6 +116,9 @@
     QString                 tinyMarqueeText;
     HbIcon                  icon;
     HbIcon                  secondaryIcon;
+    
+    bool                    mIsFavorite;
+    bool                    mIsOnline;
 };
 
 #endif // CNTHEADINGWIDGET_H
--- a/phonebookui/pbkcommonui/inc/cntcontactcardview_p.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntcontactcardview_p.h	Wed Jun 23 18:02:44 2010 +0300
@@ -24,6 +24,7 @@
 #include <QKeyEvent>
 #include <QGraphicsSceneResizeEvent>
 #include "cntglobal.h"
+#include <cntmaptileservice.h>
 
 class HbView;
 class HbScrollArea;
@@ -43,6 +44,7 @@
 class QStandardItemModel;
 class QModelIndex;
 class HbSelectionDialog;
+class CntPresenceListener;
 
 QTM_BEGIN_NAMESPACE
 class QContact;
@@ -53,6 +55,22 @@
 
 QTM_USE_NAMESPACE
 
+//To store the maptile request information
+class CntContactCardMapTileDetail 
+{
+public:
+    //Contact id 
+    int mContactId;
+    //Address type( preferred, home, work )
+    int mAddressType;
+    //Maptile status
+    int maptileStatus;
+    //Maptile progress icon animation count
+    int mProgressCount;
+    //Detial item containg contact address details
+    CntContactCardDetailItem* mDetailItem;
+};
+
 class CntContactCardViewPrivate : public QObject
 {
     Q_OBJECT
@@ -71,7 +89,7 @@
     void thumbnailReady(const QPixmap& pixmap, void *data, int id, int error);
     void drawMenu(const QPointF &aCoords);
     void sendToHs();
-    
+    void mapTileStatusReceived(int contactid, int addressType, int status);
     void keyPressed(QKeyEvent *event);
 
 private slots:
@@ -93,6 +111,13 @@
     
     void launchSendKeyAction(const QModelIndex &index);
     
+#ifdef PBK_UNIT_TEST
+public slots:
+#else
+private slots:
+#endif    
+	void updateSpinningIndicator();
+	
 public:
     CntContactCardView* q_ptr;    
     void activate(CntAbstractViewManager* aMgr, const CntViewParameters aArgs);
@@ -111,6 +136,7 @@
 #else
 private:
 #endif
+    void connectAction(QString actionName, const char* slot);
     void executeAction(QContact& aContact, QContactDetail aDetail, QString aAction);
     void executeDynamicAction(QContact& aContact, QContactDetail aDetail, QContactActionDescriptor aActionDescriptor);
     
@@ -145,6 +171,10 @@
     bool                        mAcceptSendKey;
     QStandardItemModel*         mSendKeyListModel;
     HbSelectionDialog*          mSendKeyPopup;
+    CntPresenceListener*        mPresenceListener; // own
+    CntMapTileService           *mMaptile;
+    QTimer                      *mProgressTimer;
+    QList <CntContactCardMapTileDetail*> mAddressList;
     
 };
 
--- a/phonebookui/pbkcommonui/inc/cntdateeditorviewitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntdateeditorviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -48,12 +48,10 @@
     void handleEditDate( HbAction *aAction );
     
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
     HbPushButton* mButton;
     QLocale mLocale;
+    
+    friend class T_DateEditorTest;
     };
 #endif /* CNTDATEEDITORVIEWITEM_H_ */
--- a/phonebookui/pbkcommonui/inc/cntdefaultviewmanager.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntdefaultviewmanager.h	Wed Jun 23 18:02:44 2010 +0300
@@ -55,6 +55,12 @@
     void deleteOldView();
     void switchView( const CntViewParameters aArgs, QFlags<Hb::ViewSwitchFlag> flags );
     
+protected slots:
+    virtual void closeApp();
+    
+private:
+    void cleanup();
+        
 private:
     CntAbstractViewFactory*      mFactory;
     CntAbstractView*             mCurrent;
--- a/phonebookui/pbkcommonui/inc/cntdetaileditor.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntdetaileditor.h	Wed Jun 23 18:02:44 2010 +0300
@@ -67,12 +67,7 @@
 private:    
     HbDocumentLoader* document();
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
-
     QPointer<HbDataForm>           mDataForm;
     CntDetailEditorModel           *mDataFormModel;
     QPointer<HbGroupBox>           mHeader;
@@ -84,5 +79,7 @@
     HbAction                       *mSoftkey;
     HbAction                       *mCancel;
     CntViewParameters               mArgs;
+    
+    friend class TestCntDetailEditor;
     };
 #endif /* CNTDETAILEDITOR_H_ */
--- a/phonebookui/pbkcommonui/inc/cntdetaileditormodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntdetaileditormodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -41,6 +41,8 @@
     inline QContact* contact() const;
     virtual QContactDetail detail() const = 0;
     
+    // Note that this method should not save anything if there's nothing to change.
+    // In otherwords, don't change the mContact pointer if not needed.
     virtual void saveContactDetails() = 0;
     virtual void insertDetailField(){}
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/inc/cntdetailorderinghelper.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,78 @@
+/*
+* 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:  
+*
+*/
+
+#ifndef CNTPHONENUMBERHELPER_H
+#define CNTPHONENUMBERHELPER_H
+
+#include <qmobilityglobal.h>
+#include <qtcontacts.h>
+
+QTM_BEGIN_NAMESPACE
+class QContact;
+QTM_END_NAMESPACE
+
+QTM_USE_NAMESPACE
+
+class CntDetailOrderingHelper
+{
+    
+    enum CntPhoneNumberPosition
+    { 
+        EMobile = 0,
+        EMobileHome,
+        EMobileWork,
+        EPhone,
+        EPhoneHome,
+        EPhoneWork,
+        EFax,
+        EFaxHome,
+        EFaxWork,
+        EPager,
+        EAssistant,
+        ECar
+    };
+    
+    enum CntOnlineAccountPosition
+    {
+        EInternetTelephone = 0,
+        EInternetTelephoneHome,
+        EInternetTelephoneWork,
+        ESip
+    };
+    
+    enum CntEmailAccountsPosition
+    {
+        EEmail = 0,
+        EEmailHome,
+        EEmailWork
+    };
+    
+    enum CntUrlPosition
+    {
+        EUrl = 0,
+        EUrlHome,
+        EUrlWork
+    };
+    
+public:
+    static QList<QContactPhoneNumber> getOrderedSupportedPhoneNumbers( const QContact& contact );
+    static QList<QContactOnlineAccount> getOrderedSupportedOnlineAccounts( const QContact& contact );
+    static QList<QContactEmailAddress> getOrderedEmailAccounts( const QContact& contact );
+    static QList<QContactUrl> getOrderedUrls( const QContact& contact );
+};
+
+#endif /* CNTPHONENUMBERHELPER_H */
--- a/phonebookui/pbkcommonui/inc/cnteditview_p.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cnteditview_p.h	Wed Jun 23 18:02:44 2010 +0300
@@ -42,6 +42,7 @@
 class HbMenu;
 
 QTM_BEGIN_NAMESPACE
+class QContact;
 class QContactDetail;
 class QContactId;
 QTM_END_NAMESPACE
@@ -94,6 +95,7 @@
     void addDetail( CntEditViewItem* aDetail );
     void editDetail( CntEditViewItem* aDetail );
     void removeDetail( CntEditViewItem* aDetail, const QModelIndex& aIndex );
+    void setSelectedContact( QContact aContact );
     
 public:
     HbView* mView;
--- a/phonebookui/pbkcommonui/inc/cnteditviewheadingitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cnteditviewheadingitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -35,6 +35,8 @@
 
 class CntEditViewHeadingItem : public HbWidget
 {
+    friend class TestCntEditViewHeadingItem;
+    
     Q_OBJECT
     Q_PROPERTY( QString text READ getText )
     Q_PROPERTY( QString second_text READ getSecond_text )
@@ -58,7 +60,7 @@
     void createPrimitives();
     void recreatePrimitives();
     void updatePrimitives();
-    void setDetails(const QContact* contact);
+    void setDetails(const QContact* contact, bool myCard);
 
     QString getText() const { return text; }
     QString getSecond_text() const { return second_text; }
@@ -69,11 +71,7 @@
 private slots:
     void orientationChanged(Qt::Orientation);
 
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
     HbIconItem              *mIcon;
     HbTextItem              *mLabel;
     HbTextItem              *mSecondLabel;
--- a/phonebookui/pbkcommonui/inc/cnteditviewlistmodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cnteditviewlistmodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -96,11 +96,7 @@
     void removeItem( KLookupKey aKey );
     void insertSeparator();
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
     QList<CntEditViewItem*> mItemList;
     CntExtensionManager* mManager;
     CntEditViewItemBuilder* mBuilder;
@@ -109,5 +105,7 @@
     
     QMap<KLookupKey, int> mLookupTable;
     QMap<QString, KLookupKey> mLookupMap;
+    
+    friend class TestCntEditView;
     };
 #endif /* CNTEDITVIEWLISTMODEL_H_ */
--- a/phonebookui/pbkcommonui/inc/cntemaileditormodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntemaileditormodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -23,6 +23,7 @@
 
 QTM_BEGIN_NAMESPACE
 class QContact;
+class QContactEmailAddress;
 QTM_END_NAMESPACE
 
 QTM_USE_NAMESPACE
@@ -39,6 +40,9 @@
     void insertDetailField();
     
     QContactDetail detail() const;
+    
+private:
+    QList<QContactEmailAddress> mAddressList;
     };
 
 #endif /* CNTEMAILEDITORMODEL_H_ */
--- a/phonebookui/pbkcommonui/inc/cntemaileditorviewitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntemaileditorviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -22,9 +22,7 @@
 
 class HbWidget;
 class HbAbstractViewItem;
-class HbComboBox;
-class HbLineEdit;
-class QGraphicsLinearLayout;
+class CntCommonDetailViewItem;
 
 class CntEmailEditorViewItem : public CntDetailViewItem
     {
@@ -41,18 +39,13 @@
 public slots:
     void indexChanged( int aIndex );    // HbComboBox index changed
     void textChanged( QString aText );  // HbLineEdit text changed
-    void changeOrientation(Qt::Orientation aOrient);
     
 private:
     void constructSubTypeModel( QStringList aContext );
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
-    HbComboBox*             mBox;
-    HbLineEdit*             mEdit;
-    QGraphicsLinearLayout*  mLayout;
+    CntCommonDetailViewItem*  mItem;
+    
+    friend class T_EmailEditorTest;
     };
 #endif /* CNTEMAILEDITORVIEWITEM_H_ */
--- a/phonebookui/pbkcommonui/inc/cntfetchcontactsview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntfetchcontactsview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -82,9 +82,6 @@
     void clicked();
     
 private:
-    friend class TestCntFetchUtility;
-
-private:
     HbDialog*                          mPopup;
     HbSearchPanel*                     mSearchPanel;
     CntListModel*                      mCntModel;
@@ -102,6 +99,9 @@
     HbAction*                          mPrimaryAction;
     HbAction*                          mSecondaryAction;
     HbIndexFeedback*                   mIndexFeedback;
+    
+    friend class TestCntFetchUtility;
+    friend class TestCntMyCardView;
     };
 
 #endif /* CntFetchContacts_H_ */
--- a/phonebookui/pbkcommonui/inc/cntgroupdeletepopup.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntgroupdeletepopup.h	Wed Jun 23 18:02:44 2010 +0300
@@ -19,7 +19,7 @@
 #define CNTGROUPDELETEPOPUP_H
 
 #include <QObject>
-#include <hbdialog.h>
+#include <hbselectiondialog.h>
 #include <qmobilityglobal.h>
 #include <qcontactid.h>
 #include "cntgroupdeletepopupmodel.h"
@@ -32,7 +32,7 @@
 
 QTM_USE_NAMESPACE
 
-class CntGroupDeletePopup : public HbDialog
+class CntGroupDeletePopup : public HbSelectionDialog
 {
     Q_OBJECT
 
--- a/phonebookui/pbkcommonui/inc/cntgroupeditormodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntgroupeditormodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -19,7 +19,6 @@
 #define CNTGROUPEDITORMODEL_H_
 #include "cntdetaileditormodel.h"
 #include <qtcontacts.h>
-#include "cntglobal.h"
 
 class HbDataFormModelItem;
 QTM_BEGIN_NAMESPACE
--- a/phonebookui/pbkcommonui/inc/cntgroupmemberview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntgroupmemberview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -88,6 +88,8 @@
     
 private:
     QContactManager* getContactManager();
+    void setRelationship(QSet<QContactLocalId>        &aLocalId,
+                         QList<QContactRelationship>  &aRelationshipList);
     
 private:
     QContact*                   mGroupContact; // own
--- a/phonebookui/pbkcommonui/inc/cntimageeditorview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntimageeditorview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -74,6 +74,8 @@
     void thumbnailReady( const QPixmap& pixmap, void *data, int id, int error );
     void setOrientation(Qt::Orientation orientation);
     void listViewActivated(const QModelIndex &index);
+    void handleError(int errorCode, const QString& errorMessage);
+
 
 #ifdef PBK_UNIT_TEST
 public:
--- a/phonebookui/pbkcommonui/inc/cntimportsview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntimportsview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -33,7 +33,6 @@
 class HbView;
 class HbAction;
 class QStandardItemModel;
-class SimUtility;
 class HbDialog;
 
 QTM_BEGIN_NAMESPACE
--- a/phonebookui/pbkcommonui/inc/cntmycardview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntmycardview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -46,15 +46,12 @@
 public: // From CntAbstractView
     void activate( CntAbstractViewManager* aMgr, const CntViewParameters aArgs );
     void deactivate();
-    bool isDefault() const { return false; }
-    HbView* view() const { return mView; }
-    int viewId() const { return myCardView; }
     
-#ifdef PBK_UNIT_TEST
-public slots:
-#else
+    inline bool isDefault() const { return false; }
+    inline HbView* view() const { return mView; }
+    inline int viewId() const { return myCardView; }
+    
 private slots:
-#endif
     void showPreviousView();
     void openNameEditor();
     void openMyCardSelectionView(); 
@@ -72,6 +69,8 @@
     HbView*                   mView; // own
     HbAction*                 mSoftkey;
     CntFetchContacts*         mFetchView;
+    
+    friend class TestCntMyCardView;
 };
 
 #endif /* CNTMYCARDVIEW_H_ */
--- a/phonebookui/pbkcommonui/inc/cntnamesview_p.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntnamesview_p.h	Wed Jun 23 18:02:44 2010 +0300
@@ -32,11 +32,10 @@
 class HbView;
 class HbListView;
 class HbGroupBox;
-class HbTextItem;
+class HbLabel;
 class HbDocumentLoader;
 class HbSearchPanel;
 class HbStaticVkbHost;
-class QGraphicsLinearLayout;
 class CntExtensionManager;
 class CntFetchContacts;
 
@@ -49,10 +48,7 @@
     CntNamesViewPrivate(CntExtensionManager &extensionManager);
     virtual ~CntNamesViewPrivate();
 
-public slots:
-    void showBanner( const QString aText );
-    void hideBanner();
-    
+public slots:    
     void showFinder();
     void hideFinder();
     void setFilter(const QString &filterString);
@@ -82,7 +78,6 @@
     void importSim();
     
     void handleContactAddition(const QList<QContactLocalId> & aAddedList);
-    void handleContactChanged(const QList<QContactLocalId> & aChangedList);
     void handleContactRemoval(const QList<QContactLocalId> & aRemovedList);
     void handleSelfContactIdChange(const QContactLocalId & aOldId, const QContactLocalId & aNewId);
     
@@ -93,16 +88,15 @@
     
 private:
     void disableDeleteAction();
+    void focusLineEdit();
+    void setFocusedContact();
+    void setScrollPosition();
     
 public:
     CntNamesView *q_ptr;
     
 public:  // lazy initializations
     HbListView *list();
-    HbTextItem *emptyLabel();
-    HbGroupBox *groupBox();
-    HbSearchPanel *search();
-    QGraphicsLinearLayout *layout();
     HbDocumentLoader *document();
     
 private:
@@ -111,13 +105,13 @@
     CntListModel*               mListModel;
     HbView*                     mView;
     HbListView*                 mListView;
-    HbTextItem*                 mEmptyList;
+    HbLabel*                    mEmptyList;
     HbGroupBox*                 mBanner;
     HbSearchPanel*              mSearchPanel;
     HbDocumentLoader*           mLoader;
-    QGraphicsLinearLayout*      mLayout;
     HbStaticVkbHost*            mVirtualKeyboard;
     HbAction*                   mSoftkey;
+    HbAction*                   mNamesAction;
     CntActionMenuBuilder*       mMenuBuilder;
     HbAction*                   mImportSim;
     HbAction*                   mNewContact;
@@ -127,6 +121,7 @@
     bool                        mIsDefault;
     int                         mId;
     QActionGroup*               mActionGroup;
+    QContactLocalId             mFocusedContact;
 };
 
 #endif /* CNTABSTRACTLISTVIEW_H_ */
--- a/phonebookui/pbkcommonui/inc/cntnoteeditormodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntnoteeditormodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -39,6 +39,9 @@
     void saveContactDetails();
     void insertDetailField();
     QContactDetail detail() const;
+    
+private:
+    QList<QContactNote> mNoteList;
     };
 
 #endif /* CNTNOTEEDITORMODEL_H_ */
--- a/phonebookui/pbkcommonui/inc/cntnoteeditorviewitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntnoteeditorviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -40,13 +40,11 @@
 public slots:
     void textChanged(const QString &text);
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
     HbLineEdit* mEdit;
     QGraphicsLinearLayout* mLayout;
+    
+    friend class T_NoteEditorTest;
     };
 
 #endif /* CNTNOTEEDITORVIEWITEM_H_ */
--- a/phonebookui/pbkcommonui/inc/cntphonenumbermodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntphonenumbermodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -26,6 +26,7 @@
 
 QTM_BEGIN_NAMESPACE
 class QContact;
+class QContactPhoneNumber;
 QTM_END_NAMESPACE
 
 QTM_USE_NAMESPACE
@@ -42,5 +43,10 @@
     void saveContactDetails();
     void insertDetailField();
     QContactDetail detail() const;
+    
+private:
+    QList<QContactDetail> mNumberList;
+    QContactPhoneNumber mMobileTemplate;
+    QContactPhoneNumber mLandlineTemplate;
     };
 #endif /* CNTPHONENUMBERMODELITEM_H_ */
--- a/phonebookui/pbkcommonui/inc/cntphonenumberviewitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntphonenumberviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -23,10 +23,8 @@
 
 class HbWidget;
 class HbAbstractViewItem;
-class HbComboBox;
-class HbLineEdit;
+class CntCommonDetailViewItem;
 class CntDetailModelItem;
-class QGraphicsLinearLayout;
 
 class CntPhoneNumberViewItem : public CntDetailViewItem
     {
@@ -43,20 +41,15 @@
 public slots:
     void indexChanged( int aIndex );    // HbComboBox index changed
     void textChanged( QString aText );  // HbLineEdit text changed
-    void changeOrientation(Qt::Orientation aOrient);
-    
+   
 private:
     void constructSubtypeModel( QString aSubType, QStringList aContext );
     void constructPhoneNumber(CntDetailModelItem* aItem, QString aSubType, QStringList aContext );
     void constructOnlineAccount( CntDetailModelItem* aItem, QString aSubType, QStringList aContext );
   
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
-    HbComboBox*             mBox;
-    HbLineEdit*             mEdit;
-    QGraphicsLinearLayout*  mLayout;
+    CntCommonDetailViewItem*   mItem; // Ownership transfered
+    
+    friend class T_NumberEditorTest;
     };
 #endif /* CNTPHONENUMBERVIEWITEM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/inc/cntpresencelistener.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* 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:
+*
+*/
+
+#ifndef CNTPRESENCELISTENER_H
+#define CNTPRESENCELISTENER_H
+
+#include <QObject>
+#include <qtcontacts.h>
+#include <QMap>
+
+class PrcPresenceReader;
+class PrcPresenceBuddyInfoQt;
+
+QTM_BEGIN_NAMESPACE
+class QContact;
+QTM_END_NAMESPACE
+
+QTM_USE_NAMESPACE
+
+class CntPresenceListener : public QObject
+{
+    friend class TestCntPresenceListener;
+    
+    Q_OBJECT
+    
+public:
+    CntPresenceListener(const QContact& contact, QObject* parent = NULL);
+    ~CntPresenceListener();
+    
+    QMap<QString, bool> initialPresences(bool &combinedOnlineStatus);
+    
+private slots:
+    void handlePresenceUpdate(bool aSuccess, PrcPresenceBuddyInfoQt* aPresenceBuddyInfo);
+    
+private:
+    bool parsePresence(QList<PrcPresenceBuddyInfoQt*> buddyList);
+    
+signals:
+    void accountPresenceUpdated(QString accountUri, bool online);
+    void fullPresenceUpdated(bool online);
+    
+private:
+    PrcPresenceReader*  mReader; // own
+    QStringList         mAccountList;
+    
+    const QContact&     mContact;
+    
+};
+
+#endif // CNTPRESENCELISTENER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/inc/cntsettingsmodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,46 @@
+/*
+* 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:  
+*
+*/
+
+#ifndef CNTSETTINGSMODEL_H
+#define CNTSETTINGSMODEL_H
+
+#include <hbdataformmodel.h>
+#include <hbdataformmodelitem.h>
+#include <xqsettingsmanager.h>
+
+class XQSettingsKey;
+
+/**
+* Model class for populating the settings view with the value choices
+*/
+class CntSettingsModel : public HbDataFormModel
+{
+    Q_OBJECT
+    
+public:
+    CntSettingsModel();
+    ~CntSettingsModel();
+
+private slots:
+    void handleDataChanged(QModelIndex topLeft, QModelIndex bottomRight);
+    
+private:
+    XQSettingsManager mSettings;
+    XQSettingsKey *mNameOrderkey;
+};
+
+#endif
--- a/phonebookui/pbkcommonui/inc/cntsettingsview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntsettingsview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -19,39 +19,12 @@
 
 #include <cntabstractview.h>
 #include <QObject>
-#include <hbdataformmodel.h>
 
 class HbAction;
 class HbView;
 class HbDataForm;
-class HbDataFormModelItem;
 class HbDocumentLoader;
-
-class CntSettingsModel : public HbDataFormModel
-{
-    Q_OBJECT
-    
-public:
-    virtual ~CntSettingsModel(){}
-    virtual void saveSettings() = 0;
-    virtual void loadSettings() = 0;
-};
-
-class CntDefaultSettingsModel : public CntSettingsModel
-{
-    Q_OBJECT
-    
-public:
-    CntDefaultSettingsModel();
-    ~CntDefaultSettingsModel();
-    
-public:
-    void saveSettings();
-    void loadSettings();
-    
-private:
-    HbDataFormModelItem* mOrder;
-};
+class CntSettingsModel;
 
 class CntSettingsView : public QObject, public CntAbstractView
 {
@@ -67,7 +40,7 @@
     bool isDefault() const;
     HbView* view() const;
     int viewId() const;
-    
+
 private slots:
     void back();
     
@@ -85,7 +58,7 @@
     
     CntSettingsModel* mModel;
     
-    friend class TestCntEditView;
+    friend class TestCntSettings;
 };
 #endif
 
--- a/phonebookui/pbkcommonui/inc/cntstringmapper.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cntstringmapper.h	Wed Jun 23 18:02:44 2010 +0300
@@ -55,9 +55,9 @@
         mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeLandline, "", "qtg_small_landline"));
         mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextHome, "qtg_small_landline_home"));
         mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextWork, "qtg_small_landline_work"));
-        mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", "qtg_small_fax"));
-        mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, "qtg_small_fax_home"));
-        mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, "qtg_small_fax_work"));
+        mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeFax, "", "qtg_small_fax"));
+        mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, "qtg_small_fax_home"));
+        mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, "qtg_small_fax_work"));
         mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypePager, "", "qtg_small_pager"));
         mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeCar, "", "qtg_small_car"));
         mContactEditorIconList.append(Loc(QContactPhoneNumber::SubTypeAssistant, "", "qtg_small_assistant"));
@@ -86,9 +86,9 @@
         mContactEditorLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, "", hbTrId("txt_phob_dblist_internet_telephone")));
         mContactEditorLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, QContactDetail::ContextHome, hbTrId("txt_phob_dblist_internet_telephone_home")));
         mContactEditorLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, QContactDetail::ContextWork, hbTrId("txt_phob_dblist_internet_telephone_work")));
-        mContactEditorLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", hbTrId("txt_phob_dblist_fax")));
-        mContactEditorLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, hbTrId("txt_phob_dblist_fax_home")));
-        mContactEditorLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, hbTrId("txt_phob_dblist_fax_work")));
+        mContactEditorLocList.append(Loc(QContactPhoneNumber::SubTypeFax, "", hbTrId("txt_phob_dblist_fax")));
+        mContactEditorLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, hbTrId("txt_phob_dblist_fax_home")));
+        mContactEditorLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, hbTrId("txt_phob_dblist_fax_work")));
         mContactEditorLocList.append(Loc(QContactOnlineAccount::SubTypeSip, "", hbTrId("txt_phob_dblist_ptt")));
 
         //editor list item specific menu items
@@ -116,9 +116,9 @@
         mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, "",hbTrId("txt_phob_menu_edit_phone")));
         mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextHome, hbTrId("txt_phob_menu_edit_phone_home")));
         mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextWork, hbTrId("txt_phob_menu_edit_phone_work")));
-        mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", hbTrId("txt_phob_menu_edit_fax")));
-        mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, hbTrId("txt_phob_menu_edit_fax_home")));
-        mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, hbTrId("txt_phob_menu_edit_fax_work")));
+        mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeFax, "", hbTrId("txt_phob_menu_edit_fax")));
+        mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, hbTrId("txt_phob_menu_edit_fax_home")));
+        mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, hbTrId("txt_phob_menu_edit_fax_work")));
         mContactEditorEditLocList.append(Loc(QContactPhoneNumber::SubTypePager, "", hbTrId("txt_phob_menu_edit_pager")));
         mContactEditorEditLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, "", hbTrId("txt_phob_menu_edit_internet_telephone")));
         mContactEditorEditLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, QContactDetail::ContextHome, hbTrId("txt_phob_menu_edit_internet_telephone_home")));
@@ -155,9 +155,9 @@
         mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, "",hbTrId("txt_phob_menu_delete_phone")));
         mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextHome, hbTrId("txt_phob_menu_delete_phone_home")));
         mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextWork, hbTrId("txt_phob_menu_delete_phone_work")));
-        mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", hbTrId("txt_phob_menu_delete_fax")));
-        mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, hbTrId("txt_phob_menu_delete_fax_home")));
-        mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, hbTrId("txt_phob_menu_delete_fax_work")));
+        mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeFax, "", hbTrId("txt_phob_menu_delete_fax")));
+        mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, hbTrId("txt_phob_menu_delete_fax_home")));
+        mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, hbTrId("txt_phob_menu_delete_fax_work")));
         mContactEditorDelLocList.append(Loc(QContactPhoneNumber::SubTypePager, "", hbTrId("txt_phob_menu_delete_pager")));
         mContactEditorDelLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, "", hbTrId("txt_phob_menu_delete_internet_telephone")));
         mContactEditorDelLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, QContactDetail::ContextHome, hbTrId("txt_phob_menu_delete_internet_telephone_home")));
@@ -195,9 +195,9 @@
         mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, "",hbTrId("txt_phob_menu_call_phone")));
         mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextHome, hbTrId("txt_phob_menu_call_phone_home")));
         mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextWork, hbTrId("txt_phob_menu_call_phone_work")));
-        mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", hbTrId("txt_phob_menu_fax")));
-        mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, hbTrId("txt_phob_menu_fax_home")));
-        mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, hbTrId("txt_phob_menu_fax_work")));
+        mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeFax, "", hbTrId("txt_phob_menu_fax")));
+        mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, hbTrId("txt_phob_menu_fax_home")));
+        mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, hbTrId("txt_phob_menu_fax_work")));
         mItemSpecificMenuLocList.append(Loc(QContactPhoneNumber::SubTypePager, "", hbTrId("txt_phob_menu_call_pager")));
         mItemSpecificMenuLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, "", hbTrId("txt_phob_menu_call_internet_call")));
         mItemSpecificMenuLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, QContactDetail::ContextHome, hbTrId("txt_phob_menu_call_internet_call_home")));
@@ -226,9 +226,9 @@
         mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, "",hbTrId("txt_phob_dblist_call_phone")));
         mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextHome, hbTrId("txt_phob_dblist_call_phone_home")));
         mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextWork, hbTrId("txt_phob_dblist_call_phone_work")));
-        mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", hbTrId("txt_phob_dblist_fax")));
-        mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, hbTrId("txt_phob_dblist_fax_home")));
-        mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, hbTrId("txt_phob_dblist_fax_work")));
+        mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeFax, "", hbTrId("txt_phob_dblist_fax")));
+        mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, hbTrId("txt_phob_dblist_fax_home")));
+        mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, hbTrId("txt_phob_dblist_fax_work")));
         mContactCardLocList.append(Loc(QContactPhoneNumber::SubTypePager, "", hbTrId("txt_phob_dblist_call_pager")));
         mContactCardLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, "", hbTrId("txt_phob_formlabel_internet_telephone")));
         mContactCardLocList.append(Loc(QContactOnlineAccount::SubTypeSipVoip, QContactDetail::ContextHome, hbTrId("txt_phob_formlabel_internet_telephone_home")));
@@ -251,9 +251,9 @@
         mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeLandline, "", "qtg_large_call_landline"));
         mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextHome, "qtg_large_call_landline_home"));
         mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeLandline, QContactDetail::ContextWork, "qtg_large_call_landline_work"));
-        mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, "", "qtg_large_call_fax"));
-        mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextHome, "qtg_large_call_fax_home"));
-        mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeFacsimile, QContactDetail::ContextWork, "qtg_large_call_fax_work"));
+        mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeFax, "", "qtg_large_call_fax"));
+        mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextHome, "qtg_large_call_fax_home"));
+        mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeFax, QContactDetail::ContextWork, "qtg_large_call_fax_work"));
         mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypePager, "", "qtg_large_call_pager"));
         mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeCar, "", "qtg_large_call_car"));
         mContactCardIconList.append(Loc(QContactPhoneNumber::SubTypeAssistant, "", "qtg_large_call_assistant"));
--- a/phonebookui/pbkcommonui/inc/cnturleditormodel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cnturleditormodel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -39,5 +39,8 @@
     void saveContactDetails();
     void insertDetailField();
     QContactDetail detail() const;
+    
+private:
+    QList<QContactUrl> mUrlList;
     };
 #endif /* CNTURLEDITORMODEL_H_ */
--- a/phonebookui/pbkcommonui/inc/cnturleditorviewitem.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/inc/cnturleditorviewitem.h	Wed Jun 23 18:02:44 2010 +0300
@@ -23,7 +23,8 @@
 #include <hbwidget.h>
 #include <hbcombobox.h>
 #include <hblineedit.h>
-#include <qgraphicslinearlayout.h>
+
+class CntCommonDetailViewItem;
 
 class CntUrlEditorViewItem : public CntDetailViewItem
     {
@@ -40,19 +41,14 @@
 public slots:
     void indexChanged( int aIndex );    // HbComboBox index changed
     void textChanged( QString aText );  // HbLineEdit text changed
-    void changeOrientation(Qt::Orientation aOrient);
     
 private:
     void constructSubTypeModel( QStringList aContext );
     
-#ifdef PBK_UNIT_TEST
-public:
-#else
 private:
-#endif
-    HbComboBox*             mBox;
-    HbLineEdit*             mEdit;
-    QGraphicsLinearLayout*  mLayout; 
+    CntCommonDetailViewItem*    mItem;
+    
+    friend class T_UrlEditorTest;
     };
 
 #endif /* CNTURLEDITORVIEWITEM_H_ */
--- a/phonebookui/pbkcommonui/inc/qlocationpickeritem_temp.h	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/*
-* 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:
-*
-*/
-
-#ifndef QLOCATIONPICKERITEM_H
-#define QLOCATIONPICKERITEM_H
-
-#include <QString>
-#include <xqserviceipcmarshal.h>
-
-/** class defines location type
-  */
-class QLocationPickerItem
-{
-public:
-    QLocationPickerItem():mIsValid(false)
-     {};
-    ~QLocationPickerItem() {};
-
-    // copy contructor
-    inline QLocationPickerItem(const QLocationPickerItem &l)
-    {
-    		mIsValid = l.mIsValid;
-        mName = l.mName;
-        mStreet = l.mStreet;
-        mPostalCode = l.mPostalCode;
-        mCity = l.mCity;
-        mState = l.mState;
-        mCountry = l.mCountry;
-        mLatitude = l.mLatitude;
-        mLongitude = l.mLongitude;
-    };
-
-    // assignment operator
-    inline QLocationPickerItem &operator=(const QLocationPickerItem &l)
-    {
-    		mIsValid = l.mIsValid;
-        mName = l.mName;
-        mStreet = l.mStreet;
-        mPostalCode = l.mPostalCode;
-        mCity = l.mCity;
-        mState = l.mState;
-        mCountry = l.mCountry;
-        mLatitude = l.mLatitude;
-        mLongitude = l.mLongitude;
-        return *this;
-    };
-
-		bool mIsValid; // if the current object is valid
-    QString mName; // location name
-    QString mStreet; // location street
-    QString mPostalCode; // location postal code
-    QString mCity; // location city
-    QString mState; // location state/region
-    QString mCountry; // location country
-    double mLatitude; // latitude
-    double mLongitude; // longitude
-
-    // functions to pass data between application
-    template <typename Stream> void serialize(Stream &stream) const;
-    template <typename Stream> void deserialize(Stream &stream);
-};
-
-template <typename Stream> inline void QLocationPickerItem::serialize(Stream &s) const
-{
-	  s << mIsValid;
-    s << mName;
-    s << mStreet;
-    s << mPostalCode;
-    s << mCity;
-    s << mState;
-    s << mCountry;
-    s << mLatitude;
-    s << mLongitude;
-}
-
-template <typename Stream> inline void QLocationPickerItem::deserialize(Stream &s)
-{
-		s >> mIsValid;
-    s >> mName;
-    s >> mStreet;
-    s >> mPostalCode;
-    s >> mCity;
-    s >> mState;
-    s >> mCountry;
-    s >> mLatitude;
-    s >> mLongitude;
-}
-
-
-Q_DECLARE_USER_METATYPE(QLocationPickerItem)
-
-#endif // QLOCATIONPICKERITEM_H
--- a/phonebookui/pbkcommonui/pbkcommonui.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/pbkcommonui.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -26,12 +26,13 @@
 
 DEPENDPATH += .
 INCLUDEPATH += .
-INCLUDEPATH += ../inc
+INCLUDEPATH += ../../inc
 INCLUDEPATH += ../../phonebookengines/cntimageutility/inc
 INCLUDEPATH += ../../phonebookengines/cntsimutility/inc
 
 INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
 
+
 MOC_DIR = moc
 
 DEFINES += QT_DLL BUILD_QTPBK
@@ -47,7 +48,7 @@
         :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_api/inc/cntviewparams.h APP_LAYER_PLATFORM_EXPORT_PATH(cntviewparams.h)"
         :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_api/inc/cntabstractview.h APP_LAYER_PLATFORM_EXPORT_PATH(cntabstractview.h)"
         :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_api/inc/cntabstractviewmanager.h APP_LAYER_PLATFORM_EXPORT_PATH(cntabstractviewmanager.h)"
-        :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_api/inc/cntcenrepkeys.h APP_LAYER_PLATFORM_EXPORT_PATH(cntcenrepkeys.h)"
+        :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_api/inc/cntuids.h APP_LAYER_PLATFORM_EXPORT_PATH(cntuids.h)"
 
         :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_extensions_api/inc/cntuiextensionfactory.h APP_LAYER_PLATFORM_EXPORT_PATH(cntuiextensionfactory.h)"
         :BLD_INF_RULES.prj_exports += "../../contacts_plat/contacts_ui_extensions_api/inc/cntuigroupsupplier.h APP_LAYER_PLATFORM_EXPORT_PATH(cntuigroupsupplier.h)"
@@ -127,7 +128,13 @@
     inc/cntimagelabel.h \
     inc/cntfetchcontactsview.h \
     inc/cntimportsview.h \
-    inc/cntsettingsview.h
+    inc/cntsettingsview.h \
+    inc/cntpresencelistener.h \
+    inc/cntdetailorderinghelper.h \
+    inc/cntsettingsmodel.h \
+    inc/cntcommondetailviewitem.h \
+    ../../inc/cntdebug.h \
+    
     
 SOURCES += \
 	src/cntviewnavigator.cpp \
@@ -193,7 +200,11 @@
     src/cntimportsview.cpp \
     src/cntfetchcontactsview.cpp \
     src/cntsettingsview.cpp \
-    src/cntsettingsmodel.cpp
+    src/cntpresencelistener.cpp \
+    src/cntdetailorderinghelper.cpp \
+    src/cntsettingsmodel.cpp \
+    src/cntcommondetailviewitem.cpp
+    
     
 RESOURCES += resources\pbkcommonui.qrc
 
@@ -207,9 +218,17 @@
        -lqtversit \
        -lcntimageutility \
        -lcntsimutility \
-       -lshareui
+       -lshareui \
+       -lpresencecacheqt \
+       -lxqsettingsmanager
 
 # capability
 TARGET.CAPABILITY = CAP_GENERAL_DLL
+defBlock = \      
+	"$${LITERAL_HASH}if defined(EABI)" \
+		"DEFFILE  ../eabi/pbkcommonui.def" \
+    "$${LITERAL_HASH}else" \
+        "DEFFILE  ../bwins/pbkcommonui.def" \
+	"$${LITERAL_HASH}endif"
+MMP_RULES += defBlock
 
-
--- a/phonebookui/pbkcommonui/resources/contacts_detail_editor.docml	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/resources/contacts_detail_editor.docml	Wed Jun 23 18:02:44 2010 +0300
@@ -1,8 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <hbdocument version="1.0">
-    <object name="cnt:Insert" type="HbAction">
-        <string name="text" value="Insert"/>
-    </object>
     <object name="cnt:discardchanges" type="HbAction">
          <string locid="txt_phob_opt_discard_changes" name="text" value="Discard Changes"/>
     </object>
--- a/phonebookui/pbkcommonui/resources/contacts_groupmembers.docml	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/resources/contacts_groupmembers.docml	Wed Jun 23 18:02:44 2010 +0300
@@ -17,9 +17,10 @@
     <widget name="view" type="HbView">
         <widget name="content" role="HbView:widget" type="HbWidget">
         	<widget name="listView" type="HbListView">
-                <widget name="listItemPrototype" role="HbListView:prototype" type="HbListViewItem">
-                    <enums name="graphicsSize" value="Image"/>
+                <widget name="listItemPrototype" role="HbAbstractView:prototype" type="HbListViewItem">
+                    <enums name="graphicsSize" value="Thumbnail"/>
                     <string name="state" value="normal"/>
+                    <fontspec name="fontSpec" role="Primary" textheight="26.8"/>
                 </widget>
                 <sizehint height="47.7612un" type="PREFERRED" width="35.8209un"/>
             </widget>
@@ -67,15 +68,15 @@
                 <bool name="visible" value="TRUE"/>
             </widget>
             <layout type="anchor">
-            	<anchoritem src="editViewImage" srcEdge="LEFT" spacing="0.0un" dst="" dstEdge="LEFT"/>
-                <anchoritem src="editViewImage" srcEdge="TOP" spacing="0.0un" dst="" dstEdge="TOP"/>
-                <anchoritem src="editViewImage" srcEdge="RIGHT" spacing="0.0un" dst="editViewHeading" dstEdge="LEFT"/>
-                <anchoritem src="editViewHeading" srcEdge="TOP" spacing="0.0un" dst="" dstEdge="TOP"/>
-                <anchoritem src="editViewHeading" srcEdge="BOTTOM" spacing="0.0un" dst="listView" dstEdge="TOP"/>
-                <anchoritem src="editViewHeading" srcEdge="RIGHT" spacing="0.0un" dst="" dstEdge="RIGHT"/>
-                <anchoritem src="listView" srcEdge="LEFT" dst="editViewHeading" dstEdge="LEFT"/>
-                <anchoritem src="listView" srcEdge="RIGHT" dst="editViewHeading" dstEdge="RIGHT"/>
-                <anchoritem src="listView" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM"/>
+                <anchoritem dst="" dstEdge="TOP" spacing="0un" src="editViewHeading" srcEdge="TOP"/>
+                <anchoritem dst="listView" dstEdge="TOP" spacing="0un" src="editViewHeading" srcEdge="BOTTOM"/>
+                <anchoritem dst="" dstEdge="RIGHT" spacing="0un" src="editViewHeading" srcEdge="RIGHT"/>
+                <anchoritem dst="editViewHeading" dstEdge="RIGHT" spacing="0un" src="listView" srcEdge="RIGHT"/>
+                <anchoritem dst="" dstEdge="BOTTOM" spacing="0un" src="listView" srcEdge="BOTTOM"/>
+                <anchoritem dst="editViewHeading" dstEdge="LEFT" spacing="0un" src="listView" srcEdge="LEFT"/>
+                <anchoritem dst="editViewHeading" dstEdge="LEFT" spacing="var(hb-param-margin-gene-left)" src="editViewImage" srcEdge="RIGHT"/>
+                <anchoritem dst="" dstEdge="LEFT" spacing="-var(hb-param-margin-gene-left)" src="editViewImage" srcEdge="LEFT"/>
+                <anchoritem dst="" dstEdge="TOP" spacing="-var(hb-param-margin-gene-top)" src="editViewImage" srcEdge="TOP"/>
             </layout>
         </widget>
     </section>
--- a/phonebookui/pbkcommonui/resources/contacts_mc.docml	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/resources/contacts_mc.docml	Wed Jun 23 18:02:44 2010 +0300
@@ -12,7 +12,7 @@
                 <contentsmargins bottom="var(hb-param-margin-gene-bottom)" left="var(hb-param-margin-gene-left)" right="var(hb-param-margin-gene-right)" top="0un"/>
                 <enums name="elideMode" value="ElideNone"/>
                 <string locid="txt_phob_info_create_own_card_to_share_it_with_fri" name="plainText"/>
-                <fontspec name="fontSpec" role="Primary" textheight="0"/>
+                <fontspec name="fontSpec" role="Primary"/>
             </widget>
             <widget name="cnt_button_new" type="HbPushButton">
                 <string locid="txt_phob_button_create_new" name="text"/>
--- a/phonebookui/pbkcommonui/resources/contacts_namelist.docml	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/resources/contacts_namelist.docml	Wed Jun 23 18:02:44 2010 +0300
@@ -26,16 +26,29 @@
     <object name="cnt:settings" type="HbAction">
     	<string locid="txt_common_opt_settings" name="text" value="Settings"/>
     </object>
+
     <widget name="view" type="HbView">
         <widget name="content" role="HbView:widget" type="HbWidget">
+        	<widget name="banner" type="HbGroupBox">
+            	<string locid="txt_phob_subtitle_find_all_contacts" name="heading"/>
+                <bool name="collapsable" value="FALSE"/>
+                <bool name="visible" value="FALSE"/>
+            </widget>
+            <widget name="emptyLabel" type="HbLabel">
+                <fontspec name="fontSpec" role="Primary"/>
+                <string name="alignment" value="AlignCenter"/>
+                <string locid="txt_phob_info_no_matching_contacts" name="plainText"/>
+                <sizepolicy horizontalPolicy="MinimumExpanding" horizontalStretch="0" verticalPolicy="MinimumExpanding" verticalStretch="0"/>
+                <bool name="visible" value="FALSE"/>
+            </widget>
             <widget name="listView" type="HbListView">
                 <sizehint height="1.0un" type="PREFERRED" width="1.0un"/>
                 <sizepolicy horizontalPolicy="MinimumExpanding" horizontalStretch="0" verticalPolicy="MinimumExpanding" verticalStretch="0"/>
+                <bool name="visible" value="FALSE"/>
             </widget>
-            <layout orientation="Vertical" spacing="0un" type="linear">
-                <contentsmargins bottom="0un" left="0un" right="0un" top="0un"/>
-                <linearitem itemname="listView"/>
-            </layout>
+            <widget name="searchPanel" type="HbSearchPanel">
+                <bool name="visible" value="FALSE"/>
+            </widget>
         </widget>
         <widget name="viewToolbar" role="HbView:toolBar" type="HbToolBar">
             <enums name="orientation" value="Horizontal"/>
@@ -49,11 +62,95 @@
             <ref object="cnt:newcontact" role="HbMenu:addAction"/>
 			<ref object="cnt:delete" role="HbMenu:addAction"/>
             <ref object="cnt:importsim" role="HbMenu:addAction"/>
+            <ref object="cnt:settings" role="HbMenu:addAction"/>
         </widget>
         <string locid="txt_phob_title_contacts" name="title" value="Contacts"/>
+        <bool name="contentFullScreen" value="FALSE"/>
     </widget>
+
+    <section name="no_find">
+        <widget name="view" type="HbView">
+            <widget name="content" role="HbView:widget" type="HbWidget">
+            	<widget name="banner" type="HbGroupBox">
+                    <bool name="visible" value="FALSE"/>
+                </widget>
+                <widget name="emptyLabel" type="HbLabel">
+                    <bool name="visible" value="FALSE"/>
+                </widget>
+                <widget name="listView" type="HbListView">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <widget name="searchPanel" type="HbSearchPanel">
+                    <bool name="visible" value="FALSE"/>
+                </widget>
+                <layout orientation="Vertical" spacing="0un" type="linear">
+                    <contentsmargins bottom="0un" left="0un" right="0un" top="0un"/>
+                    <linearitem itemname="listView"/>
+                </layout>
+            </widget>
+            <string locid="txt_phob_title_contacts" name="title" value="Contacts"/>
+            <bool name="contentFullScreen" value="FALSE"/>
+        </widget>
+    </section>
+
+    <section name="find_list">
+        <widget name="view" type="HbView">
+            <widget name="content" role="HbView:widget" type="HbWidget">
+            	<widget name="banner" type="HbGroupBox">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <widget name="emptyLabel" type="HbLabel">
+                    <bool name="visible" value="FALSE"/>
+                </widget>
+                <widget name="listView" type="HbListView">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <widget name="searchPanel" type="HbSearchPanel">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <layout orientation="Vertical" spacing="0un" type="linear">
+                    <contentsmargins bottom="0un" left="0un" right="0un" top="0un"/>
+                    <linearitem itemname="banner"/>
+                    <linearitem itemname="listView"/>
+                    <linearitem itemname="searchPanel"/>
+                </layout>
+            </widget>
+            <string locid="txt_phob_title_contacts" name="title" value="Contacts"/>
+            <bool name="contentFullScreen" value="TRUE"/>
+        </widget>
+    </section>
+
+    <section name="find_empty">
+        <widget name="view" type="HbView">
+            <widget name="content" role="HbView:widget" type="HbWidget">
+            	<widget name="banner" type="HbGroupBox">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <widget name="emptyLabel" type="HbLabel">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <widget name="listView" type="HbListView">
+                    <bool name="visible" value="FALSE"/>
+                </widget>
+                <widget name="searchPanel" type="HbSearchPanel">
+                    <bool name="visible" value="TRUE"/>
+                </widget>
+                <layout orientation="Vertical" spacing="0un" type="linear">
+                    <contentsmargins bottom="0un" left="0un" right="0un" top="0un"/>
+                    <linearitem itemname="banner"/>
+                    <linearitem itemname="emptyLabel"/>
+                    <linearitem itemname="searchPanel"/>
+                </layout>
+            </widget>
+            <string locid="txt_phob_title_contacts" name="title" value="Contacts"/>
+            <bool name="contentFullScreen" value="TRUE"/>
+        </widget>
+    </section>
+
     <metadata activeUIState="Common ui state" display="NHD portrait" unit="un">
-        <resource location="pbkcommonui.qrc"/>
         <uistate name="Common ui state" sections="#common"/>
+        <uistate name="no_find" sections="#common no_find"/>
+        <uistate name="find_list" sections="#common find_list"/>
+        <uistate name="find_empty" sections="#common find_empty"/>
     </metadata>
 </hbdocument>
--- a/phonebookui/pbkcommonui/resources/pbkcommonui.qrc	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/resources/pbkcommonui.qrc	Wed Jun 23 18:02:44 2010 +0300
@@ -36,5 +36,7 @@
         <file alias="cnthistoryviewitem.css">style/cnthistoryviewitem.css</file>
         <file alias="cntlocationbutton.hbpushbutton.widgetml">style/cntlocationbutton.hbpushbutton.widgetml</file>
         <file alias="cntlocationbutton.css">style/cntlocationbutton.css</file>
+        <file alias="cntcommondetailviewitem.widgetml">style/cntcommondetailviewitem.widgetml</file>
+        <file alias="cntcommondetailviewitem.css">style/cntcommondetailviewitem.css</file>
     </qresource>
 </RCC>
--- a/phonebookui/pbkcommonui/resources/phonebook.svg	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="tiny" height="44.006px" version="1.1" viewBox="0 0 44 44.006" width="44px" x="0px" y="0px">
-<path d="M36.504,34.804V8.949c0-2.279-1.642-3.086-3.047-3.086L9.928,5.869c-0.553,0-1,0.447-1,1v2.47  c-1.113,0-1.935,0.815-1.935,1.819c0,1.001,0.712,1.817,1.935,1.817v3.434c-1.113,0-1.935,0.815-1.935,1.819  c0,1.001,0.759,1.817,1.935,1.817v3.485c-1.145,0-1.935,0.815-1.935,1.819c0,1.002,0.806,1.817,1.935,1.817v3.461  c-1.145,0-1.935,0.815-1.935,1.817c0,1.003,0.821,1.819,1.935,1.819v2.879c0,0.552,0.447,1,1,1h23.117  C35.189,38.144,36.504,36.771,36.504,34.804z" fill-opacity="0.2" stroke-opacity="0.2"/>
-<path d="M35.505,34.803V10.452L8.813,10.338c-0.451,0-0.819,0.363-0.819,0.818c0,0.451,0.368,0.818,0.819,0.818h1.114  v5.433H8.813c-0.451,0-0.819,0.365-0.819,0.82c0,0.451,0.368,0.818,0.819,0.818h1.114v5.484H8.813c-0.451,0-0.819,0.365-0.819,0.82  c0,0.451,0.368,0.816,0.819,0.816h1.114v5.46H8.813c-0.451,0-0.819,0.363-0.819,0.818c0,0.453,0.368,0.818,0.819,0.818h1.114v3.881  h23.119C35.685,37.145,35.505,34.803,35.505,34.803z" fill-opacity="0.5" stroke-opacity="0.5"/>
-<rect fill="none" height="44.006" width="44"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_1_" x1="22.7168" x2="22.7168" y1="2.6196" y2="42.6339">
-<stop offset="0" style="stop-color:#3687FF"/>
-<stop offset="1" style="stop-color:#051F7D"/>
-</linearGradient>
-<path d="M33.046,36.145H9.927V5.869h23.369c0,0,2.209-0.229,2.209,2.08v25.854  C35.505,33.803,35.685,36.145,33.046,36.145z" fill="url(#SVGID_1_)"/>
-<polygon fill-opacity="0.4" points="12.595,32.129 9.927,33.867 9.927,32.156 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="31.451" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_2_" x1="10.4668" x2="10.4668" y1="30.1924" y2="33.4658">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,31.445c0,0.453-0.364,0.818-0.816,0.818H8.813c-0.451,0-0.819-0.365-0.819-0.818l0,0  c0-0.455,0.368-0.818,0.819-0.818h3.313C12.577,30.627,12.941,30.99,12.941,31.445L12.941,31.445z" fill="url(#SVGID_2_)"/>
-<polygon fill-opacity="0.4" points="12.595,25.024 9.927,26.763 9.927,25.052 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="24.354" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_3_" x1="10.4668" x2="10.4668" y1="23.0957" y2="26.3691">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,24.351c0,0.451-0.364,0.816-0.816,0.816H8.813c-0.451,0-0.819-0.365-0.819-0.816l0,0  c0-0.455,0.368-0.82,0.819-0.82h3.313C12.577,23.53,12.941,23.896,12.941,24.351L12.941,24.351z" fill="url(#SVGID_3_)"/>
-<polygon fill-opacity="0.4" points="12.595,17.925 9.927,19.663 9.927,17.952 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="17.267" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_4_" x1="10.4668" x2="10.4668" y1="15.9722" y2="19.2495">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,17.228c0,0.451-0.364,0.818-0.816,0.818H8.813c-0.451,0-0.819-0.367-0.819-0.818l0,0  c0-0.455,0.368-0.82,0.819-0.82h3.313C12.577,16.407,12.941,16.772,12.941,17.228L12.941,17.228z" fill="url(#SVGID_4_)"/>
-<polygon fill-opacity="0.4" points="12.595,10.838 9.927,12.576 9.927,10.865 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="10.227" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_5_" x1="10.4668" x2="10.4668" y1="8.9033" y2="12.1768">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,10.156c0,0.451-0.364,0.818-0.816,0.818H8.813c-0.451,0-0.819-0.367-0.819-0.818l0,0  c0-0.455,0.368-0.818,0.819-0.818h3.313C12.577,9.338,12.941,9.701,12.941,10.156L12.941,10.156z" fill="url(#SVGID_5_)"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_6_" x1="23.6406" x2="23.6406" y1="11.1069" y2="42.3992">
-<stop offset="0" style="stop-color:#F2F2F2"/>
-<stop offset="0.1364" style="stop-color:#E4EDF0"/>
-<stop offset="0.3929" style="stop-color:#C0DFEB"/>
-<stop offset="0.7391" style="stop-color:#86C8E3"/>
-<stop offset="0.9945" style="stop-color:#57B6DD"/>
-<stop offset="1" style="stop-color:#57B6DD"/>
-</linearGradient>
-<path d="M25.46,20.76c-1.317,0.777-2.427,0.73-3.732,0.021c-3.713,0.674-4.901,3.396-4.901,6.652v1.244  c0,3.063,13.629,3.063,13.629,0v-1.244C30.455,24.147,29.25,21.404,25.46,20.76z M26.249,17.999  c0.723-1.343,0.883-2.334,0.883-3.422c0-1.982-1.54-3.62-3.491-3.62s-3.487,1.638-3.487,3.62c0,1.088,0.16,2.079,0.882,3.422  C22.405,20.574,24.633,20.661,26.249,17.999z" fill="url(#SVGID_6_)"/>
-<path d="M23.676,11.655c1.873,0,3.322,1.52,3.435,3.399c0.235-1.517-0.812-4.099-3.435-4.099  c-2.314,0-3.721,2.051-3.501,4.099C20.287,13.175,21.803,11.655,23.676,11.655z" fill="#051F7D"/>
-<path d="M25.46,20.76c-1.224,0.793-2.661,0.699-3.732,0.021c-5.413,0.912-4.901,6.568-4.901,7.353  c0-3.175,1.188-5.979,4.901-6.652c1.29,0.774,2.462,0.696,3.732-0.021c3.79,0.645,4.995,3.421,4.995,6.674  C30.627,24.162,29.25,21.404,25.46,20.76z" fill="#051F7D"/>
-<path d="M23.676,11.655c1.873,0,3.322,1.52,3.435,3.399c0.235-1.517-0.812-4.099-3.435-4.099  c-2.314,0-3.721,2.051-3.501,4.099C20.287,13.175,21.803,11.655,23.676,11.655z" fill-opacity="0.2" stroke-opacity="0.2"/>
-<path d="M25.46,20.76c-1.224,0.793-2.661,0.699-3.732,0.021c-5.413,0.912-4.901,6.568-4.901,7.353  c0-3.175,1.188-5.979,4.901-6.652c1.29,0.774,2.462,0.696,3.732-0.021c3.79,0.645,4.995,3.421,4.995,6.674  C30.627,24.162,29.25,21.404,25.46,20.76z" fill-opacity="0.2" stroke-opacity="0.2"/>
-</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/resources/style/cntcommondetailviewitem.css	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,7 @@
+CntCommonDetailViewItem{
+    layout:customLayout;
+}
+
+CntCommonDetailViewItem:landscape{
+    layout:customLayout-landscape;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/resources/style/cntcommondetailviewitem.widgetml	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,24 @@
+<hbwidget version="0.1" type="cntcommondetailviewitem">
+  <layout name="customLayout" type="mesh">
+    <meshitem src="combobox" srcEdge="TOP" dst="" dstEdge="TOP"  spacing="-var(hb-param-margin-gene-top)" />
+    <meshitem src="combobox" srcEdge="LEFT" dst="" dstEdge="LEFT"  spacing="-var(hb-param-margin-gene-left)" />
+    <meshitem src="combobox" srcEdge="RIGHT" dst="" dstEdge="RIGHT" spacing="var(hb-param-margin-gene-right)" />
+    
+    <meshitem src="editbox" srcEdge="TOP" dst="combobox" dstEdge="BOTTOM" spacing="-var(hb-param-margin-gene-middle-vertical)" />
+    <meshitem src="editbox" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" spacing="var(hb-param-margin-gene-bottom)" />
+    <meshitem src="editbox" srcEdge="LEFT" dst="combobox" dstEdge="LEFT" spacing="-var(hb-param-margin-gene-left)" />
+    <meshitem src="editbox" srcEdge="RIGHT" dst="" dstEdge="RIGHT" spacing="var(hb-param-margin-gene-right)" />
+  </layout>
+  
+  <layout name="customLayout-landscape" type="mesh">
+    <meshitem src="combobox" srcEdge="LEFT" dst="" dstEdge="LEFT" spacing="-var(hb-param-margin-gene-left)" />
+    <meshitem src="combobox" srcEdge="RIGHT" dst="" dstEdge="CENTERH" />
+    <meshitem src="combobox" srcEdge="TOP" dst="" dstEdge="TOP" spacing="-var(hb-param-margin-gene-top)" />
+		<meshitem src="editbox" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" spacing="var(hb-param-margin-gene-bottom)" />
+
+    <meshitem src="editbox" srcEdge="LEFT" dst="combobox" dstEdge="RIGHT" spacing="-var(hb-param-margin-gene-left)" />
+    <meshitem src="editbox" srcEdge="RIGHT" dst="" dstEdge="RIGHT" spacing="var(hb-param-margin-gene-right)" />
+    <meshitem src="editbox" srcEdge="TOP" dst="" dstEdge="TOP" spacing="-var(hb-param-margin-gene-top)" />
+		<meshitem src="editbox" srcEdge="BOTTOM" dst="" dstEdge="BOTTOM" spacing="var(hb-param-margin-gene-bottom)" />
+  </layout>
+</hbwidget>
--- a/phonebookui/pbkcommonui/src/cntaddressmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntaddressmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -27,6 +27,7 @@
 mAddressWork(NULL),
 mIsLocationPickerEnabled( false )
     {
+    mMaptileInterface = new CntMapTileService;
     HbDataFormModelItem* address = appendDataFormGroup(hbTrId("txt_phob_formlabel_address"), invisibleRootItem());
     HbDataFormModelItem* addressHome = appendDataFormGroup(hbTrId("txt_phob_formlabel_address_home"), invisibleRootItem());
     HbDataFormModelItem* addressWork = appendDataFormGroup(hbTrId("txt_phob_formlabel_address_work"), invisibleRootItem());
@@ -84,12 +85,13 @@
     delete mAddress;
     delete mAddressHome;
     delete mAddressWork;
+    delete mMaptileInterface;
     }
 
 void CntAddressModel::createAddressItems( HbDataFormModelItem* aGroup, QContactAddress* aAddress )
     {
 	//Show the location picker button only if location feature enabled
-    if( CntMapTileService::isLocationFeatureEnabled() )
+    if( mMaptileInterface->isLocationFeatureEnabled() )
     {
         // custom item for map button
         HbDataFormModelItem* mapButton = new HbDataFormModelItem( HbDataFormModelItem::CustomItemBase );
@@ -129,20 +131,24 @@
 {
     // No Context
     HbDataFormModelItem* addressRoot = invisibleRootItem()->childAt( 0 );
-    saveAddressItems( addressRoot, mAddress );
+    if ( saveAddressItems( addressRoot, mAddress ) )
+    {
+        mContact->saveDetail( mAddress );    
+    }
     
     // Home 
     HbDataFormModelItem* addressHomeRoot = invisibleRootItem()->childAt( 1 );
-    saveAddressItems( addressHomeRoot, mAddressHome );
+    if ( saveAddressItems( addressHomeRoot, mAddressHome ) )
+    {
+        mContact->saveDetail( mAddressHome );    
+    }
     
-    // Work
+    // Business
     HbDataFormModelItem* addressWorkRoot = invisibleRootItem()->childAt( 2 );
-    saveAddressItems( addressWorkRoot, mAddressWork );
-    
-    // save and remove empty details
-    mContact->saveDetail( mAddress );
-    mContact->saveDetail( mAddressHome );
-    mContact->saveDetail( mAddressWork );
+    if ( saveAddressItems( addressWorkRoot, mAddressWork ) )
+    {
+        mContact->saveDetail( mAddressWork );    
+    }
     
     if ( isAddressEmpty(mAddress) ) 
     {
@@ -180,20 +186,37 @@
     return QContactAddress();
 }
 
-void CntAddressModel::saveAddressItems( HbDataFormModelItem* aGroup, QContactAddress* aAddress )
+bool CntAddressModel::saveAddressItems( HbDataFormModelItem* aGroup, QContactAddress* aAddress )
 {
     int offset = 0;
-    if( CntMapTileService::isLocationFeatureEnabled() )
+    if( mMaptileInterface->isLocationFeatureEnabled() )
     {
         offset = 1;
     }
-		
-    // first item (0) is the map button
-    aAddress->setStreet( aGroup->childAt( 0 + offset  )->contentWidgetData("text").toString().trimmed() );
-    aAddress->setPostcode( aGroup->childAt( 1 + offset )->contentWidgetData("text").toString().trimmed() );
-    aAddress->setLocality( aGroup->childAt( 2 + offset  )->contentWidgetData("text").toString().trimmed() );
-    aAddress->setRegion( aGroup->childAt( 3 + offset  )->contentWidgetData("text").toString().trimmed() );
-    aAddress->setCountry( aGroup->childAt( 4 + offset  )->contentWidgetData("text").toString().trimmed() );
+    
+	QString street = aGroup->childAt( 0 + offset  )->contentWidgetData("text").toString().trimmed();
+	QString postcode = aGroup->childAt( 1 + offset )->contentWidgetData("text").toString().trimmed();
+	QString locality = aGroup->childAt( 2 + offset  )->contentWidgetData("text").toString().trimmed();
+	QString region = aGroup->childAt( 3 + offset  )->contentWidgetData("text").toString().trimmed();
+	QString country = aGroup->childAt( 4 + offset  )->contentWidgetData("text").toString().trimmed();
+	
+	bool changed = ( 
+	        street != aAddress->street() || 
+            postcode != aAddress->postcode() || 
+            locality != aAddress->locality() ||
+            region != aAddress->region() ||
+            country != aAddress->country() 
+            );
+	
+	if ( changed )
+	{
+        aAddress->setStreet( street );
+        aAddress->setPostcode( postcode );
+        aAddress->setLocality( locality );
+        aAddress->setRegion( region );
+        aAddress->setCountry( country );
+	}
+    return changed;
 }
 
 bool CntAddressModel::isAddressEmpty( QContactAddress* aAddress ) const
--- a/phonebookui/pbkcommonui/src/cntbaseselectionview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntbaseselectionview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -23,11 +23,13 @@
 #include <hbscrollbar.h>
 #include <hbdocumentloader.h>
 #include <hbaction.h>
-#include <cntlistmodel.h>
+#include "cntlistmodel.h"
 
 const char *CNT_SELECTION_LISTVIEW_UI_XML = ":/xml/contacts_list.docml";
 
-CntBaseSelectionView::CntBaseSelectionView() : QObject()
+CntBaseSelectionView::CntBaseSelectionView() : 
+QObject(),
+mDocument(NULL)
 {
     mDocument = new HbDocumentLoader();
     
@@ -72,24 +74,12 @@
         //setOrientation(window->orientation());
     }
     
-    QContactSortOrder sortOrderFirstName;
-    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,QContactName::FieldFirstName);
-    sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
-
-    QContactSortOrder sortOrderLastName;
-    sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,QContactName::FieldLastName);
-    sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
-
-    QList<QContactSortOrder> sortOrders;
-    sortOrders.append(sortOrderFirstName);
-    sortOrders.append(sortOrderLastName);
-    
     QContactDetailFilter filter;
     filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
     QString typeContact = QContactType::TypeContact;
     filter.setValue(typeContact);
 
-    mListModel = new CntListModel(mMgr->contactManager(SYMBIAN_BACKEND), filter, sortOrders);
+    mListModel = new CntListModel(mMgr->contactManager(SYMBIAN_BACKEND), filter);
     mListModel->showMyCard( false );
     
     mListView->setModel( mListModel );
--- a/phonebookui/pbkcommonui/src/cntcollectionlistmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcollectionlistmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -21,12 +21,17 @@
 
 #include <cntuiextensionfactory.h>
 #include <cntuigroupsupplier.h>
+#include <cntuids.h>
+#include <xqsettingskey.h>
 
 #include <QIcon>
 #include <qtcontacts.h>
 #include <hbglobal.h>
 #include <hbiconitem.h>
 
+// CONTSTANTS
+const int CntNamesLengthLimit = 30;
+
 /*!
 Constructor
 */
@@ -45,7 +50,6 @@
 */
 CntCollectionListModel::~CntCollectionListModel()
 {
-    
 }
 
 /*!
@@ -173,33 +177,51 @@
         sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
 
         QList<QContactSortOrder> sortOrders;
-        sortOrders.append(sortOrderFirstName);
-        sortOrders.append(sortOrderLastName);
-
+        XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
+            KCRUiContacts.iUid,
+            KCntNameOrdering);
+        int order = mSettings.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
+        if (order == CntOrderFirstLast)
+        {
+            sortOrders.append(sortOrderFirstName);
+            sortOrders.append(sortOrderLastName);
+        } 
+        else
+        {
+            sortOrders.append(sortOrderLastName);
+            sortOrders.append(sortOrderFirstName);
+        }
         // group members and their count
-       QList<QContactLocalId> groupMemberIds = mContactManager->contactIds(rFilter, sortOrders);
+        QList<QContactLocalId> groupMemberIds = mContactManager->contactIds(rFilter, sortOrders);
 
-       if (!groupMemberIds.isEmpty())
-       {
-           QStringList nameList;
-           for(int i = 0;i < groupMemberIds.count();i++)
-           {
-               QContact contact = mContactManager->contact(groupMemberIds.at(i));
-               QString memberName = contact.displayLabel();
-               nameList << memberName;
-               if (nameList.join(", ").length() > 30)
-               {
-                   break;
-               }
-           }
-           QString names = nameList.join(", ");
-           displayList.append(names);
-           displayList.append(hbTrId("(%1)").arg(groupMemberIds.count()));
-       }
-       else
-       {
-           displayList.append(hbTrId("txt_phob_dblist_favorites_val_no_favorites_selecte"));
-       }
+        if (!groupMemberIds.isEmpty())
+        {
+            QStringList nameList;
+            for(int i = 0;i < groupMemberIds.count();i++)
+            {
+                QContact contact = mContactManager->contact(groupMemberIds.at(i));
+                QString memberName = contact.displayLabel();
+                if (memberName.isEmpty())
+                {
+                    memberName = hbTrId("txt_phob_dblist_unnamed");
+                }
+                
+                // Incase the format is LastnameCommaFirstname, remove the commas
+                memberName = memberName.replace(", ", " ");
+                nameList << memberName;
+                if (nameList.join(", ").length() > CntNamesLengthLimit)
+                {
+                    break;
+                }
+            }
+            QString names = nameList.join(", ").trimmed();
+            displayList.append(names);
+            displayList.append(hbTrId("(%1)").arg(groupMemberIds.count()));
+        }
+        else
+        {
+            displayList.append(hbTrId("txt_phob_dblist_favorites_val_no_favorites_selecte"));
+        }
     }
     else
     {
@@ -309,8 +331,20 @@
             sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
 
             QList<QContactSortOrder> sortOrders;
-            sortOrders.append(sortOrderFirstName);
-            sortOrders.append(sortOrderLastName);
+            XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
+                KCRUiContacts.iUid,
+                KCntNameOrdering);
+            int order = mSettings.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
+            if (order == CntOrderFirstLast)
+            {
+                sortOrders.append(sortOrderFirstName);
+                sortOrders.append(sortOrderLastName);
+            } 
+            else
+            {
+                sortOrders.append(sortOrderLastName);
+                sortOrders.append(sortOrderFirstName);
+            }
 
             // group members and their count
             QList<QContactLocalId> groupMemberIds = mContactManager->contactIds(rFilter, sortOrders);
@@ -322,30 +356,37 @@
                 {
                     QContact contact = mContactManager->contact(groupMemberIds.at(i));
                     QString memberName = contact.displayLabel();
+                    if (memberName.isEmpty())
+                    {
+                        memberName = hbTrId("txt_phob_dblist_unnamed");
+                    }
+                        
+                    // Incase the format is LastnameCommaFirstname, remove the commas
+                    memberName = memberName.replace(", ", " ");
                     nameList << memberName;
-                    if (nameList.join(", ").length() > 30)
+                    if (nameList.join(", ").length() > CntNamesLengthLimit)
                     {
                         break;
                     }
                 }
-                QString names = nameList.join(", ");
+                QString names = nameList.join(", ").trimmed();
                 displayList.append(names);
                 displayList.append(hbTrId("(%1)").arg(groupMemberIds.count()));
             }
             else
             {
-                displayList.append(hbTrId("No members selected"));
+                displayList.append(hbTrId("txt_phob_dblist_val_no_members_selected"));
             }
             dataList.append(displayList);
 
             // Default if no image for group 
             bool icon = false;
             QList<QContactAvatar> details = contact.details<QContactAvatar>();
-            for (int i = 0;i < details.count();i++)
+            for (int k = 0;k < details.count();k++)
             {
-                if (details.at(i).imageUrl().isValid())
+                if (details.at(k).imageUrl().isValid())
                 {
-                    dataList.append(QStringList(details.at(i).imageUrl().toString()));
+                    dataList.append(QStringList(details.at(k).imageUrl().toString()));
                     icon = true;
                     break;
                 }
--- a/phonebookui/pbkcommonui/src/cntcollectionview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcollectionview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -300,6 +300,9 @@
     HbInputDialog *popup = new HbInputDialog();
     popup->setAttribute(Qt::WA_DeleteOnClose, true);
     
+    HbLineEdit *lineEdit = popup->lineEdit();
+    lineEdit->setInputMethodHints(Qt::ImhNoPredictiveText);
+    
     popup->setPromptText(hbTrId("txt_phob_title_new_group_name"));
     popup->clearActions();
     HbAction* primaryAction = new HbAction(hbTrId("txt_phob_button_create"));
@@ -336,7 +339,7 @@
 
         // Select some contact(s) to add to the group
         QString groupNameCreated(mHandledContact->displayLabel());
-        mFetchView->setDetails(HbParameterLengthLimiter(hbTrId("txt_phob_subtitle_1_group")).arg(groupNameCreated),
+        mFetchView->setDetails(HbParameterLengthLimiter(hbTrId("txt_phob_title_members_of_1_group")).arg(groupNameCreated),
                                hbTrId("txt_common_button_save"));
         mFetchView->displayContacts(CntFetchContacts::popup,
                                     HbAbstractItemView::MultiSelection,
@@ -388,7 +391,7 @@
           
     HbMessageBox::question(hbTrId("txt_phob_dialog_only_group_will_be_removed_contac")
             , this, SLOT(handleDeleteGroup(HbAction*)),
-                hbTrId("txt_phob_button_delete"), hbTrId("txt_common_button_cancel"), headingLabel);
+                hbTrId("txt_common_button_delete"), hbTrId("txt_common_button_cancel"), headingLabel);
 }
 
 void CntCollectionView::handleDeleteGroup(HbAction* action)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/src/cntcommondetailviewitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,44 @@
+/*
+* 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:
+*
+*/
+#include "cntcommondetailviewitem.h"
+
+#include <hbcombobox.h>
+#include <hblineedit.h>
+
+
+CntCommonDetailViewItem::CntCommonDetailViewItem(QGraphicsItem *aParent):
+HbWidget(aParent)
+{
+    mPhoneTypeSelector = new HbComboBox(this);
+    style()->setItemName(mPhoneTypeSelector, "combobox");
+
+    mDataEditor = new HbLineEdit(this);
+    style()->setItemName(mDataEditor, "editbox");
+    mDataEditor->setInputMethodHints(Qt::ImhNoPredictiveText);
+}
+
+HbComboBox* CntCommonDetailViewItem::comboBox() const
+{
+    return mPhoneTypeSelector;
+}
+
+HbLineEdit* CntCommonDetailViewItem::editor() const
+{
+    return mDataEditor;
+}
+
+// End of File
--- a/phonebookui/pbkcommonui/src/cntcompanyeditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcompanyeditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -63,24 +63,22 @@
 void CntCompanyEditorModel::saveContactDetails()
 {
     HbDataFormModelItem* root = invisibleRootItem();
-    if (!root->childAt(0)->contentWidgetData("text").toString().isEmpty())
-        mCompany.setName( root->childAt(0)->contentWidgetData("text").toString() );
-    else
-        mCompany.setName(QString());
-    if (!root->childAt(1)->contentWidgetData("text").toString().isEmpty())
-        mCompany.setTitle( root->childAt(1)->contentWidgetData("text").toString() );
-    else
-        mCompany.setTitle(QString());
-    if (!root->childAt(2)->contentWidgetData("text").toString().isEmpty())
-        mCompany.setDepartment( root->childAt(2)->contentWidgetData("text").toString().split(", ") );
-    else
-        mCompany.setDepartment(QStringList());
-    if (!root->childAt(3)->contentWidgetData("text").toString().isEmpty())
-        mCompany.setAssistantName( root->childAt(3)->contentWidgetData("text").toString() );
-    else
-        mCompany.setAssistantName(QString());
+    QString name = root->childAt(0)->contentWidgetData("text").toString();
+    QString title = root->childAt(1)->contentWidgetData("text").toString();
+    QString department = root->childAt(2)->contentWidgetData("text").toString();
+    QString assistant = root->childAt(3)->contentWidgetData("text").toString();
     
-    mContact->saveDetail( &mCompany );
+    if ( mCompany.name() != name ||
+         mCompany.title() != title || 
+         mCompany.department().join(", ") != department ||
+         mCompany.assistantName() != assistant )
+    {
+        mCompany.setName( name );
+        mCompany.setTitle( title );
+        mCompany.setDepartment( department.split(", ") );
+        mCompany.setAssistantName( assistant );
+        mContact->saveDetail( &mCompany );
+    }
     
     if ( mCompany.name().isEmpty() && 
          mCompany.title().isEmpty() &&
--- a/phonebookui/pbkcommonui/src/cntcontactcarddatacontainer.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcontactcarddatacontainer.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,6 +17,7 @@
 
 #include "cntcontactcarddatacontainer.h"
 #include "cntcontactcarddataitem.h"
+#include "cntdetailorderinghelper.h"
 #include <cntmaptileservice.h> //For fetching maptile
 #include "cntuiactionextension.h"
 
@@ -44,7 +45,11 @@
 /*!
 Constructor
 */
-CntContactCardDataContainer::CntContactCardDataContainer(QContact* contact, QObject *parent, bool myCard) : mContact(contact), mSeparatorIndex(-1)
+CntContactCardDataContainer::CntContactCardDataContainer(QContact* contact, QObject *parent, bool myCard, CntMapTileService* maptile) :
+                                                            mContact(contact), 
+                                                            mSeparatorIndex(-1),
+                                                            mLocationFeatureEnabled(false), 
+                                                            mMaptileInterface(maptile)
 {
     Q_UNUSED(parent);
     if (contact->type() == QContactType::TypeGroup)
@@ -91,7 +96,7 @@
             extendedActions << action;
     }
 
-    QList<QContactPhoneNumber> details = mContact->details<QContactPhoneNumber>();
+    QList<QContactPhoneNumber> details = CntDetailOrderingHelper::getOrderedSupportedPhoneNumbers(*mContact);
     for (int i = 0; i < details.count(); i++)
     { 
         //call
@@ -356,7 +361,7 @@
 void CntContactCardDataContainer::initializeDetailsData()
 {
     //sip & internet call
-    QList<QContactOnlineAccount> onlinedDetails = mContact->details<QContactOnlineAccount>();
+    QList<QContactOnlineAccount> onlinedDetails = CntDetailOrderingHelper::getOrderedSupportedOnlineAccounts(*mContact);
     for (int i = 0; i < onlinedDetails.count(); i++)
     {
         QContactOnlineAccount online(onlinedDetails.at(i));
@@ -379,7 +384,10 @@
     QString contextHome(QContactAddress::ContextHome.operator QString());
     QString contextWork(QContactAddress::ContextWork.operator QString());
     CntMapTileService::ContactAddressType sourceAddressType;  
-    mLocationFeatureEnabled = CntMapTileService::isLocationFeatureEnabled() ;
+    if( mMaptileInterface )
+    {
+        mLocationFeatureEnabled = mMaptileInterface->isLocationFeatureEnabled() ;
+    }
 
     QList<QContactAddress> addressDetails = mContact->details<QContactAddress>();
     for (int i = 0; i < addressDetails.count(); i++)
@@ -422,25 +430,51 @@
             address.append(addressDetails[i].region());
         if (!addressDetails[i].country().isEmpty())
             address.append(addressDetails[i].country());
-                
+	    bool maptileAvailable = false;
+		QString imageFile;
+		
+		if( mLocationFeatureEnabled && mMaptileInterface )
+        {
+        
+            QContactLocalId contactId = mContact->id().localId();
+            
+			      //Get the maptile image path
+            int status = mMaptileInterface->getMapTileImage(
+                        contactId, sourceAddressType, imageFile );
+                 
+            if( status == CntMapTileService::MapTileFetchingInProgress || status == 
+                    CntMapTileService::MapTileFetchingNetworkError )
+            {
+                //Load the progress indicator icon
+                QString iconName("qtg_anim_small_loading_1");
+                HbIcon inProgressIcon(iconName);
+                dataItem->setSecondaryIcon( inProgressIcon );
+            }
+            else if( status == CntMapTileService::MapTileFetchingUnknownError || 
+                        status == CntMapTileService::MapTileFetchingInvalidAddress  )
+            {
+                //Load the search stop icon
+                QString iconName("qtg_mono_search_stop");
+                HbIcon stopIcon(iconName);
+                dataItem->setSecondaryIcon( stopIcon );
+            }
+            else if( status == CntMapTileService::MapTileFetchingCompleted )
+            {
+                maptileAvailable = true;
+            }
+        }
         dataItem->setValueText(address.join(" "));
         dataItem->setContactDetail(addressDetails[i]);
         addSeparator(itemCount());
         mDataItemList.append(dataItem);
         
         //Check whether location feature enabled
-        if (mLocationFeatureEnabled)
+        if ( mLocationFeatureEnabled && maptileAvailable && !imageFile.isNull() )
         {
-            QContactLocalId contactId = mContact->id().localId();
-         
-            //Get the maptile image path
-            QString imageFile = CntMapTileService::getMapTileImage(contactId, sourceAddressType);
-        
-		        if ( !imageFile.isNull() )
-		        {   
-		            //Display the maptile image
-                HbIcon icon(imageFile);
-                
+            //Display the maptile image
+            HbIcon icon(imageFile);
+            if( !icon.isNull() )
+            {
                 CntContactCardDataItem* dataItem = new CntContactCardDataItem(QString(), position, false);
                 dataItem->setIcon(icon);
                 addSeparator(itemCount());
@@ -655,15 +689,15 @@
     {
         position = CntContactCardDataItem::ECallPhoneWork;
     }
-    else if (aId == QContactPhoneNumber::SubTypeFacsimile && aContext.isEmpty() && !dynamicAction)
+    else if (aId == QContactPhoneNumber::SubTypeFax && aContext.isEmpty() && !dynamicAction)
     {
         position = CntContactCardDataItem::ECallFax;
     }
-    else if (aId == QContactPhoneNumber::SubTypeFacsimile && aContext == QContactDetail::ContextHome && !dynamicAction)
+    else if (aId == QContactPhoneNumber::SubTypeFax && aContext == QContactDetail::ContextHome && !dynamicAction)
     {
         position = CntContactCardDataItem::ECallFaxHome;
     }
-    else if (aId == QContactPhoneNumber::SubTypeFacsimile && aContext == QContactDetail::ContextWork && !dynamicAction)
+    else if (aId == QContactPhoneNumber::SubTypeFax && aContext == QContactDetail::ContextWork && !dynamicAction)
     {
         position = CntContactCardDataItem::ECallFaxWork;
     }
@@ -788,7 +822,7 @@
     }
     else if (!dynamicAction)
     {
-        position = CntContactCardDataItem::EOther;
+        position = CntContactCardDataItem::ENotSupported;
     }
     else
     {
--- a/phonebookui/pbkcommonui/src/cntcontactcarddetailitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcontactcarddetailitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -16,7 +16,7 @@
 */
 
 #include <QGraphicsLayout>
-#include <QDebug>
+#include "cntdebug.h"
 
 #include "cntcontactcarddetailitem.h"
 #include "cntcontactcarddataitem.h"
@@ -33,7 +33,6 @@
 #include <QGestureEvent>
 #include <hbtapgesture.h>
 
-const int CNT_CONTACTCARD_TEXT_MAX_ROWCOUNT = 1;
 const int CNT_CONTACTCARD_Z_FRAME = -1;
 const int CNT_CONTACTCARD_Z_FOCUS = -2;
 
@@ -93,7 +92,7 @@
         style()->setItemName(mSecondaryIcon, "secondaryIcon");
     }
     mSecondaryIcon->setIcon(secondaryIcon);
-    mSecondaryIcon->setColor(HbColorScheme::color("foreground"));
+    mSecondaryIcon->setColor(HbColorScheme::color("qtc_view_normal"));
 
     
     if (!mFirstLineText)
@@ -154,7 +153,8 @@
 
 void CntContactCardDetailItem::gestureEvent(QGestureEvent* event)
 {
-    qDebug() << "CntContactCardDetailItem::gestureEvent - IN";
+    CNT_ENTRY
+    
     if (HbTapGesture *tap = qobject_cast<HbTapGesture *>(event->gesture(Qt::TapGesture))) 
     {
         switch(tap->state()) 
@@ -194,7 +194,8 @@
     {
         event->ignore();
     }
-    qDebug() << "CntContactCardDetailItem::gestureEvent - OUT";
+    
+    CNT_EXIT
 }
 
 void CntContactCardDetailItem::onLongPress(const QPointF &point)
@@ -226,15 +227,15 @@
     mValueTextElideMode = aDataItem->elideMode();
 
     if (aDataItem->icon() != icon)
-        {
+    {
         icon.clear();
         icon = aDataItem->icon();
-        }
+    }
     if (aDataItem->secondaryIcon() != secondaryIcon)
-        {
+    {
         secondaryIcon.clear();
         secondaryIcon = aDataItem->secondaryIcon();
-        }
+    }
    
     text.clear();
     text = aDataItem->titleText();
@@ -245,6 +246,21 @@
     recreatePrimitives();
 }
 
+//To update the secondary icon item
+void CntContactCardDetailItem::setSecondaryIconItem( HbIcon aIcon )
+{
+    secondaryIcon.clear();
+    secondaryIcon = aIcon;
+    if ( !mSecondaryIcon )
+    {
+        mSecondaryIcon = new HbIconItem(this);
+        mSecondaryIcon->setFlags(HbIcon::Colorized);
+        style()->setItemName(mSecondaryIcon, "secondaryIcon");
+    }
+    mSecondaryIcon->setIcon(secondaryIcon);
+    mSecondaryIcon->setColor(HbColorScheme::color("foreground"));
+}
+
 int CntContactCardDetailItem::index()
 {
     return mIndex;
--- a/phonebookui/pbkcommonui/src/cntcontactcardheadingitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcontactcardheadingitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -30,6 +30,9 @@
 #include <hbaction.h>
 #include <hbmainwindow.h>
 #include <hbtapgesture.h>
+#include <cntuids.h>
+#include <xqsettingsmanager.h>
+#include <xqsettingskey.h>
 
 CntContactCardHeadingItem::CntContactCardHeadingItem(QGraphicsItem *parent) :
     HbWidget(parent),
@@ -41,7 +44,9 @@
     mSecondaryText(NULL),
     mMarqueeItem(NULL),
     mFrameItem(NULL),
-    mPictureArea(NULL)
+    mPictureArea(NULL),
+    mIsFavorite(false),
+    mIsOnline(false)
 {
 }
 
@@ -71,22 +76,22 @@
     }
     
     if (!secondaryIcon.isNull())
+    {
+        if (!mSecondaryIcon)
         {
-            if (!mSecondaryIcon)
-            {
-                mSecondaryIcon = new HbIconItem(this);
-                mSecondaryIcon->setIcon(secondaryIcon);
-                style()->setItemName(mSecondaryIcon, "secondary_icon");
-            }
+            mSecondaryIcon = new HbIconItem(this);
+            mSecondaryIcon->setIcon(secondaryIcon);
+            style()->setItemName(mSecondaryIcon, "secondary_icon");
         }
-        else
+    }
+    else
+    {
+        if (mSecondaryIcon)
         {
-            if (mSecondaryIcon)
-            {
-                delete mSecondaryIcon;
-            }
-            mSecondaryIcon = 0;
+            delete mSecondaryIcon;
         }
+        mSecondaryIcon = 0;
+    }
 
     if (!firstLineText.isNull())
     {
@@ -95,6 +100,7 @@
             mFirstLineText = new HbTextItem(this);
             mFirstLineText->setText(firstLineText);
             mFirstLineText->setMaximumLines(1);
+            mFirstLineText->setElideMode(Qt::ElideRight);
             style()->setItemName(mFirstLineText, "first_line_text");
         }
     }
@@ -115,6 +121,7 @@
             mPrimaryText->setText(primaryText);
             mPrimaryText->setMaximumLines(2);
             mPrimaryText->setTextWrapping(Hb::TextWordWrap);
+            mPrimaryText->setElideMode(Qt::ElideRight);
             style()->setItemName(mPrimaryText, "primary_text");
         }
     }
@@ -222,22 +229,17 @@
     }
 }
 
-void CntContactCardHeadingItem::setSecondaryIcon(bool favoriteContact)
+void CntContactCardHeadingItem::setFavoriteStatus(bool favoriteContact)
 {
-    secondaryIcon.clear();
-
-    if (favoriteContact)
+    if (favoriteContact != mIsFavorite)
     {
-        secondaryIcon = HbIcon("qtg_small_favorite");
-        createPrimitives();
-        mSecondaryIcon->setIcon(secondaryIcon);
+        mIsFavorite = favoriteContact;
+        
+        if (!mIsOnline)
+        {
+            setSecondaryIcon();
+        }
     }
-    else
-    {
-        createPrimitives();
-    }
-    repolish();
-
 }
 
 void CntContactCardHeadingItem::recreatePrimitives()
@@ -299,6 +301,7 @@
     secondaryText.clear();
     icon.clear();
     tinyMarqueeText.clear();
+    secondaryIcon.clear();
 
     // icon label
     icon = HbIcon("qtg_large_add_contact_picture");
@@ -308,10 +311,7 @@
     // name label
     if (isNickName(contact) || isCompanyName(contact))
     {
-        // prefix, first, middle, last and suffix
-        QStringList nameList;
-        nameList << name.prefix() << name.firstName() << name.middleName() << name.lastName() << name.suffix();
-        firstLineText = nameList.join(" ").trimmed();
+        firstLineText = createNameText(name);
         if (firstLineText.isEmpty())
         {
             firstLineText = hbTrId("txt_phob_list_unnamed");
@@ -319,10 +319,7 @@
     }
     else
     {
-        // prefix, first, middle, last and suffix
-        QStringList nameList;
-        nameList << name.prefix() << name.firstName() << name.middleName() << name.lastName() << name.suffix();
-        primaryText = nameList.join(" ").trimmed();
+        primaryText = createNameText(name);
         if (primaryText.isEmpty())
         {
             primaryText = hbTrId("txt_phob_list_unnamed");
@@ -347,6 +344,35 @@
     recreatePrimitives();
 }
 
+QString CntContactCardHeadingItem::createNameText(const QContactName name)
+{
+    XQSettingsManager settingsMng;
+    XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
+                             KCRUiContacts.iUid,
+                             KCntNameOrdering);
+    int setting = settingsMng.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
+    
+    QStringList nameList;
+    QString last;
+    
+    switch( setting ) {
+        case CntOrderLastFirst:
+            nameList << name.prefix() << name.lastName() << name.firstName() << name.middleName() << name.suffix();
+            break;
+        case CntOrderLastCommaFirst:
+            if (!name.lastName().isEmpty())
+                last = name.lastName() + ",";
+            nameList << name.prefix() << last << name.firstName() << name.middleName() << name.suffix();
+            break;
+        default:    // Default to first name last name
+            nameList << name.prefix() << name.firstName() << name.middleName() << name.lastName() << name.suffix();
+            break;
+    }
+    
+    nameList.removeAll("");
+    return nameList.join(" ").trimmed();
+}
+
 void CntContactCardHeadingItem::setGroupDetails(const QContact* contact)
 {
     firstLineText.clear();
@@ -379,6 +405,16 @@
     emit passShortPressed(point);
 }
 
+void CntContactCardHeadingItem::setOnlineStatus(bool online)
+{
+    if (online != mIsOnline)
+    {
+        mIsOnline = online;
+        
+        setSecondaryIcon();
+    }
+}
+
 void CntContactCardHeadingItem::gestureEvent(QGestureEvent* event)
 {
     
@@ -409,11 +445,6 @@
     }
 }
 
-void CntContactCardHeadingItem::initGesture()
-{
-    grabGesture(Qt::TapGesture);
-}
-
 QVariant CntContactCardHeadingItem::itemChange(GraphicsItemChange change, const QVariant &value)
 {      
     if (change == QGraphicsItem::ItemSceneHasChanged)
@@ -438,6 +469,32 @@
     repolish();
 }
 
+void CntContactCardHeadingItem::initGesture()
+{
+    grabGesture(Qt::TapGesture);
+}
+
+void CntContactCardHeadingItem::setSecondaryIcon()
+{
+    if (mIsOnline)
+    {
+        secondaryIcon = HbIcon("qtg_small_online");
+        createPrimitives();
+        mSecondaryIcon->setIcon(secondaryIcon);
+    }
+    else if (!mIsOnline && mIsFavorite)
+    {
+        secondaryIcon = HbIcon("qtg_small_favorite");
+        createPrimitives();
+        mSecondaryIcon->setIcon(secondaryIcon);
+    }
+    else
+    {
+        secondaryIcon.clear();
+        createPrimitives();
+    }
+
+    repolish();
+}
 
 // EOF
-
--- a/phonebookui/pbkcommonui/src/cntcontactcardview_p.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcontactcardview_p.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -20,8 +20,6 @@
 #include <QGraphicsSceneResizeEvent>
 #include <QStringList>
 #include <QStandardItemModel>
-#include <hblistview.h>
-#include <hblistviewitem.h>
 #include <QDebug>
 #include <QKeyEvent>
 #include <QDir>
@@ -39,13 +37,18 @@
 #include <hbparameterlengthlimiter.h>
 #include <hbframeitem.h>
 #include <hbframedrawer.h>
+#include <hbselectiondialog.h>
+#include <hblistview.h>
+#include <hblistviewitem.h>
 #include <shareui.h>
 #include <thumbnailmanager_qt.h>
 #include <cntmaptileservice.h>  //For maptile processing
 #include <qversitcontactexporter.h>
 #include <qversitwriter.h>
 #include <xqservicerequest.h>
+#include <QTimer>  //Progress indication icon
 
+#include <cntdebug.h>
 #include "cntcontactcarddatacontainer.h"
 #include "cntcontactcarddetailitem.h"
 #include "cntcontactcardheadingitem.h"
@@ -58,11 +61,14 @@
 #include "cntimageutility.h"
 #include "cntfavourite.h"
 #include "cntactionlauncher.h"
-#include <hbselectiondialog.h>
+#include "cntpresencelistener.h"
 
+#define CNT_MAPTILE_PROGRESS_TIMER  100 //100 msec
+#define CNT_UNKNOWN_MAPTILE_STATUS  -1
 
 const char *CNT_CONTACTCARDVIEW_XML = ":/xml/contacts_contactcard.docml";
-
+const char *CNT_MAPTILE_INPROGRESS_ICON = "qtg_anim_small_loading_1";
+const char *CNT_MAPTILE_SEARCH_STOP_ICON = "qtg_mono_search_stop";
 /*!
 Constructor, initialize member variables.
 \a viewManager is the parent that creates this view. \a parent is a pointer to parent QGraphicsItem (by default this is 0)
@@ -78,7 +84,6 @@
     mHeadingItem(NULL),
     mThumbnailManager(NULL),
     mAvatar(NULL),
-    mIsHandlingMenu(false),
     mFavoriteGroupId(-1),
     mLoader(NULL),
     mContactAction(NULL),
@@ -87,7 +92,10 @@
     mVCardIcon(NULL),
     mShareUi(NULL),
     mAcceptSendKey(true),
-    mSendKeyListModel(NULL)
+    mSendKeyListModel(NULL),
+    mPresenceListener(NULL),
+    mMaptile(NULL),
+	mProgressTimer(NULL)
 {
     bool ok;
     document()->load(CNT_CONTACTCARDVIEW_XML, &ok);
@@ -110,6 +118,15 @@
     mBackKey = new HbAction(Hb::BackNaviAction, mView);
     mView->setNavigationAction(mBackKey);  
     connect(mBackKey, SIGNAL(triggered()), this, SLOT(showPreviousView()));
+	
+    mProgressTimer = new QTimer(this);
+    mProgressTimer->setSingleShot(true);
+    connect(mProgressTimer, SIGNAL(timeout()),this, SLOT(updateSpinningIndicator())); 
+
+    mMaptile = new CntMapTileService;
+    //Connect for maptile status evenet
+    bool ret = QObject::connect( mMaptile, SIGNAL(maptileFetchingStatusUpdate(int, 
+            int,int)),this,SLOT(mapTileStatusReceived(int,int,int)));
 }
 
 /*!
@@ -131,18 +148,28 @@
     delete mLoader;
     mLoader = NULL;
     
-    if (mVCardIcon) {
+    if (mVCardIcon) 
+    {
         delete mVCardIcon;
         mVCardIcon = NULL;
     }
     
-    if (mShareUi) {
+    if (mShareUi) 
+    {
         delete mShareUi;
         mShareUi = NULL;
     }
     
     delete mSendKeyListModel;
     mSendKeyListModel = NULL;
+    
+    delete mPresenceListener;
+    mPresenceListener = NULL;
+	delete mMaptile;
+    mMaptile = NULL;
+    
+    delete mProgressTimer;
+    mProgressTimer = NULL;
 }
 
 /*!
@@ -175,6 +202,8 @@
 */
 void CntContactCardViewPrivate::activate(CntAbstractViewManager* aMgr, const CntViewParameters aArgs)
 {   
+    CNT_ENTRY
+    
     mViewManager = aMgr;
     mArgs = aArgs;
     
@@ -208,6 +237,13 @@
     mHeadingItem->setDetails(mContact);
     connect(mHeadingItem, SIGNAL(passLongPressed(const QPointF&)), this, SLOT(drawMenu(const QPointF&)));
     connect(mHeadingItem, SIGNAL(passShortPressed(const QPointF&)), this, SLOT(doChangeImage()));
+    
+    // presence listener
+    mPresenceListener = new CntPresenceListener(*mContact);
+    connect(mPresenceListener, SIGNAL(fullPresenceUpdated(bool)), mHeadingItem, SLOT(setOnlineStatus(bool)));
+    bool online;
+    mPresenceListener->initialPresences(online);
+    mHeadingItem->setOnlineStatus(online);
 
     mImageLabel = static_cast<CntImageLabel*>(document()->findWidget("cnt_contactcard_image"));
     connect(mImageLabel, SIGNAL(iconClicked()), this, SLOT(doChangeImage()));
@@ -226,7 +262,7 @@
     }
     
     // data
-    mDataContainer = new CntContactCardDataContainer(mContact, NULL, myCard);
+    mDataContainer = new CntContactCardDataContainer(mContact, NULL, myCard, mMaptile );
 
     // scroll area + container widget
     mScrollArea = static_cast<HbScrollArea*>(document()->findWidget(QString("scrollArea")));
@@ -299,6 +335,43 @@
             else
             {    
                 CntContactCardDetailItem* item = new CntContactCardDetailItem(index, mContainerWidget, false);
+				//To check whether maptile status  icon is set with the address 
+                if( ( dataItem->titleText() == hbTrId("txt_phob_formlabel_address") ||
+                      dataItem->titleText() == hbTrId("txt_phob_formlabel_address_home")||  
+                      dataItem->titleText() == hbTrId("txt_phob_formlabel_address_work") ) &&
+                      dataItem->secondaryIcon().iconName() == QString(CNT_MAPTILE_INPROGRESS_ICON) )
+                    
+                {
+                    //Information for displaying maptile fetching progress bar.
+                    //Memory will be deleted from the queue.
+                    CntContactCardMapTileDetail* detail = new CntContactCardMapTileDetail;
+                    if( detail )
+                    {
+                        detail->mContactId = mContact->id().localId();
+                            
+                        if( dataItem->titleText() == hbTrId("txt_phob_formlabel_address") )
+                        {
+                               detail->mAddressType = CntMapTileService::AddressPreference;
+                        }
+                        else if ( dataItem->titleText() ==  hbTrId("txt_phob_formlabel_address_home") )
+                        {
+                               detail->mAddressType = CntMapTileService::AddressHome;
+                        }
+                        else if( dataItem->titleText() ==  hbTrId("txt_phob_formlabel_address_work") )
+                        {
+                               detail->mAddressType = CntMapTileService::AddressWork;
+                        }
+                        
+                        detail->mProgressCount = 0;
+                        detail->mDetailItem =  item;
+                        detail->maptileStatus = CNT_UNKNOWN_MAPTILE_STATUS;
+                        mAddressList.append( detail );  
+                    }
+                    
+                    //Update the spinning indicator
+                    updateSpinningIndicator();
+                    
+                }
                 item->setDetails(dataItem);
                 mContainerLayout->addItem(item);
             }
@@ -312,37 +385,160 @@
         if( favouriteGroupId != 0 )
         {
             setAsFavorite = CntFavourite::isMemberOfFavouriteGroup( contactManager(), mContact );
-            mHeadingItem->setSecondaryIcon( setAsFavorite ); // if contact is part of favourites group
+            mHeadingItem->setFavoriteStatus( setAsFavorite ); // if contact is part of favourites group
         }
         qobject_cast<HbAction *>(document()->findObject("cnt:setasfavorite"))->setVisible( !setAsFavorite );
         qobject_cast<HbAction *>(document()->findObject("cnt:removefromfavorite"))->setVisible( setAsFavorite );
     }
-        
+    document()->findWidget("viewToolbar")->setParent(mView);
+    document()->findWidget("viewMenu")->setParent(mView);
+    
     // Menu items
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:sendbusinesscard")), SIGNAL(triggered()),
-                this, SLOT (sendBusinessCard()));
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:deletecontact")), SIGNAL(triggered()),
-                this, SLOT (deleteContact()));
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:setasfavorite")), SIGNAL(triggered()),
-                this, SLOT (setAsFavorite()));
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:removefromfavorite")), SIGNAL(triggered()),
-                this, SLOT (removeFromFavorite()));    
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:placecontacttohs")), SIGNAL(triggered()),
-                this, SLOT (sendToHs()));
+    connectAction("cnt:sendbusinesscard", SLOT(sendBusinessCard()));
+    connectAction("cnt:deletecontact", SLOT(deleteContact()));
+    connectAction("cnt:setasfavorite", SLOT(setAsFavorite()));
+    connectAction("cnt:removefromfavorite", SLOT(removeFromFavorite()));
+    connectAction("cnt:placecontacttohs", SLOT(sendToHs()));
+    connectAction("cnt:edit", SLOT(editContact()));
+    connectAction("cnt:history", SLOT(viewHistory()));
+    connectAction("cnt:sendMyCard", SLOT(sendBusinessCard()));
+    connectAction("cnt:activityStream", NULL);      // placeholder until this action is implemented (needed to avoid memory leak)
     
-    // Toolbar items
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:edit")), SIGNAL(triggered()),
-                this, SLOT(editContact()));
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:history")), SIGNAL(triggered()),
-                this, SLOT(viewHistory()));
-    connect(qobject_cast<HbAction *>(document()->findObject("cnt:sendMyCard")), SIGNAL(triggered()),
-                this, SLOT (sendBusinessCard()));
+    emit viewActivated( mViewManager, aArgs );
+
+    CNT_EXIT
+}
+
+/*
+    Connects the action with a slot and also sets the view as the parent for the action.
+ */
+void CntContactCardViewPrivate::connectAction(QString actionName, const char* slot)
+{
+    HbAction *action = qobject_cast<HbAction *>(document()->findObject(actionName));
+    if (action) {
+        action->setParent(mView);
+        if (slot != NULL) {
+            connect(action, SIGNAL(triggered()), this, slot);
+        }
+    }
+}
+
+/*
+    Updates the maptile fetching spinning indicator icon
+ */
+void CntContactCardViewPrivate::updateSpinningIndicator()
+{
+    //Check all address details( Preferred, Home, Work )
+    for( int index = 0 ; index < mAddressList.count(); )
+    {
+        //Maptile status not received update the rotating icon
+        if( mAddressList[index]->maptileStatus == CNT_UNKNOWN_MAPTILE_STATUS )
+        {
+             QString iconName("qtg_anim_small_loading_");
+             mAddressList[index]->mProgressCount = mAddressList[index]->mProgressCount % 10 + 1;
+             iconName.append(QVariant(mAddressList[index]->mProgressCount).toString());
+             
+             HbIcon icon(iconName);
+             mAddressList[index]->mDetailItem->setSecondaryIconItem( icon );
+             mAddressList[index]->mDetailItem->update();   
+             mProgressTimer->start(CNT_MAPTILE_PROGRESS_TIMER); 
+             index++;
+        }
+        else
+        {
+            //Maptile status received. Show the maptile image if available
+            CntMapTileService::ContactAddressType sourceAddressType =
+                    static_cast <CntMapTileService::ContactAddressType>( mAddressList[index]->mAddressType );
+             
+            QContactLocalId contactId = mContact->id().localId();
+             
+            if( mAddressList[index]->mDetailItem != NULL )
+            {
+                 if( mAddressList[index]->maptileStatus == CntMapTileService::MapTileFetchingCompleted )
+                 {
+                     //Empty icon. Clear the search stop icon
+                     HbIcon icon;
+                     mAddressList[index]->mDetailItem->setSecondaryIconItem( icon );
+                         
+                     QString imagePath;
+                                     
+                     //Read the maptile path and update the image
+                     mMaptile->getMapTileImage( contactId, sourceAddressType, imagePath );
+                     if( !imagePath.isEmpty() )
+                     {
+                         HbIcon icon( imagePath );
+                         
+                         HbLabel* iconLabel = new HbLabel(mView);
+                         iconLabel->setIcon(icon);
+                         
+                         int width = icon.width();
+                         int height = icon.height();    
+                         
+                         //HbLabel setPreferredSize is not working properly,
+                         //so added minimum , maximum size to fix the issue
+                         iconLabel->setPreferredSize(QSizeF(width,height));
+                         iconLabel->setMinimumSize(QSizeF(width, height));
+                         iconLabel->setMaximumSize(QSizeF(width, height));
+                         iconLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed,
+                                             QSizePolicy::Fixed));        
+                        
+                         //find the index of the item and insert maptile in the next index 
+                         for( int itemIndex = 0 ; itemIndex < mContainerLayout->count(); itemIndex++ )
+                         {
+                             if( mContainerLayout->itemAt(itemIndex) == mAddressList[index]->mDetailItem )
+                             {
+                                 mContainerLayout->insertItem( itemIndex+1, iconLabel );
+                                 break;
+                             }
+                         }
+                         
+                     }
+                 }
+                 else
+                 {
+                     //Maptile fetching failed. Show the search stop icon
+                     QString iconName(CNT_MAPTILE_SEARCH_STOP_ICON);
+                     HbIcon icon(iconName);
+                     mAddressList[index]->mDetailItem->setSecondaryIconItem( icon );
+                     bool visible = mAddressList[index]->mDetailItem->isVisible();
+                     mAddressList[index]->mDetailItem->update();
  
-    emit viewActivated( mViewManager, aArgs );
+                 }
+                 
+                 delete mAddressList[index];
+                 mAddressList.removeAt(index);
+            }
+            else
+            {
+                 //increment the index now
+                 index++;
+            }
+        }
+    }
+}
+
+/*
+* Slot to receive the maptile status information
+*/
+void CntContactCardViewPrivate::mapTileStatusReceived( int contactid, int addressType, int status)
+{
+    //Update the maptile status information for all 3( Preferred, Work, Home ) address
+    for( int index = 0 ; index < mAddressList.count(); index++  )
+    {
+        if( mAddressList[index]->mContactId == contactid &&  
+                 mAddressList[index]->mAddressType == addressType )
+        {
+            mAddressList[index]->maptileStatus = status;
+        }
+    }
+    
+    updateSpinningIndicator();
 }
 
 void CntContactCardViewPrivate::thumbnailReady(const QPixmap& pixmap, void *data, int id, int error)
 {
+    CNT_ENTRY
+    
     Q_UNUSED(data);
     Q_UNUSED(id);
     if (!error)
@@ -354,6 +550,8 @@
         mImageLabel->clear();
         mImageLabel->setIcon(icon);
     }
+    
+    CNT_EXIT
 }
 
 /*!
@@ -397,7 +595,7 @@
     
     qobject_cast<HbAction *>(document()->findObject("cnt:removefromfavorite"))->setVisible(true);
     qobject_cast<HbAction *>(document()->findObject("cnt:setasfavorite"))->setVisible(false);
-    mHeadingItem->setSecondaryIcon(true);  
+    mHeadingItem->setFavoriteStatus(true);  
 }
 
 void CntContactCardViewPrivate::removeFromFavorite()
@@ -407,7 +605,7 @@
 
     qobject_cast<HbAction *>(document()->findObject("cnt:removefromfavorite"))->setVisible(false);
     qobject_cast<HbAction *>(document()->findObject("cnt:setasfavorite"))->setVisible(true);
-    mHeadingItem->setSecondaryIcon(false); 
+    mHeadingItem->setFavoriteStatus(false); 
 }
 
 /*!
@@ -728,9 +926,10 @@
 
 void CntContactCardViewPrivate::handleSendBusinessCard( HbAction* aAction )
 {
+    Q_UNUSED(aAction);
     qDebug() << "CntContactCardViewPrivate::handleSendBusinessCard - IN";
     QList<QContact> list;
-    /* if ( aAction && aAction->objectName() == "cancel" )
+    /*if ( aAction && aAction->objectName() == "cancel" )
     {
         QContact tmpContact( *mContact );
         foreach ( QContactAvatar a, tmpContact.details<QContactAvatar>() )
@@ -743,14 +942,13 @@
     {
         list.append( *mContact );
     }*/
-    
     QContact tmpContact( *mContact );
     foreach ( QContactAvatar a, tmpContact.details<QContactAvatar>() )
     {
         tmpContact.removeDetail( &a );
     }
     list.append( tmpContact );
-      
+    
     QString tempDir = QDir::tempPath().append("/tempcntvcard");
     QDir dir(tempDir);
            
@@ -758,7 +956,10 @@
     if (!dir.exists()) 
     {
         // Create a temp directory
-        QDir::temp().mkdir("tempcntvcard");
+        if (!QDir::temp().mkdir("tempcntvcard"))
+        {
+            return;
+        }
     } 
     else 
     {    
@@ -857,12 +1058,6 @@
 */
 void CntContactCardViewPrivate::drawMenu(const QPointF &aCoords)
 {
-    if (mIsHandlingMenu) return;
-    
-    // To avoid re-drawing the menu and causing a crash due to 
-    // multiple emitted signals, set state that we are handling the signal
-    mIsHandlingMenu = true;
-    
     HbMenu *menu = new HbMenu();
     menu->addAction(hbTrId("txt_phob_menu_change_picture"), this, SLOT(doChangeImage()) );
     if (mAvatar)
@@ -872,7 +1067,7 @@
     menu->setAttribute( Qt::WA_DeleteOnClose );
     menu->setPreferredPos( aCoords );
     menu->open();
-    }
+}
 
 /*!
 Return the pointer to the document loader
@@ -998,6 +1193,4 @@
     }
 }
 
-
-
 // end of file
--- a/phonebookui/pbkcommonui/src/cntdefaultviewmanager.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntdefaultviewmanager.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -24,6 +24,8 @@
 #include <qtcontacts.h>
 #include "cntviewnavigator.h"
 #include "cntsimutility.h"
+#include "cntdebug.h"
+#include <QApplication>
 
 CntDefaultViewManager::CntDefaultViewManager( HbMainWindow* aWindow ) : QObject(),
     mFactory(NULL),
@@ -32,8 +34,9 @@
     mNavigator(NULL),
     mMainWindow( aWindow ),
     mSimUtility(NULL)
-
-{    
+{
+    CNT_ENTRY
+    
     setViewFactory(new CntDefaultViewFactory());
     setViewNavigator(new CntViewNavigator(this));
 
@@ -44,33 +47,76 @@
         delete mSimUtility; 
         mSimUtility = 0;
     }
+    
+    CNT_EXIT
 }
 
 CntDefaultViewManager::~CntDefaultViewManager()
 {
+    CNT_ENTRY
+    
+    cleanup();
+
+    CNT_EXIT
+}
+
+void CntDefaultViewManager::cleanup()
+{
+    CNT_ENTRY
+
+    mOldView = mCurrent;
+    mCurrent = NULL;
+    deleteOldView();
+    
+    qDeleteAll(mBackends);
+    mBackends.clear();
+
     qDeleteAll(mDefaults.values());
+    mDefaults.clear();
+
     delete mFactory;
+    mFactory = NULL;
+
     delete mSimUtility;
+    mSimUtility = NULL;
+    
+    CNT_EXIT
 }
 
 void CntDefaultViewManager::setViewFactory( CntAbstractViewFactory* aFactory ) 
 {
+    CNT_ENTRY
+    
     if ( aFactory )
     {
+        if (mFactory) {
+            delete mFactory;
+        }
         mFactory = aFactory;
     }
+    
+    CNT_EXIT
 }
 
 void CntDefaultViewManager::setViewNavigator( CntViewNavigator* aNavigator )
 {
+    CNT_ENTRY
+    
     if ( aNavigator )
     {
+        if (mNavigator) {
+            delete mNavigator;
+        }
         mNavigator = aNavigator;
     }
+    
+    CNT_EXIT
 }
 
 void CntDefaultViewManager::back(const CntViewParameters aArgs)
 {
+    CNT_ENTRY
+    
     mArgs.clear();
     
     QFlags<Hb::ViewSwitchFlag> flags;
@@ -90,17 +136,39 @@
     {
         switchView( mArgs, flags );
     }
+    else {
+        // exiting application
+        cleanup();
+        closeApp();
+    }
+    
+    CNT_EXIT
+}
+
+void CntDefaultViewManager::closeApp()
+{
+    CNT_ENTRY
+    
+    qApp->quit();
+    
+    CNT_EXIT
 }
 
 void CntDefaultViewManager::changeView(const CntViewParameters aArgs)
 {
+    CNT_ENTRY
+    
     QFlags<Hb::ViewSwitchFlag> flags;
     mNavigator->next(aArgs.value(EViewId).toInt(), flags);
     switchView(aArgs, flags);
+    
+    CNT_EXIT
 }
 
 QContactManager* CntDefaultViewManager::contactManager( const QString& aType )
 {
+    CNT_ENTRY
+    
     foreach ( QContactManager* mgr, mBackends ) 
     {
         QString uri = mgr->managerUri();
@@ -116,11 +184,14 @@
         mBackends.append( manager );
     }
     
+    CNT_EXIT
     return manager;
 }
 
 void CntDefaultViewManager::removeCurrentView()
 {
+    CNT_ENTRY
+    
     if (mOldView) 
     {
         connect(mMainWindow, SIGNAL(viewReady()), this, SLOT(deleteOldView()));
@@ -129,10 +200,14 @@
     {
         mMainWindow->setInteractive( true );
     }
+    
+    CNT_EXIT
 }
 
 void CntDefaultViewManager::deleteOldView()
 {
+    CNT_ENTRY
+    
     disconnect(mMainWindow, SIGNAL(viewReady()), this, SLOT(deleteOldView()));
     
     if (mOldView)
@@ -141,7 +216,7 @@
         
         // Due to something strange in wk16, this check will fail occationally and cause
         // a memory leak... most likely when opening edit view for the first time
-        if (!mOldView->view()->isVisible())
+        if (mCurrent == NULL || !mOldView->view()->isVisible())
         {
             mMainWindow->removeView(mOldView->view());
             
@@ -160,10 +235,14 @@
     }
 
     mMainWindow->setInteractive(true);
+    
+    CNT_EXIT
 }
 
 void CntDefaultViewManager::switchView(const CntViewParameters aArgs, QFlags<Hb::ViewSwitchFlag> flags)
 {
+    CNT_ENTRY
+    
     mMainWindow->setInteractive(false);
     int id = aArgs.value(EViewId).toInt();
     if ( id != noView )
@@ -184,12 +263,13 @@
         
         mOldView = mCurrent;
         mCurrent = nextView;
-            
         mMainWindow->addView(mCurrent->view());
         mMainWindow->setCurrentView(mCurrent->view(), true, flags);
         mCurrent->activate(this, aArgs);
         
         removeCurrentView();
     }
+    
+    CNT_EXIT
 }
 // End of File
--- a/phonebookui/pbkcommonui/src/cntdetaileditor.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntdetaileditor.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -27,12 +27,14 @@
 #include <hblineedit.h>
 #include <hbinputeditorinterface.h>
 #include <hbinputstandardfilters.h>
+#include <cntdebug.h>
 
 const char *CNT_DETAILEDITOR_XML = ":/xml/contacts_detail_editor.docml";
 
 CntDetailEditor::CntDetailEditor( int aId ) :
     QObject(),
     mDataFormModel(NULL),
+    mHeader(NULL),   
     mId(aId),
     mView(NULL),
     mLoader(NULL),   
@@ -73,7 +75,7 @@
 
 void CntDetailEditor::setInsertAction( const QString aInsert )
 {
-    HbAction* insert = new HbAction( aInsert );
+    HbAction* insert = new HbAction( aInsert, mView );
     mView->menu()->insertAction(mCancel, insert);
     connect( insert, SIGNAL(triggered()), this, SLOT(insertField()) );
 }
@@ -84,7 +86,8 @@
     mArgs = aArgs; //don't loose the params while swiching between editview and editorviews.
     
     mCancel = static_cast<HbAction*>(document()->findObject("cnt:discardchanges"));
-    mView->menu()->addAction( mCancel );
+    mCancel->setParent(mView);
+    mView->menu()->addAction(mCancel);
     connect( mCancel, SIGNAL(triggered()), this, SLOT(discardChanges()) );
     
     if ( mView->navigationAction() != mSoftkey) {
@@ -96,11 +99,11 @@
     {
         selectedContact = aArgs.value(ESelectedGroupContact).value<QContact>();
         connect( mDataForm, SIGNAL(itemShown(const QModelIndex&)), this, SLOT(handleItemShown(const QModelIndex&)) );
-
     }
     else
     {
         selectedContact = aArgs.value(ESelectedContact).value<QContact>();
+        connect( mDataForm, SIGNAL(itemShown(const QModelIndex&)), this, SLOT(handleItemShown(const QModelIndex&)) );
     }
     mEditorFactory->setupEditorView(*this, selectedContact);
     
@@ -157,6 +160,12 @@
             edit->setInputMethodHints( Qt::ImhDialableCharactersOnly );
         }
     }
+    else
+    {
+        HbDataFormViewItem* viewItem = static_cast<HbDataFormViewItem*>(mDataForm->itemByIndex( aIndex ));
+        HbLineEdit* edit = static_cast<HbLineEdit*>( viewItem->dataItemContentWidget() );
+        edit->setInputMethodHints( Qt::ImhNoPredictiveText );
+    }
 }
 
 void CntDetailEditor::discardChanges()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/src/cntdetailorderinghelper.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,270 @@
+/*
+* 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:  
+*
+*/
+
+#include "cntdetailorderinghelper.h"
+
+/**
+* Return ordered list of supported (by UI implementation) phone numbers
+*
+* @param QContact&, contact
+* @return QList<QContactPhoneNumber>, ordered list of supported phone numbers
+*/    
+QList<QContactPhoneNumber> CntDetailOrderingHelper::getOrderedSupportedPhoneNumbers( const QContact& contact )
+{
+    QMap<QPair<QString, QString>, int> orderMap;
+    
+    QPair<QString, QString> pair = qMakePair(QContactPhoneNumber::SubTypeMobile.operator QString(), QString(""));
+    orderMap.insert(pair , EMobile);
+    pair = qMakePair(QContactPhoneNumber::SubTypeMobile.operator QString(), QContactPhoneNumber::ContextHome.operator QString());
+    orderMap.insert(pair , EMobileHome);
+    pair = qMakePair(QContactPhoneNumber::SubTypeMobile.operator QString(), QContactPhoneNumber::ContextWork.operator QString());
+    orderMap.insert(pair , EMobileWork);
+    
+    pair = qMakePair(QContactPhoneNumber::SubTypeLandline.operator QString(), QString(""));
+    orderMap.insert(pair , EPhone);
+    pair = qMakePair(QContactPhoneNumber::SubTypeLandline.operator QString(), QContactPhoneNumber::ContextHome.operator QString());
+    orderMap.insert(pair , EPhoneHome);
+    pair = qMakePair(QContactPhoneNumber::SubTypeLandline.operator QString(), QContactPhoneNumber::ContextWork.operator QString());
+    orderMap.insert(pair , EPhoneWork);
+    
+    pair = qMakePair(QContactPhoneNumber::SubTypeFax.operator QString(), QString(""));
+    orderMap.insert(pair , EFax);
+    pair = qMakePair(QContactPhoneNumber::SubTypeFax.operator QString(), QContactPhoneNumber::ContextHome.operator QString());
+    orderMap.insert(pair , EFaxHome);
+    pair = qMakePair(QContactPhoneNumber::SubTypeFax.operator QString(), QContactPhoneNumber::ContextWork.operator QString());
+    orderMap.insert(pair , EFaxWork);
+    
+    pair = qMakePair(QContactPhoneNumber::SubTypePager.operator QString(), QString(""));
+    orderMap.insert(pair , EPager);
+    pair = qMakePair(QContactPhoneNumber::SubTypeAssistant.operator QString(), QString(""));
+    orderMap.insert(pair , EAssistant);
+    pair = qMakePair(QContactPhoneNumber::SubTypeCar.operator QString(), QString(""));
+    orderMap.insert(pair , ECar);
+    
+    QList<QContactPhoneNumber> completeList = contact.details<QContactPhoneNumber>();
+    QList<QContactPhoneNumber> orderedSupportedList;
+    
+    foreach ( QContactPhoneNumber number, completeList )
+    {
+        QString context = number.contexts().isEmpty() ? QString() : number.contexts().first();
+        QString subtype = number.subTypes().isEmpty() ? number.definitionName() : number.subTypes().first();
+        
+        QPair<QString, QString> pair = qMakePair(subtype, context);
+        
+        if ( orderMap.keys().contains(pair) )
+        {
+            int position = orderMap.value(pair);
+            bool added = false;
+            
+            for (int i = 0; i < orderedSupportedList.count(); i++)
+            {
+                QString currentContext = orderedSupportedList.at(i).contexts().isEmpty() ? 
+                        QString() : orderedSupportedList.at(i).contexts().first();
+                
+                // this is safe because no details without a subtype can be in the list
+                QString currentSubtype = orderedSupportedList.at(i).subTypes().first();
+                
+                QPair<QString, QString> currentPair = qMakePair(currentSubtype, currentContext);
+                
+                int currentPosition = orderMap.value(currentPair);
+                
+                if (currentPosition > position)
+                {
+                    orderedSupportedList.insert(i, number);
+                    added = true;
+                    break;
+                }
+            }
+            
+            if (!added)
+            {
+                orderedSupportedList.append(number);
+            }
+        }
+    }
+    
+    return orderedSupportedList;
+}
+
+/**
+* Return ordered list of supported (by UI implementation) online accounts
+*
+* @param QContact&, contact
+* @return QList<QContactOnlineAccount>, ordered list of supported online accounts
+*/    
+QList<QContactOnlineAccount> CntDetailOrderingHelper::getOrderedSupportedOnlineAccounts( const QContact &contact )
+{
+    QMap<QPair<QString, QString>, int> orderMap;
+    
+    QPair<QString, QString> pair = qMakePair(QContactOnlineAccount::SubTypeSipVoip.operator QString(), QString(""));
+    orderMap.insert(pair , EInternetTelephone);
+    pair = qMakePair(QContactOnlineAccount::SubTypeSipVoip.operator QString(), QContactOnlineAccount::ContextHome.operator QString());
+    orderMap.insert(pair , EInternetTelephoneHome);
+    pair = qMakePair(QContactOnlineAccount::SubTypeSipVoip.operator QString(), QContactOnlineAccount::ContextWork.operator QString());
+    orderMap.insert(pair , EInternetTelephoneWork);
+    
+    pair = qMakePair(QContactOnlineAccount::SubTypeSip.operator QString(), QString(""));
+    orderMap.insert(pair , ESip);
+    
+    QList<QContactOnlineAccount> completeList = contact.details<QContactOnlineAccount>();
+    QList<QContactOnlineAccount> orderedSupportedList;
+    
+    foreach ( QContactOnlineAccount account, completeList )
+    {
+        QString context = account.contexts().isEmpty() ? QString() : account.contexts().first();
+        QString subtype = account.subTypes().isEmpty() ? account.definitionName() : account.subTypes().first();
+        
+        QPair<QString, QString> pair = qMakePair(subtype, context);
+        
+        if ( orderMap.keys().contains(pair) )
+        {
+            int position = orderMap.value(pair);
+            bool added = false;
+            
+            for (int i = 0; i < orderedSupportedList.count(); i++)
+            {
+                QString currentContext = orderedSupportedList.at(i).contexts().isEmpty() ? 
+                        QString() : orderedSupportedList.at(i).contexts().first();
+                
+                // this is safe because no details without a subtype can be in the list
+                QString currentSubtype = orderedSupportedList.at(i).subTypes().first();
+                
+                QPair<QString, QString> currentPair = qMakePair(currentSubtype, currentContext);
+                
+                int currentPosition = orderMap.value(currentPair);
+                
+                if (currentPosition > position)
+                {
+                    orderedSupportedList.insert(i, account);
+                    added = true;
+                    break;
+                }
+            }
+            
+            if (!added)
+            {
+                orderedSupportedList.append(account);
+            }
+        }
+    }
+    
+    return orderedSupportedList;
+}
+
+/**
+* Return ordered list of email accounts
+*
+* @param QContact&, contact
+* @return QList<QContactEmailAddress>, ordered list of email accounts
+*/    
+QList<QContactEmailAddress> CntDetailOrderingHelper::getOrderedEmailAccounts( const QContact &contact )
+{
+    QMap<QString, int> orderMap;
+    
+    orderMap.insert("" , EEmail);
+    orderMap.insert(QContactEmailAddress::ContextHome , EEmailHome);
+    orderMap.insert(QContactEmailAddress::ContextWork , EEmailWork);
+    
+    QList<QContactEmailAddress> completeList = contact.details<QContactEmailAddress>();
+    QList<QContactEmailAddress> orderedSupportedList;
+    
+    foreach ( QContactEmailAddress email, completeList )
+    {
+        QString context = email.contexts().isEmpty() ? QString() : email.contexts().first();
+        
+        if ( orderMap.keys().contains(context) )
+        {
+            int position = orderMap.value(context);
+            bool added = false;
+            
+            for (int i = 0; i < orderedSupportedList.count(); i++)
+            {
+                QString currentContext = orderedSupportedList.at(i).contexts().isEmpty() ? 
+                        QString() : orderedSupportedList.at(i).contexts().first();
+                
+                int currentPosition = orderMap.value(currentContext);
+                
+                if (currentPosition > position)
+                {
+                    orderedSupportedList.insert(i, email);
+                    added = true;
+                    break;
+                }
+            }
+            
+            if (!added)
+            {
+                orderedSupportedList.append(email);
+            }
+        }
+    }
+    
+    return orderedSupportedList;
+}
+
+/**
+* Return ordered list of url details
+*
+* @param QContact&, contact
+* @return QList<QContactUrl>, ordered list of url details
+*/   
+QList<QContactUrl> CntDetailOrderingHelper::getOrderedUrls( const QContact &contact )
+{
+    QMap<QString, int> orderMap;
+    
+    orderMap.insert("" , EUrl);
+    orderMap.insert(QContactUrl::ContextHome , EUrlHome);
+    orderMap.insert(QContactUrl::ContextWork , EUrlWork);
+    
+    QList<QContactUrl> completeList = contact.details<QContactUrl>();
+    QList<QContactUrl> orderedSupportedList;
+    
+    foreach ( QContactUrl url, completeList )
+    {
+        QString context = url.contexts().isEmpty() ? QString() : url.contexts().first();
+        
+        if ( orderMap.keys().contains(context) )
+        {
+            int position = orderMap.value(context);
+            bool added = false;
+            
+            for (int i = 0; i < orderedSupportedList.count(); i++)
+            {
+                QString currentContext = orderedSupportedList.at(i).contexts().isEmpty() ? 
+                        QString() : orderedSupportedList.at(i).contexts().first();
+                
+                int currentPosition = orderMap.value(currentContext);
+                
+                if (currentPosition > position)
+                {
+                    orderedSupportedList.insert(i, url);
+                    added = true;
+                    break;
+                }
+            }
+            
+            if (!added)
+            {
+                orderedSupportedList.append(url);
+            }
+        }
+    }
+    
+    return orderedSupportedList;
+}
+
+// EOF
--- a/phonebookui/pbkcommonui/src/cnteditview_p.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnteditview_p.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -22,6 +22,7 @@
 #include "cnteditviewheadingitem.h"
 #include "cntimagelabel.h"
 
+#include <qtcontacts.h>
 #include <hbdocumentloader.h>
 #include <thumbnailmanager_qt.h>
 #include <hbabstractviewitem.h>
@@ -64,10 +65,16 @@
     
     mSoftkey = new HbAction(Hb::BackNaviAction, mView);
     mDiscard = static_cast<HbAction*>( mDocument->findObject("cnt:discard") );
+    mDiscard->setParent(mView);
+
     mSave = static_cast<HbAction*>( mDocument->findObject("cnt:savecontact") );
+    mSave->setParent(mView);
+
     mDelete = static_cast<HbAction*>( mDocument->findObject("cnt:deletecontact") );
+    mDelete->setParent(mView);
     
     HbAction* add = static_cast<HbAction*>( mDocument->findObject("cnt:adddetail_options") );
+    add->setParent(mView);
 
     connect( add, SIGNAL(triggered()), this, SLOT(addDetailItem()) );
     connect( mDelete, SIGNAL(triggered()), this, SLOT(deleteContact()) );
@@ -86,7 +93,6 @@
 {
     mView->deleteLater();
     delete mDocument;
-    delete mListView;
     delete mModel;
     delete mContact;
     
@@ -126,14 +132,16 @@
         
     QString myCard = mArgs.value( EMyCard ).toString();
     QString selectedAction = mArgs.value( ESelectedAction ).toString();
-    
     QVariant contact = aArgs.value( ESelectedContact );
-    mContact = new QContact( contact.value<QContact>() );
+    setSelectedContact( contact.value<QContact>() );
+        
     QContactLocalId localId = mContact->localId();
-    
     QContactManager* cm = mMgr->contactManager(SYMBIAN_BACKEND);
     QContactLocalId selfContactId = cm->selfContactId();
-    mIsMyCard = ( localId == selfContactId && localId != 0 ) || myCard == "myCard"; 
+    mIsMyCard = ( localId == selfContactId && localId != 0 ) || myCard == "myCard";
+    
+    if ( mHeading )
+        mHeading->setDetails( mContact, mIsMyCard );
 
     // if "MyCard", set slightly different heading and options menu
     if ( mIsMyCard )
@@ -166,10 +174,6 @@
         mSave->setEnabled( false );
     }
     
-    mHeading->setDetails( mContact );
-    mModel = new CntEditViewListModel( mContact );
-    mListView->setModel( mModel );
-
     mThumbnailManager = new ThumbnailManager(this);
     mThumbnailManager->setMode(ThumbnailManager::Default);
     mThumbnailManager->setQualityPreference(ThumbnailManager::OptimizeForQuality);
@@ -335,7 +339,7 @@
         QContactManager* cm = mMgr->contactManager( SYMBIAN_BACKEND );
         QString name = cm->synthesizedDisplayLabel( *mContact );
         HbMessageBox::question(HbParameterLengthLimiter(hbTrId("txt_phob_info_delete_1")).arg(name), this, SLOT(handleDeleteContact(HbAction*)), 
-                hbTrId("txt_phob_button_delete"), hbTrId("txt_common_button_cancel"));
+                hbTrId("txt_common_button_delete"), hbTrId("txt_common_button_cancel"));
     }
 }
 
@@ -392,22 +396,18 @@
                 
                 QString name = mgr->synthesizedDisplayLabel( *mContact );
                 
+                emit contactUpdated(success);
+                
                 if ( success )
                 {
-                    HbDeviceNotificationDialog notificationDialog;
-                    notificationDialog.setTitle(HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contact_1_saved")).arg(name));
-                    notificationDialog.show();
+                    HbDeviceNotificationDialog::notification(QString(),HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contact_1_saved")).arg(name));
                 }
                 else
                 {
                     //TODO: localization is missing
-                    HbDeviceNotificationDialog notificationDialog;
-                    notificationDialog.setTitle(qtTrId("SAVING FAILED!"));
-                    notificationDialog.show();
+                    HbDeviceNotificationDialog::notification(QString(),qtTrId("SAVING FAILED!"));
                 }
                 
-                emit contactUpdated(success);
-                
                 QVariant var;
                 var.setValue(*mContact);
                 mArgs.insert(ESelectedContact, var);
@@ -431,22 +431,18 @@
                 
                 QString name = mgr->synthesizedDisplayLabel( *mContact );
                 
+                emit contactUpdated( success );
+                
                 if ( success )
                 {
-                    HbDeviceNotificationDialog notificationDialog;
-                    notificationDialog.setTitle(HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contacts_1_updated")).arg(name));
-                    notificationDialog.show();
+                    HbDeviceNotificationDialog::notification(QString(),HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contacts_1_updated")).arg(name));
                 }
                 else
                 {
                     //TODO: localization is missing
-                    HbDeviceNotificationDialog notificationDialog;
-                    notificationDialog.setTitle(qtTrId("SAVING FAILED!"));
-                    notificationDialog.show();
+                    HbDeviceNotificationDialog::notification(QString(),qtTrId("SAVING FAILED!"));
                 }
                 
-                emit contactUpdated( success );
-                
                 QVariant var;
                 var.setValue(*mContact);
                 mArgs.insert(ESelectedContact, var);           
@@ -628,5 +624,25 @@
     mSave->setEnabled( true );
     mDiscard->setEnabled( true );
 }
+
+void CntEditViewPrivate::setSelectedContact( QContact aContact )
+{
+    if ( mContact )
+    {
+        delete mContact;
+        mContact = NULL;
+    }
+    mContact = new QContact( aContact );
+    
+    if ( mModel )
+    {
+        delete mModel;
+        mModel = NULL;
+    }
+    mModel = new CntEditViewListModel( mContact );
+    
+    if ( mListView )
+        mListView->setModel( mModel );
+}
 // End of File
 
--- a/phonebookui/pbkcommonui/src/cnteditviewheadingitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnteditviewheadingitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -26,6 +26,9 @@
 #include <hbtoucharea.h>
 #include <hbinstantfeedback.h>
 #include <hbmainwindow.h>
+#include <xqsettingsmanager.h>
+#include <xqsettingskey.h>
+#include <cntuids.h>
 
 #include <QGraphicsSceneMouseEvent>
 
@@ -75,6 +78,7 @@
             mLabel->setText(text);
             mLabel->setMaximumLines(2);
             mLabel->setTextWrapping(Hb::TextWordWrap);
+            mLabel->setElideMode(Qt::ElideRight);
             style()->setItemName(mLabel, "text");
         }
     }
@@ -149,7 +153,7 @@
     HbWidget::updatePrimitives();
 }
 
-void CntEditViewHeadingItem::setDetails(const QContact* contact)
+void CntEditViewHeadingItem::setDetails(const QContact* contact, bool myCard)
 {
     text.clear();
     second_text.clear();
@@ -160,29 +164,31 @@
 
     QContactName name = contact->detail<QContactName>();
 
-    QStringList nameList;
-    if (!name.prefix().isEmpty())
-    {
-        nameList << name.prefix();
-    }
-    if (!name.firstName().isEmpty())
-    {
-        nameList << name.firstName();
+    XQSettingsManager settingsMng;
+    XQSettingsKey nameOrderKey(XQSettingsKey::TargetCentralRepository,
+                             KCRUiContacts.iUid,
+                             KCntNameOrdering);
+    int setting = settingsMng.readItemValue(nameOrderKey, XQSettingsManager::TypeInt).toInt();
+    QStringList nameList = QStringList();
+    QString last;
+    
+    switch( setting ) {
+        case CntOrderLastFirst:
+            nameList << name.prefix() << name.lastName() << name.firstName() << name.middleName() << name.suffix();
+            break;
+        case CntOrderLastCommaFirst:
+            if (!name.lastName().isEmpty())
+                last = name.lastName() + ",";
+            nameList << name.prefix() << last << name.firstName() << name.middleName() << name.suffix();
+            break;
+        default:    // Default to first name last name
+            nameList << name.prefix() << name.firstName() << name.middleName() << name.lastName() << name.suffix();
+            break;
     }
-    if (!name.middleName().isEmpty())
-    {
-        nameList << name.middleName();
-    }
-    if (!name.lastName().isEmpty())
-    {
-        nameList << name.lastName();
-    }
-    if (!name.suffix().isEmpty())
-    {
-        nameList << name.suffix();
-    }
-    text = nameList.join(" ");
-
+    
+    nameList.removeAll("");
+    text = nameList.join(" ").trimmed();
+    
     if (!contact->detail<QContactNickname>().nickname().isEmpty())
     {
         second_text = contact->detail<QContactNickname>().nickname();
@@ -190,7 +196,14 @@
 
     if (text.isEmpty() && second_text.isEmpty())
     {
-        text = hbTrId("txt_phob_list_enter_name");
+        if (myCard)
+        {
+            text = hbTrId("txt_phob_list_enter_your_name");
+        }
+        else
+        {
+            text = hbTrId("txt_phob_list_enter_name");
+        }
     }
 
     recreatePrimitives();
--- a/phonebookui/pbkcommonui/src/cnteditviewitembuilder.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnteditviewitembuilder.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -19,6 +19,7 @@
 #include "cnteditviewdetailitem.h"
 #include "cntviewparams.h"
 #include "cntstringmapper.h"
+#include "cntdetailorderinghelper.h"
 #include <hbnumbergrouping.h>
 
 CntEditViewItemBuilder::CntEditViewItemBuilder() :
@@ -34,7 +35,7 @@
 QList<CntEditViewItem*> CntEditViewItemBuilder::phoneNumberItems(QContact& aContact)
 {
     QList<CntEditViewItem*> list;
-    QList<QContactPhoneNumber> numbers = aContact.details<QContactPhoneNumber>();
+    QList<QContactPhoneNumber> numbers = CntDetailOrderingHelper::getOrderedSupportedPhoneNumbers(aContact);
     // template for editor launcher
     if ( numbers.isEmpty() ) 
     {
@@ -52,16 +53,14 @@
     {
         foreach ( QContactPhoneNumber number, numbers )
         {
-            if ( !number.subTypes().isEmpty() )
-            {
             QString context = number.contexts().isEmpty() ? "" : number.contexts().first();
             QString subtype = number.subTypes().first();
-            
+
             CntEditViewDetailItem* detailItem = new CntEditViewDetailItem(
                     number,
                     QContactPhoneNumber::FieldNumber,
                     phoneNumberEditorView);
-            
+
             detailItem->addIcon( mMap->getContactEditorIconString(subtype, context) );
             detailItem->addText( mMap->getContactEditorLocString(subtype, context) );
             /*
@@ -71,11 +70,10 @@
             //detailItem->addText( HbNumberGrouping::formatPhoneNumber(number.number())); 
             detailItem->addText( number.number());
             list.append( detailItem );
-            }
         }
     }
     
-    QList<QContactOnlineAccount> urls = aContact.details<QContactOnlineAccount>();
+    QList<QContactOnlineAccount> urls = CntDetailOrderingHelper::getOrderedSupportedOnlineAccounts(aContact);
     // template for editor launcher
     if ( !urls.isEmpty() ) 
     {
@@ -113,6 +111,7 @@
                 else
                 {
                     /* Other subtypes of QContactOnlineAccount are not supported by UI */
+                    delete detailItem;
                 }
             }
         }
@@ -124,7 +123,7 @@
 QList<CntEditViewItem*> CntEditViewItemBuilder::emailAddressItems(QContact& aContact)
 {
     QList<CntEditViewItem*> list;
-    QList<QContactEmailAddress> emails = aContact.details<QContactEmailAddress>();
+    QList<QContactEmailAddress> emails = CntDetailOrderingHelper::getOrderedEmailAccounts(aContact);
     // template for editor launcher
     if ( emails.isEmpty() ) 
     {
@@ -190,7 +189,7 @@
 QList<CntEditViewItem*> CntEditViewItemBuilder::urlItems(QContact& aContact)
 {
     QList<CntEditViewItem*> list;
-    QList<QContactUrl> urls = aContact.details<QContactUrl>();
+    QList<QContactUrl> urls = CntDetailOrderingHelper::getOrderedUrls(aContact);
     // template for editor launcher
     if ( urls.isEmpty() ) 
     {
--- a/phonebookui/pbkcommonui/src/cnteditviewlistmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnteditviewlistmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -60,6 +60,13 @@
 
 CntEditViewListModel::~CntEditViewListModel()
 {
+    // Delete the separator item separately if it hasn't been added to the list
+    if (mSeparator && mItemList.indexOf(mSeparator) == -1)
+    {
+        delete mSeparator;
+        mSeparator = NULL;
+    }
+    
     qDeleteAll( mItemList );
     
     delete mBuilder;
@@ -106,9 +113,7 @@
     {
         beginRemoveRows( aIndex.parent(), index, index );
         // remove item from item list
-        int count = mItemList.count();
         CntEditViewItem* item = mItemList.takeAt( index );
-        count = mItemList.count();
         
         // get detailed information
         QContactDetail detail = item->data(ERoleContactDetail).value<QContactDetail>();
@@ -121,6 +126,9 @@
         // we can't remove address template, so the mapping for address always points to address detail
         KLookupKey lookupKey = mLookupMap.value( detail.definitionName() );
         removeItem( lookupKey );
+        
+        delete item;
+        
         endRemoveRows();
         
         // Remove separator item if needed
@@ -128,33 +136,46 @@
         {
             int separatorIndex = mItemList.indexOf( mSeparator );
             beginRemoveRows( aIndex.parent(), separatorIndex, separatorIndex );
-            mItemList.removeAt( mItemList.indexOf(mSeparator) );
+            mItemList.removeAt( separatorIndex );
             removeItem( ESeparator  );
+            
+            delete mSeparator;
+            mSeparator = NULL;
+            
             endRemoveRows();
         }
         
-        
         // Check if the removed item is -1 in lookuptable and if it needs a template
         int lookupValue = mLookupTable.value( lookupKey );
         if ( lookupValue == -1 )
         {
-            beginResetModel();
-            
             if ( detail.definitionName() == QContactPhoneNumber::DefinitionName )
+            {
+                beginInsertRows(aIndex.parent(), index, index);
                 insertItem( EPhonenumber, mBuilder->phoneNumberItems(*mContact) );
-            
+                endInsertRows();
+            }
             else if ( detail.definitionName() == QContactEmailAddress::DefinitionName )
+            {
+                beginInsertRows(aIndex.parent(), index, index);
                 insertItem( EEmailAddress, mBuilder->emailAddressItems(*mContact) );
-            
+                endInsertRows();
+            }
             else if ( detail.definitionName() == QContactAddress::DefinitionName )
+            {
+                // special case: unlike the others, address template isn't in the same index as the last deleted detail
+                int emailIndex = mLookupTable.value( EEmailAddress );
+                beginInsertRows(aIndex.parent(), emailIndex + 1, emailIndex + 1);
                 insertItem( EAddressTemplate, mBuilder->addressItems(*mContact) );
-            
+                endInsertRows();
+            }
             else if ( detail.definitionName() == QContactUrl::DefinitionName )
+            {
+                beginInsertRows(aIndex.parent(), index, index);
                 insertItem( EUrl, mBuilder->urlItems(*mContact) );
-            
-            endResetModel();
+                endInsertRows();
+            }
         }
-        delete item;
     }
 }
 
@@ -292,14 +313,17 @@
 
 bool CntEditViewListModel::isEmptyItem( CntEditViewItem* aItem )
 {
-    QContactDetail d = aItem->data( ERoleContactDetail ).value<QContactDetail>();
-    QStringList fields = aItem->data( ERoleContactDetailFields ).toStringList();
-    
-    foreach ( QString field, fields )
+    if ( aItem )
     {
-        if ( !d.value(field).isEmpty() )
+        QContactDetail d = aItem->data( ERoleContactDetail ).value<QContactDetail>();
+        QStringList fields = aItem->data( ERoleContactDetailFields ).toStringList();
+        
+        foreach ( QString field, fields )
         {
-            return false;
+            if ( !d.value(field).isEmpty() )
+            {
+                return false;
+            }
         }
     }
     return true;
--- a/phonebookui/pbkcommonui/src/cntemaileditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntemaileditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -16,19 +16,20 @@
 */
 #include "cntemaileditormodel.h"
 #include "cntdetailmodelitem.h"
+#include "cntdetailorderinghelper.h"
 #include <qcontactemailaddress.h>
 
 CntEmailEditorModel::CntEmailEditorModel( QContact* aContact ) :
 CntDetailEditorModel( aContact )
     {
-    QList<QContactEmailAddress> addr = mContact->details<QContactEmailAddress>();
-    if ( addr.isEmpty() )
+    mAddressList = CntDetailOrderingHelper::getOrderedEmailAccounts(*mContact);
+    if ( mAddressList.isEmpty() )
         {
         QContactEmailAddress newAddr;
-        addr.append( newAddr );
+        mAddressList.append( newAddr );
         }
     
-    foreach ( QContactEmailAddress email, addr )
+    foreach ( QContactEmailAddress email, mAddressList )
         {
         CntDetailModelItem* item = new CntDetailModelItem( email );
         appendDataFormItem( item, invisibleRootItem() );
@@ -41,6 +42,8 @@
 
 void CntEmailEditorModel::insertDetailField()
 {
+    // don't put this one in mAddressList since that list is used
+    // to check if there's new items
     QContactEmailAddress newAddr;
     CntDetailModelItem* item = new CntDetailModelItem( newAddr );
     appendDataFormItem( item, invisibleRootItem() );
@@ -52,9 +55,13 @@
     int count( root->childCount() );
     for ( int i(0); i < count; i++ ) {
         CntDetailModelItem* item = static_cast<CntDetailModelItem*>( root->childAt(i) );
-        QContactDetail address = item->detail();
-        mContact->saveDetail( &address );
-        
+        QContactEmailAddress address = item->detail();
+        if ( !mAddressList.contains(address) && !address.emailAddress().isEmpty() )
+        {
+            mContact->saveDetail( &address );
+            // this is not currently necessary since view is closed after this call.
+            mAddressList.append( address );
+        }
         if ( address.value(QContactEmailAddress::FieldEmailAddress).isEmpty() ) {
             mContact->removeDetail( &address );
         }
--- a/phonebookui/pbkcommonui/src/cntemaileditorviewitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntemaileditorviewitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,9 +17,9 @@
 #include "cntemaileditorviewitem.h"
 #include "cntdetailmodelitem.h"
 #include "cntdetailconst.h"
+#include "cntcommondetailviewitem.h"
 
 #include <qcontactdetail.h>
-#include <qgraphicslinearlayout.h>
 #include <qcontactemailaddress.h>
 #include <qgraphicslinearlayout.h>
 #include <hbwidget.h>
@@ -35,9 +35,7 @@
 
 CntEmailEditorViewItem::CntEmailEditorViewItem( QGraphicsItem* aParent ) :
 CntDetailViewItem( aParent ),
-mBox(NULL),
-mEdit(NULL),
-mLayout(NULL)
+mItem(NULL)
     {
     }
 
@@ -53,43 +51,31 @@
 
 HbWidget* CntEmailEditorViewItem::createCustomWidget()
     {
-    connect(itemView()->mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(changeOrientation(Qt::Orientation)));
-    mLayout = new QGraphicsLinearLayout( itemView()->mainWindow()->orientation() );
-    HbWidget* widget = new HbWidget();
-    mBox = new HbComboBox();
-    mEdit = new HbLineEdit();
-    mEdit->setMaxLength( CNT_EMAIL_EDITOR_MAXLENGTH );
-    mEdit->setInputMethodHints(Qt::ImhPreferLowercase);
+    mItem = new CntCommonDetailViewItem(this);
+    mItem->editor()->setMaxLength( CNT_EMAIL_EDITOR_MAXLENGTH );
+    mItem->editor()->setInputMethodHints(Qt::ImhPreferLowercase);
     
-    widget->setLayout( mLayout );
-    mLayout->addItem( mBox );
-    mLayout->addItem( mEdit );
-        
-    mLayout->setStretchFactor(mBox, 2);
-    mLayout->setStretchFactor(mEdit, 2);
-    
-    connect( mBox, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) );
-    connect( mEdit, SIGNAL(textChanged(QString)),this, SLOT(textChanged(QString)) );
-        
-        
     HbDataFormModel* model = static_cast<HbDataFormModel*>(itemView()->model());
     CntDetailModelItem* item = static_cast<CntDetailModelItem*>( model->itemFromIndex(modelIndex()) );
     QContactDetail detail = item->detail();
     
-    mEdit->setInputMethodHints( Qt::ImhEmailCharactersOnly );
+    mItem->editor()->setInputMethodHints( Qt::ImhEmailCharactersOnly );
     
     constructSubTypeModel( detail.contexts() );
     
     QContactEmailAddress address = detail;
     QString d = address.emailAddress();
-    mEdit->setText( address.emailAddress() );
+    mItem->editor()->setText( address.emailAddress() );
     
-    return widget;
+    connect( mItem->comboBox(), SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) );
+    connect( mItem->editor(), SIGNAL(textChanged(QString)),this, SLOT(textChanged(QString)) );
+        
+    return mItem;
     }
     
 void CntEmailEditorViewItem::indexChanged( int aIndex )
     {
-    QString context = mBox->itemData( aIndex, DetailContext ).toString();
+    QString context = mItem->comboBox()->itemData( aIndex, DetailContext ).toString();
         
     // check that if current QContactDetail contains the changed subtype
     HbDataFormModel* model = static_cast<HbDataFormModel*>(itemView()->model());
@@ -114,13 +100,6 @@
     item->setDetail( address );
     }
 
-void CntEmailEditorViewItem::changeOrientation(Qt::Orientation aOrient)
-    {
-        if (mLayout) {
-            mLayout->setOrientation(aOrient);
-        }
-    }
-
 void CntEmailEditorViewItem::constructSubTypeModel( QStringList aContext )
     {
     QStandardItemModel* model = new QStandardItemModel();
@@ -149,7 +128,7 @@
     work->setData(CNT_EMAIL_EDITOR_MAXLENGTH, DetailMaxLength);
     model->appendRow(work);
     
-    mBox->setModel( model );
+    mItem->comboBox()->setModel( model );
     
     QString context = aContext.isEmpty() ? "" : aContext.first();
     // search the selected index to be set
@@ -157,7 +136,7 @@
         {
         if ( model->item(i)->data( DetailContext ).toString() == context )
             {
-            mBox->setCurrentIndex( i );
+            mItem->comboBox()->setCurrentIndex( i );
             break;
             }
         }
--- a/phonebookui/pbkcommonui/src/cntextensionmanager.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntextensionmanager.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -46,9 +46,9 @@
     QPluginLoader* pluginLoader = mPlugins[index];
     QObject *plugin = pluginLoader->instance();
     if (plugin)
-        {
-            return qobject_cast<CntUiExtensionFactory*>(plugin);
-        }
+    {
+        return qobject_cast<CntUiExtensionFactory*>(plugin);
+    }
     return NULL;
 }
 
@@ -86,29 +86,29 @@
     
     QDir pluginsDir(CNT_UI_EXTENSION_PLUGIN_DIRECTORY);
     foreach (QString fileName, pluginsDir.entryList(QDir::Files))
-        {
+    {
         // Create plugin loader
         QPluginLoader* pluginLoader = new QPluginLoader( 
                 pluginsDir.absoluteFilePath(fileName));
         if ( pluginLoader->load() )
-            {
+        {
             QObject *plugin = pluginLoader->instance();
             if (plugin)
-                {
-                CntUiExtensionFactory* interface = qobject_cast<CntUiExtensionFactory*>(plugin);        
+            {
+                CntUiExtensionFactory* interface = qobject_cast<CntUiExtensionFactory*>(plugin); 
+                
                 if ( interface )
-                    {
+                {
                     mPlugins.append(pluginLoader);
-                    }
+                }
+                // If plugin loader did not load our plugin, unload the loader
+                else
+                {
+                    pluginLoader->unload();
                 }
             }
-        // If plugin loader was not for our plugins, delete loader handle
-        if ( !mPlugins.contains( pluginLoader ) )
-            {
-            pluginLoader->unload();
-            delete pluginLoader;
-            }
         }
+    }
     mPluginsLoaded = true;
 }
 
@@ -116,10 +116,9 @@
 {
     // Unload plugins and clear plugin array
     foreach (QPluginLoader* pluginLoader, mPlugins)
-        {
+    {
         pluginLoader->unload();
-        delete pluginLoader;
-        }   
+    }   
     mPlugins.clear();  
     mPluginsLoaded = false;  
 }
--- a/phonebookui/pbkcommonui/src/cntfamilyeditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntfamilyeditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -29,8 +29,7 @@
     }
 
     mFamily = familyList.first();
-    QStringList children = mFamily.children();
-
+    
     HbDataFormModelItem* spouseItem = new HbDataFormModelItem(HbDataFormModelItem::TextItem,
         hbTrId("txt_phob_formlabel_spouse"));
     spouseItem->setContentWidgetData("text", mFamily.spouse());
@@ -38,7 +37,7 @@
 
     HbDataFormModelItem* childrenItem = new HbDataFormModelItem(HbDataFormModelItem::TextItem,
         hbTrId("txt_phob_formlabel_children"));
-    childrenItem->setContentWidgetData("text", children.join(", "));
+    childrenItem->setContentWidgetData("text", mFamily.children().join(", "));
     childrenItem->setContentWidgetData("maxLength", CNT_CHILDREN_MAXLENGTH);
 
     HbDataFormModelItem* root = invisibleRootItem();
@@ -53,14 +52,23 @@
 void CntFamilyEditorModel::saveContactDetails()
 {
     HbDataFormModelItem* root = invisibleRootItem();
-    mFamily.setSpouse( root->childAt(0)->contentWidgetData("text").toString() );
-
+    QString spouse = root->childAt(0)->contentWidgetData("text").toString();
     QString children = root->childAt(1)->contentWidgetData("text").toString();
-    mFamily.setChildren( children.split(", ", QString::SkipEmptyParts) );
     
-    if ( !mFamily.isEmpty() ) {
+    if ( spouse != mFamily.spouse() || children != mFamily.children().join(", "))
+    {
+        mFamily.setSpouse( spouse );
+        QString children = root->childAt(1)->contentWidgetData("text").toString();
+        mFamily.setChildren( children.split(", ", QString::SkipEmptyParts) );
+        
         mContact->saveDetail( &mFamily );
     }
+    
+    if ( mFamily.spouse().isEmpty() && mFamily.children().isEmpty() )
+    {
+        mContact->removeDetail( &mFamily );
+    }
+    
 }
 
 QContactDetail CntFamilyEditorModel::detail() const
--- a/phonebookui/pbkcommonui/src/cntfavoritesmemberview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntfavoritesmemberview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -120,8 +120,6 @@
         createModel();
     }
 
-    mFavoriteListView->setModel(mModel);
-
     connect(mFavoriteListView, SIGNAL(activated (const QModelIndex&)), this,
             SLOT(openContact(const QModelIndex&)));
 }
@@ -200,21 +198,7 @@
     rFilter.setRelatedContactRole(QContactRelationship::First);
     rFilter.setRelatedContactId(mContact->id());
 
-    QContactSortOrder sortOrderFirstName;
-    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,
-        QContactName::FieldFirstName);
-    sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
-
-    QContactSortOrder sortOrderLastName;
-    sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,
-        QContactName::FieldLastName);
-    sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
-
-    QList<QContactSortOrder> sortOrders;
-    sortOrders.append(sortOrderFirstName);
-    sortOrders.append(sortOrderLastName);
-
-    mModel = new CntListModel(getContactManager(), rFilter, sortOrders, false);
+    mModel = new CntListModel(mViewManager->contactManager(SYMBIAN_BACKEND), rFilter, false);
     mFavoriteListView->setModel(mModel);
 }
 
--- a/phonebookui/pbkcommonui/src/cntfetchcontactsview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntfetchcontactsview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -21,6 +21,7 @@
 #include <hbaction.h>
 #include <hblabel.h>
 #include <hbaction.h>
+#include <hblineedit.h>
 #include <hbmainwindow.h>
 #include <hblistviewitem.h>
 #include <hblistview.h>
@@ -28,7 +29,6 @@
 #include <hbstaticvkbhost.h>
 #include <QGraphicsLinearLayout>
 #include <qcontactid.h>
-#include <QDebug>
 #include <cntlistmodel.h>
 #include "cntfetchcontactsview.h"
 
@@ -55,27 +55,13 @@
     mSearchPanel->setVisible(false);
     mSearchPanel->setCancelEnabled(false);
     connect(mSearchPanel, SIGNAL(criteriaChanged(QString)), this, SLOT(setFilter(QString)));
-
+    
+    HbLineEdit *editor = static_cast<HbLineEdit*>(mSearchPanel->primitive("lineedit"));
+    editor->setInputMethodHints(Qt::ImhNoPredictiveText);
+    
     mLayout = new QGraphicsLinearLayout(Qt::Vertical);
     
     mContainerWidget = new HbWidget();
-
-    // set up the list with all contacts
-    QList<QContactSortOrder> sortOrders;
-    QContactSortOrder sortOrderFirstName;
-    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirstName);
-    sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
-    sortOrders.append(sortOrderFirstName);
-
-    QContactSortOrder sortOrderLastName;
-    sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldLastName);
-    sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
-    sortOrders.append(sortOrderLastName);
-
-    QContactDetailFilter contactsFilter;
-    contactsFilter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
-    contactsFilter.setValue(QString(QLatin1String(QContactType::TypeContact)));
-    mCntModel = new CntListModel(mManager, contactsFilter, sortOrders, false);
 }
 
 CntFetchContacts::~CntFetchContacts()
@@ -130,8 +116,14 @@
         
         mLayout->addItem(mSearchPanel);
         mContainerWidget->setLayout(mLayout);
-        mContainerWidget->setPreferredHeight(mListView->mainWindow()->size().height());
+        
+        // Main window is NULL in unit tests
+        HbMainWindow* window = mListView->mainWindow();
+        if (window) {
+            mContainerWidget->setPreferredHeight(mListView->mainWindow()->size().height());
+        }
         mContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+                
         break;
     }
 
@@ -154,7 +146,7 @@
     detailfilter.setMatchFlags(QContactFilter::MatchStartsWith);
     detailfilter.setValue(searchList);
     
-    mCntModel->setFilterAndSortOrder(detailfilter);
+    mCntModel->setFilter(detailfilter);
 
     markMembersInView();
 
@@ -213,13 +205,17 @@
     if (popup && userCanceled) {
         mCurrentlySelected.clear();
         
-        // Notify that the user canceled.
         mWasCanceled = true;
     }
     else {
         mWasCanceled = false;
     }
     
+    mPopup->setVisible(false);
+    mListView->setModel(NULL);
+    delete mCntModel;
+    mCntModel = NULL;
+    
     emit clicked();
 }
 
@@ -261,6 +257,13 @@
     if (!mPopup) {
         mPopup = new HbDialog;
     }
+
+    QContactDetailFilter contactsFilter;
+    contactsFilter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
+    contactsFilter.setValue(QString(QLatin1String(QContactType::TypeContact)));
+    if (!mCntModel) {
+        mCntModel = new CntListModel(mManager, contactsFilter, false);
+    }
     
     if (!mListView) {
         mListView = new HbListView(mPopup);
@@ -295,6 +298,11 @@
 
         mCntModel->showMyCard(false);
     }
+    
+    // Handle the case where the model was removed for the list view
+    if (!mListView->model()) {
+        mListView->setModel(mCntModel);
+    }
 }
 
 void CntFetchContacts::connectSignal()
@@ -336,7 +344,7 @@
 
 void CntFetchContacts::markMembersInView()
 {
-    // if there are no contacts matching the current filter,
+    // If there are no contacts matching the current filter,
     // show "no matching contacts" label
     if (mCntModel->rowCount() == 0) {
         if (!mEmptyListLabel) {
--- a/phonebookui/pbkcommonui/src/cntgroupdeletepopup.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntgroupdeletepopup.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -20,10 +20,11 @@
 #include <hbgroupbox.h>
 #include <hbaction.h>
 #include <hblistview.h>
+#include <hblistviewitem.h>
 #include <qtcontacts.h>
 
 CntGroupDeletePopup::CntGroupDeletePopup(QContactManager *manager, QGraphicsItem *parent):
-    HbDialog(parent),
+    HbSelectionDialog(parent),
     mListView(0),
     mContactManager(manager),
     mModel(0)
@@ -56,6 +57,10 @@
     mListView->setFrictionEnabled(true);
     mListView->setScrollingStyle(HbScrollArea::PanWithFollowOn);
     
+    HbListViewItem *prototype = mListView->listItemPrototype();
+    prototype->setGraphicsSize(HbListViewItem::Thumbnail);
+    prototype->setStretchingStyle(HbListViewItem::StretchLandscape);
+    
     setContentWidget(mListView);
     
     setTimeout(HbDialog::NoTimeout);
@@ -63,6 +68,7 @@
     setModal(true);
     setAttribute(Qt::WA_DeleteOnClose, true);
     
+    clearActions(); 
     HbAction *mPrimaryAction = new HbAction(hbTrId("txt_phob_button_delete_selected"), this);
     addAction(mPrimaryAction);
     
--- a/phonebookui/pbkcommonui/src/cntgroupdeletepopupmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntgroupdeletepopupmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -19,6 +19,7 @@
 
 #include <qtcontacts.h>
 #include <hbglobal.h>
+#include <hbiconitem.h>
 
 /*!
 Constructor
@@ -88,6 +89,23 @@
                 // contact Id for identification
                 dataList.append(groupContactIds.at(i));
                 
+                // Default if no image for group 
+                bool icon = false;
+                QList<QContactAvatar> details = contact.details<QContactAvatar>();
+                for (int k = 0;k < details.count();k++)
+                {
+                   if (details.at(k).imageUrl().isValid())
+                   {
+                       dataList.append(QStringList(details.at(k).imageUrl().toString()));
+                       icon = true;
+                       break;
+                   }
+                }
+                if(!icon)
+                {
+                   dataList.append(QStringList("qtg_large_custom"));
+                }
+
                 mDataPointer->mDataList.append(dataList);
             }
         }
@@ -154,6 +172,17 @@
         return QVariant(list);
     }
     
+    else if (role == Qt::DecorationRole)
+    {
+        QVariantList icons;
+        for (int i = 0;i < values[2].toStringList().count();i++)
+        {
+            HbIcon icon(values[2].toStringList().at(i));
+            icons.append(icon);
+        }
+        return QVariant(icons);
+    }
+    
     else if (role == Qt::UserRole)
        {
            int contactId = values[1].toInt();
--- a/phonebookui/pbkcommonui/src/cntgroupeditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntgroupeditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -16,8 +16,10 @@
 */
 #include "cntgroupeditormodel.h"
 #include "cntdetailconst.h"
+#include "cntdetailorderinghelper.h"
 #include <qcontactname.h>
 #include <qcontactphonenumber.h>
+#include "cntglobal.h"
 
 CntGroupEditorModel::CntGroupEditorModel(QContact* aContact) :
     CntDetailEditorModel(aContact)
@@ -29,7 +31,7 @@
         nameDetails.append(emptyName);
     }
     
-    QList<QContactPhoneNumber> numberDetails = mContact->details<QContactPhoneNumber>();
+    QList<QContactPhoneNumber> numberDetails = CntDetailOrderingHelper::getOrderedSupportedPhoneNumbers(*mContact);
     if (numberDetails.isEmpty())
     {
         QContactPhoneNumber emptyNumber;
--- a/phonebookui/pbkcommonui/src/cntgroupmemberview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntgroupmemberview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -284,30 +284,10 @@
     QList<QContactRelationship> addedMemberships;
 
     QSet<QContactLocalId> removedMembers = mOriginalGroupMembers.toSet() - selectedContacts;
-    
-    // TODO Notice the duplication with these loops. Refactor to use one only
-    foreach (QContactLocalId id, removedMembers) {
-        QContact contact = getContactManager()->contact(id);
-
-        // new contact added to the group
-        QContactRelationship membership;
-        membership.setRelationshipType(QContactRelationship::HasMember);
-        membership.setFirst(mGroupContact->id());
-        membership.setSecond(contact.id());
-        removedMemberships.append(membership);
-    }
+    setRelationship(removedMembers, removedMemberships);
 
     QSet<QContactLocalId> addedMembers = selectedContacts - mOriginalGroupMembers.toSet();
-    foreach (QContactLocalId id, addedMembers) {
-        QContact contact = getContactManager()->contact(id);
-
-        // new contact added to the group
-        QContactRelationship membership;
-        membership.setRelationshipType(QContactRelationship::HasMember);
-        membership.setFirst(mGroupContact->id());
-        membership.setSecond(contact.id());
-        addedMemberships.append(membership);
-    }
+    setRelationship(addedMembers, addedMemberships);
     
     QMap<int, QContactManager::Error> errors;
     if (!addedMemberships.isEmpty()) {
@@ -331,22 +311,9 @@
     rFilter.setRelationshipType(QContactRelationship::HasMember);
     rFilter.setRelatedContactRole(QContactRelationship::First);
     rFilter.setRelatedContactId(mGroupContact->id());
-    
-    QContactSortOrder sortOrderFirstName;
-    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,
-        QContactName::FieldFirstName);
-    sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
+
 
-    QContactSortOrder sortOrderLastName;
-    sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,
-        QContactName::FieldLastName);
-    sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
-
-    QList<QContactSortOrder> sortOrders;
-    sortOrders.append(sortOrderFirstName);
-    sortOrders.append(sortOrderLastName);
-
-    mModel = new CntListModel(getContactManager(), rFilter, sortOrders, false);
+    mModel = new CntListModel(getContactManager(), rFilter, false);
     mListView->setModel(mModel);
 }
 
@@ -366,7 +333,7 @@
     headingLabel->setPlainText(HbParameterLengthLimiter(hbTrId("txt_phob_dialog_delete_1_group")).arg(groupName));
     
     HbMessageBox::question(hbTrId("txt_phob_dialog_only_group_will_be_removed_contac"), this, SLOT(handleDeleteGroup(HbAction*)),
-            hbTrId("txt_phob_button_delete"), hbTrId("txt_common_button_cancel"), headingLabel);
+            hbTrId("txt_common_button_delete"), hbTrId("txt_common_button_cancel"), headingLabel);
 }
 
 void CntGroupMemberView::handleDeleteGroup(HbAction *action)
@@ -509,6 +476,20 @@
     return mViewManager->contactManager(SYMBIAN_BACKEND);
 }
 
+void CntGroupMemberView::setRelationship(QSet<QContactLocalId>        &aLocalId,
+                                         QList<QContactRelationship>  &aRelationshipList)
+{
+    foreach (QContactLocalId id, aLocalId) {
+        QContact contact = getContactManager()->contact(id);
+
+        QContactRelationship membership;
+        membership.setRelationshipType(QContactRelationship::HasMember);
+        membership.setFirst(mGroupContact->id());
+        membership.setSecond(contact.id());
+        aRelationshipList.append(membership);
+    }
+}
+
 /*!
 Draw the image specific content menu
 */
--- a/phonebookui/pbkcommonui/src/cnthistoryview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnthistoryview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -164,7 +164,7 @@
     QString name = mContact->displayLabel();
     
     HbMessageBox::question(HbParameterLengthLimiter(hbTrId("txt_phob_info_clear_communications_history_with_1")).arg(name), this, 
-            SLOT(handleClearHistory(HbAction*)), hbTrId("txt_phob_button_delete"), hbTrId("txt_common_button_cancel"));
+            SLOT(handleClearHistory(HbAction*)), hbTrId("txt_common_button_delete"), hbTrId("txt_common_button_cancel"));
 }
 
 /*
--- a/phonebookui/pbkcommonui/src/cntimageeditorview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntimageeditorview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -20,6 +20,10 @@
 
 #include <hblabel.h>
 #include <xqaiwrequest.h>
+#include <xqaiwdecl.h>
+
+#include "cntdebug.h"
+
 #include <thumbnailmanager_qt.h>
 #include <hbaction.h>
 #include <hbview.h>
@@ -32,10 +36,6 @@
 
 const char *CNT_IMAGE_XML = ":/xml/contacts_if.docml";
 
-#define FETCHER_SERVICE "photos"
-#define FETCHER_INTERFACE "com.nokia.symbian.IImageFetch"
-#define FETCHER_OPERATION "fetch()"
-
 /*!
 Constructor
 */
@@ -83,6 +83,8 @@
 */
 CntImageEditorView::~CntImageEditorView()
 {
+    CNT_ENTRY
+    
     mView->deleteLater();
 
     delete mAvatar;
@@ -95,6 +97,8 @@
     mRemoveImage = 0;
     delete mModel;
     mModel = 0;
+    
+    CNT_EXIT
 }
 
 /*!
@@ -180,7 +184,39 @@
 */
 void CntImageEditorView::openCamera()
 {
+    CNT_ENTRY
+    
+    if (mRequest)
+    {
+        delete mRequest;
+        mRequest = 0;
+    }
+    
+    mRequest = mAppManager.create(XQI_CAMERA_CAPTURE, "capture(int,QVariantMap)", false);
+    if ( mRequest ) 
+    {
+        int mode = 0; //image mode
+        
+        QVariantMap map;
+        map.insert(XQCAMERA_INDEX, 0);
+        map.insert(XQCAMERA_QUALITY, 0);
+        map.insert(XQCAMERA_MODE_SWITCH, false);
+        map.insert(XQCAMERA_INDEX_SWITCH, false);
+        map.insert(XQCAMERA_QUALITY_CHANGE, true);
+        
+        // Set function parameters
+        QList<QVariant> args;
+        args << mode;
+        args << map;
+        mRequest->setArguments(args);
+        
+        connect(mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(handleImageChange(const QVariant&)));
+        connect(mRequest, SIGNAL(requestError(int,const QString&)), this, SLOT(handleError(int,const QString&)));
 
+        mRequest->send();
+    }
+    
+    CNT_EXIT
 }
 
 /*!
@@ -194,7 +230,7 @@
         mRequest = 0;
     }
     
-    mRequest = mAppManager.create(FETCHER_SERVICE, FETCHER_INTERFACE, FETCHER_OPERATION, true);
+    mRequest = mAppManager.create(XQI_IMAGE_FETCH, XQOP_IMAGE_FETCH, true);
     if ( mRequest ) 
     {
         connect(mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(handleImageChange(const QVariant&)));
@@ -247,23 +283,29 @@
 */
 void CntImageEditorView::handleImageChange(const QVariant &value)
 {
+    CNT_ENTRY_ARGS("image path = " << value.toString())
+    
     if(value.canConvert<QString>())
     {
         CntImageUtility imageUtility;
         if(imageUtility.isMassStorageAvailable())
         {
+            CNT_LOG_ARGS("mass storage available")
             /* Copy image and create thumbnail
              * When contact image removed only copy is deleted
              */
             QString imagepath;
             if(imageUtility.createImage(value.toString(),imagepath))
             {
+                
                 // If image already assigned, delete
                 QString filePath=mAvatar->imageUrl().toString();
                 if(!filePath.isEmpty()
                    && imageUtility.isImageRemovable(filePath))
                     imageUtility.removeImage(filePath);
             
+                CNT_LOG_ARGS("image created, image = " << filePath)
+                
                 mAvatar->setImageUrl(QUrl(imagepath));
                 mThumbnailManager->getThumbnail(imagepath);
                 mRemoveImage->setEnabled(true);
@@ -277,10 +319,14 @@
             mRemoveImage->setEnabled(true);
         }
     }
+    
+    CNT_EXIT
 }
 
 void CntImageEditorView::thumbnailReady(const QPixmap& pixmap, void *data, int id, int error)
 {
+    CNT_ENTRY_ARGS("error code = " << error)
+    
     Q_UNUSED(data);
     Q_UNUSED(id);
     if (!error)
@@ -290,6 +336,8 @@
         mImageLabel->clear();
         mImageLabel->setIcon(icon);
     }
+    
+    CNT_EXIT
 }
 
 void CntImageEditorView::setOrientation(Qt::Orientation orientation)
@@ -327,3 +375,9 @@
         }
     }
 }
+
+void CntImageEditorView::handleError(int errorCode, const QString& errorMessage)
+{
+    CNT_LOG_ARGS("error code = " << errorCode << "errorMessage=" << errorMessage)
+}
+
--- a/phonebookui/pbkcommonui/src/cntimagelabel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntimagelabel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -48,7 +48,7 @@
             case Qt::GestureUpdated:
                 if (tap->tapStyleHint() == HbTapGesture::TapAndHold) 
                 {
-                    emit iconLongPressed(tap->position());
+                    emit iconLongPressed(tap->scenePosition());
                 }
                 break;
             default:
--- a/phonebookui/pbkcommonui/src/cntimportsview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntimportsview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -33,6 +33,10 @@
 #include <QGraphicsLinearLayout>
 #include <hbframebackground.h>
 #include <hbabstractviewitem.h>
+#include <hbextendedlocale.h>
+#include <hbparameterlengthlimiter.h>
+#include <hblistviewitem.h>
+#include <hbstringutil.h>
 
 const char *CNT_IMPORT_UI_XML = ":/xml/contacts_sim.docml";
 const int KTimerValue = 1; // used as 1 msec timer for saving ADN contacts from SIM   
@@ -124,6 +128,7 @@
     //ADN store
     int error = -1;
     mAdnSimUtility = new CntSimUtility(CntSimUtility::AdnStore, error);
+    
     if (error != 0) 
     {
         delete mAdnSimUtility; 
@@ -209,7 +214,7 @@
     frame.setFrameGraphicsName("qtg_fr_list_normal");
     frame.setFrameType(HbFrameDrawer::NinePieces);
     mListView->itemPrototypes().first()->setDefaultFrame(frame);
-    
+    mListView->listItemPrototype()->setStretchingStyle(HbListViewItem::StretchLandscape);
     mListView->setUniformItemSizes(true);
     
     connect(mListView, SIGNAL(activated (const QModelIndex&)),
@@ -256,7 +261,17 @@
     {   
         // SIM card is present
         //ADN entries or SDN entries are there
-        simList << simImport ;        
+        simList << simImport;
+        int error = 0;
+        QDateTime date = mAdnSimUtility->getLastImportTime(error);
+        if (error == 0) {
+            HbExtendedLocale locale = HbExtendedLocale::system();
+            QString dateStr = locale.format(date.date(), r_qtn_date_usual);
+            QString dateStrLocaleDigits = HbStringUtil::convertDigits(dateStr); 
+            QString dateStrFull = 
+                HbParameterLengthLimiter(hbTrId("txt_phob_dblist_import_from_1_val_updated_1")).arg(dateStrLocaleDigits);
+            simList << dateStrFull;
+        }
     }
     importSimItem->setData(simList, Qt::DisplayRole);
     importSimItem->setData(HbIcon("qtg_large_sim"), Qt::DecorationRole);   
@@ -310,9 +325,14 @@
     bool started = false;
 
     delete mFetchRequestADN;
-    mFetchRequestADN = 0;
+    mContactSimManagerADN = mViewManager->contactManager(SIM_BACKEND_ADN);
+    mFetchRequestADN = new QContactFetchRequest;
+    mFetchRequestADN->setManager(mContactSimManagerADN);   
+    
     delete mFetchRequestSDN;
-    mFetchRequestSDN = 0;
+    mContactSimManagerSDN = mViewManager->contactManager(SIM_BACKEND_SDN);
+    mFetchRequestSDN = new QContactFetchRequest;
+    mFetchRequestSDN->setManager(mContactSimManagerSDN);        
         
     if (mWaitingForAdnCache)
     {
@@ -323,18 +343,11 @@
     {
         if(mAdnStorePresent)
         {
-            mContactSimManagerADN = mViewManager->contactManager(SIM_BACKEND_ADN);
-            mFetchRequestADN = new QContactFetchRequest;
-            mFetchRequestADN->setManager(mContactSimManagerADN);
             connect(mFetchRequestADN, SIGNAL(resultsAvailable()), this, SLOT(importFetchResultReceivedADN()));
         }
       
         if(mSdnStorePresent)
         {
-            mContactSimManagerSDN = mViewManager->contactManager(SIM_BACKEND_SDN);
-            // SDN store fetch request
-            mFetchRequestSDN = new QContactFetchRequest;
-            mFetchRequestSDN->setManager(mContactSimManagerSDN);
             connect(mFetchRequestSDN, SIGNAL(resultsAvailable()), this, SLOT(importFetchResultReceivedSDN()));
         }
         
@@ -376,10 +389,47 @@
         mFetchRequestSDN->cancel();
     }
     
+    // save import time
+    int error = 0;
+    mAdnSimUtility->setLastImportTime(error);
+    
+    //update sim import row with last import time
+    if (error == 0) {
+        QList<QStandardItem*> importSimItems = mModel->takeRow(0);
+        QStandardItem* importSimItem = 0;
+        if (importSimItems.count() > 0) {
+            importSimItem = importSimItems.at(0);
+        }
+        
+        if (importSimItem != 0) {
+            QDateTime date = mAdnSimUtility->getLastImportTime(error);
+            if (error == 0) {
+                QStringList simList;
+                QString simImport(hbTrId("txt_phob_dblist_import_from_sim"));
+                simList << simImport;
+                
+                HbExtendedLocale locale = HbExtendedLocale::system();
+                QString dateStr = locale.format(date.date(), r_qtn_date_usual);
+                QString dateStrLocaleDigits = HbStringUtil::convertDigits(dateStr);
+                QString dateStrFull = 
+                    HbParameterLengthLimiter(hbTrId("txt_phob_dblist_import_from_1_val_updated_1")).arg(dateStrLocaleDigits);
+                simList << dateStrFull;
+                
+                importSimItem->setData(simList, Qt::DisplayRole);
+                importSimItem->setData(HbIcon("qtg_large_sim"), Qt::DecorationRole);
+            }
+            mModel->insertRow(0, importSimItem);
+            mListView->reset();
+        }
+    }
 }
 
 void CntImportsView::importFetchResultReceivedADN()
 {
+    //save import time
+    int error = 0;
+    mAdnSimUtility->setLastImportTime(error);
+
     QList<QContact> simContactsList = mFetchRequestADN->contacts();
     if (simContactsList.isEmpty())
     {
@@ -446,7 +496,6 @@
             mFetchIsDone = true;
             mSaveCount = 0;    
         }
-    
     }
 }
 
@@ -541,6 +590,10 @@
 
 void CntImportsView::importFetchResultReceivedSDN()
 {
+    //save import time
+    int error = 0;
+    mAdnSimUtility->setLastImportTime(error);
+
     QList<QContact> simContactsListSDN = mFetchRequestSDN->contacts();
     if (simContactsListSDN.isEmpty())
     {
--- a/phonebookui/pbkcommonui/src/cntmainwindow.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntmainwindow.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -15,18 +15,18 @@
 *
 */
 
-
-
-
 #include "cntmainwindow.h"
 #include "cntdefaultviewmanager.h"
 #include "cntviewnavigator.h"
 #include <QCoreApplication>
+#include <cntdebug.h>
 
 CntMainWindow::CntMainWindow(QWidget *parent, int defaultView)
     : HbMainWindow(parent),
     mViewManager(NULL)
 {
+    CNT_ENTRY
+
     if (defaultView != noView)
     {
         CntViewNavigator* navigator = new CntViewNavigator(this);
@@ -45,12 +45,18 @@
         viewParameters.insert(EViewId, defaultView);
         mViewManager->changeView( viewParameters );
     }
+
+    CNT_EXIT
 }
 
 CntMainWindow::~CntMainWindow()
 {
+    CNT_ENTRY
+
     delete mViewManager;
-    mViewManager=0;
+    mViewManager = NULL;
+
+    CNT_EXIT
 }
 
 /*
@@ -61,7 +67,7 @@
 {
     if (event->key() == Qt::Key_Yes || event->key() == Qt::Key_No)
     {
-        emit keyPressed(event);
+       emit keyPressed(event);
     }
     else
     {
@@ -69,7 +75,4 @@
     }
 }
 
-
-//
-
 // end of file
--- a/phonebookui/pbkcommonui/src/cntmycardview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntmycardview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -18,6 +18,7 @@
 #include "cntmycardview.h"
 #include "cntfetchcontactsview.h"
 #include "cntglobal.h"
+#include <qtcontacts.h>
 #include <hbpushbutton.h>
 #include <hbaction.h>
 #include <hbview.h>
@@ -158,11 +159,10 @@
 
     if ( !mFetchView->wasCanceled() && !selectedContacts.isEmpty() ) {
         QList<QContactLocalId> selectedContactsList = selectedContacts.values();
-        manager->setSelfContactId(selectedContactsList.front());
-
-        QContact contact = mViewManager->contactManager(SYMBIAN_BACKEND)->contact(selectedContactsList.front());
+        QContact contact = manager->contact(selectedContactsList.front());
         removeFromGroup(&contact);
-
+        
+        manager->setSelfContactId( contact.localId() );
         showPreviousView();
     }
 }
--- a/phonebookui/pbkcommonui/src/cntnameeditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntnameeditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -75,30 +75,47 @@
 void CntNameEditorModel::saveContactDetails()
 {
     HbDataFormModelItem* root = invisibleRootItem();
-    iName.setFirstName( root->childAt( 0 )->contentWidgetData("text").toString().trimmed() );
-    iName.setLastName( root->childAt( 1 )->contentWidgetData("text").toString().trimmed() );
-    iName.setMiddleName( root->childAt( 2 )->contentWidgetData("text").toString().trimmed() );
-    iNick.setNickname( root->childAt( 3 )->contentWidgetData("text").toString().trimmed() );
-    iName.setPrefix( root->childAt( 4 )->contentWidgetData("text").toString().trimmed() );
-    iName.setSuffix( root->childAt( 5 )->contentWidgetData("text").toString().trimmed() );
+    QString firstname = root->childAt( 0 )->contentWidgetData("text").toString().trimmed();
+    QString lastname = root->childAt( 1 )->contentWidgetData("text").toString().trimmed();
+    QString midname = root->childAt( 2 )->contentWidgetData("text").toString().trimmed();
+    QString nick = root->childAt( 3 )->contentWidgetData("text").toString().trimmed();
+    QString prefix = root->childAt( 4 )->contentWidgetData("text").toString().trimmed();
+    QString suffix = root->childAt( 5 )->contentWidgetData("text").toString().trimmed();
+
+    if ( firstname != iName.firstName() || 
+         lastname != iName.lastName() ||
+         midname != iName.middleName() ||
+         prefix != iName.prefix() ||
+         suffix != iName.suffix() )
+    {
+        iName.setFirstName( firstname );
+        iName.setLastName( lastname );
+        iName.setMiddleName( midname );
+        iName.setPrefix( prefix );
+        iName.setSuffix( suffix );
+        mContact->saveDetail( &iName );    
+    }
     
-    mContact->saveDetail( &iName );
-    mContact->saveDetail( &iNick );
+    if ( nick != iNick.nickname() )
+    {
+        iNick.setNickname( nick );
+        mContact->saveDetail( &iNick );
+    }
     
     // remove empty details
-    if (iName.firstName().isEmpty() &&
-            iName.lastName().isEmpty() &&
-            iName.middleName().isEmpty() &&
-            iName.prefix().isEmpty() &&
-            iName.suffix().isEmpty())
-            {
-            mContact->removeDetail( &iName );
-            }
+    if (firstname.isEmpty() &&
+        lastname.isEmpty() &&
+        midname.isEmpty() &&
+        prefix.isEmpty() &&
+        suffix.isEmpty())
+    {
+    mContact->removeDetail( &iName );
+    }
     
-    if(iNick.nickname().isEmpty())
-        {
+    if( nick.isEmpty())
+    {
         mContact->removeDetail( &iNick );
-        }
+    }
 }
 
 QContactDetail CntNameEditorModel::detail() const
--- a/phonebookui/pbkcommonui/src/cntnamesview_p.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntnamesview_p.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -20,6 +20,7 @@
 #include "cntfetchcontactsview.h"
 #include "cntextensionmanager.h"
 #include "cntglobal.h"
+#include "cntdebug.h"
 
 #include <cntuiextensionfactory.h>
 #include <cntuisocialextension.h>
@@ -31,10 +32,11 @@
 #include <hbtoolbar.h>
 #include <hbmainwindow.h>
 #include <hbview.h>
-#include <hbtextitem.h>
+#include <hblabel.h>
 #include <hbdocumentloader.h>
 #include <hblistview.h>
 #include <hblistviewitem.h>
+#include <hblineedit.h>
 #include <hbindexfeedback.h>
 #include <hbscrollbar.h>
 #include <hbgroupbox.h>
@@ -45,7 +47,6 @@
 #include <hbmessagebox.h>
 #include <hbparameterlengthlimiter.h>
 
-#include <QGraphicsLinearLayout>
 #include <QList>
 
 const char *CNT_CONTACTLIST_XML = ":/xml/contacts_namelist.docml";
@@ -61,75 +62,94 @@
     mBanner(NULL),
     mSearchPanel(NULL),
     mLoader(NULL),
-    mLayout(NULL),
+    mVirtualKeyboard(NULL),
+    mNamesAction(NULL),
     mMenuBuilder(NULL),
     mHandledContactId(0),
     mFetchView(NULL),
     mIsDefault(true),
     mId( namesView ),
-    mActionGroup(NULL)
+    mActionGroup(NULL),
+    mFocusedContact(0)
 {
+    CNT_ENTRY
+    
     bool ok;
     document()->load( CNT_CONTACTLIST_XML, &ok);
     if (!ok) {
         qFatal("Unable to read %S", CNT_CONTACTLIST_XML);
     }
+    
+    document()->load( CNT_CONTACTLIST_XML, "no_find");
+    
     mView = static_cast<HbView*> (document()->findWidget("view"));
     
     mVirtualKeyboard = new HbStaticVkbHost(mView);
     connect(mVirtualKeyboard, SIGNAL(keypadOpened()), this, SLOT(handleKeypadOpen()));
     connect(mVirtualKeyboard, SIGNAL(keypadClosed()), this, SLOT(handleKeypadClose()));
-    
+
     mSoftkey = new HbAction(Hb::BackNaviAction, mView);
-       
+    connect(mSoftkey, SIGNAL(triggered()), this, SLOT(showPreviousView()));
+    
     mNewContact = static_cast<HbAction*> (document()->findObject("cnt:newcontact"));
+    mNewContact->setParent(mView);
+    connect(mNewContact, SIGNAL(triggered()), this, SLOT(createNewContact()));
+
     mMultipleDeleter = static_cast<HbAction*> (document()->findObject("cnt:delete"));
+    mMultipleDeleter->setParent(mView);
+    connect(mMultipleDeleter, SIGNAL(triggered()), this, SLOT(deleteMultipleContacts()));
+
     HbAction* findContacts = static_cast<HbAction*> (document()->findObject("cnt:find"));
+    findContacts->setParent(mView);
+    connect(findContacts, SIGNAL(triggered()), this, SLOT(showFinder()));
+
     HbAction* groups = static_cast<HbAction*> (document()->findObject("cnt:groups"));
-    HbAction* names = static_cast<HbAction*> (document()->findObject("cnt:names"));
+    groups->setParent(mView);
+    connect(groups, SIGNAL(triggered()), this, SLOT(showCollectionView()));
+
+    mNamesAction = static_cast<HbAction*> (document()->findObject("cnt:names"));
+    mNamesAction->setParent(mView);
+
     mImportSim = static_cast<HbAction*> (document()->findObject("cnt:importsim"));
+    mImportSim->setParent(mView);
+    connect(mImportSim, SIGNAL(triggered()), this, SLOT(importSim()));
     
     mActionGroup = new QActionGroup(this);
     groups->setActionGroup(mActionGroup);
-    names->setActionGroup(mActionGroup);
+    mNamesAction->setActionGroup(mActionGroup);
     
     HbAction* extension = static_cast<HbAction*> (document()->findObject("cnt:activity"));
+    extension->setParent(mView);
+    connect(extension, SIGNAL(triggered()), this, SLOT(handleExtensionAction()));
        
-    connect(mSoftkey, SIGNAL(triggered()), this, SLOT(showPreviousView()));
-    connect(mNewContact, SIGNAL(triggered()), this, SLOT(createNewContact()));
-    connect(mMultipleDeleter, SIGNAL(triggered()), this, SLOT(deleteMultipleContacts()));
-    connect(findContacts, SIGNAL(triggered()), this, SLOT(showFinder()));
-    connect(groups, SIGNAL(triggered()), this, SLOT(showCollectionView()));
-    connect(mImportSim, SIGNAL(triggered()), this, SLOT(importSim()));
-    connect(extension, SIGNAL(triggered()), this, SLOT(handleExtensionAction()));
+    HbAction* settings = static_cast<HbAction*>(document()->findObject("cnt:settings") );
+    settings->setParent(mView);
+    connect( settings, SIGNAL(triggered()), this, SLOT(showSettings()) );
+
+    HbMenu* viewMenu = static_cast<HbMenu*>(document()->findObject("viewMenu") );
+    viewMenu->setParent(mView);
+
     connect(list(), SIGNAL(longPressed(HbAbstractViewItem*,QPointF)), this,
            SLOT(showContextMenu(HbAbstractViewItem*,QPointF)));
     connect(list(), SIGNAL(activated (const QModelIndex&)), this,
            SLOT(showContactView(const QModelIndex&)));
+
+    mEmptyList = static_cast<HbLabel*> (document()->findWidget("emptyLabel"));
+    mBanner = static_cast<HbGroupBox*> (document()->findWidget("banner"));
+    mSearchPanel = static_cast<HbSearchPanel*> (document()->findWidget("searchPanel"));
+    connect(mSearchPanel, SIGNAL(exitClicked()), this, SLOT(hideFinder()));
+    connect(mSearchPanel, SIGNAL(criteriaChanged(QString)), this, SLOT(setFilter(QString)));
     
-    HbAction* settings = static_cast<HbAction*>(document()->findObject("cnt:settings") );
-    connect( settings, SIGNAL(triggered()), this, SLOT(showSettings()) );
+    CNT_EXIT
 }
 
 CntNamesViewPrivate::~CntNamesViewPrivate()
 {
-    mView->deleteLater();
-
+    CNT_ENTRY
+    
     delete mListModel;
     mListModel = NULL;
 
-    delete mListView;
-    mListView = NULL;
-
-    delete mSearchPanel;
-    mSearchPanel = NULL;
-
-    delete mEmptyList;
-    mEmptyList = NULL;
-
-    delete mBanner;
-    mBanner = NULL;
-
     delete mLoader;
     mLoader = NULL;
 
@@ -138,39 +158,32 @@
     
     delete mMenuBuilder;
     mMenuBuilder = NULL;
+    
+    delete mView;
+    mView = NULL;
+
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::activate(CntAbstractViewManager* aMgr, const CntViewParameters aArgs)
 {
+    CNT_ENTRY
+    
     Q_UNUSED( aArgs )
     mViewManager = aMgr;
+    
     if (!mListModel) {
-        QContactSortOrder sortOrderFirstName;
-        sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName,
-            QContactName::FieldFirstName);
-        sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
-
-        QContactSortOrder sortOrderLastName;
-        sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName,
-            QContactName::FieldLastName);
-        sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
-
-        QList<QContactSortOrder> sortOrders;
-        sortOrders.append(sortOrderFirstName);
-        sortOrders.append(sortOrderLastName);
-
         QContactDetailFilter filter;
         filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
         QString typeContact = QContactType::TypeContact;
         filter.setValue(typeContact);
-
-        mListModel = new CntListModel(mViewManager->contactManager(SYMBIAN_BACKEND), filter, sortOrders);
+        
+        mListModel = new CntListModel(mViewManager->contactManager(SYMBIAN_BACKEND), filter);
         list()->setModel(mListModel);
-        
+        setFocusedContact();
     }
     
-    HbAction* names = static_cast<HbAction*> (document()->findObject("cnt:names"));
-    names->setChecked(true);
+    mNamesAction->setChecked(true);
 
     mMenuBuilder = new CntActionMenuBuilder( mListModel->myCardId() );
     connect( mMenuBuilder, SIGNAL(deleteContact(QContact&)), this, SLOT(deleteContact(QContact&)) );
@@ -189,30 +202,58 @@
     // make connections unique, that is, duplicate connections are not connected again
     connect(contactManager, SIGNAL(contactsAdded(const QList<QContactLocalId>&)),
             this, SLOT(handleContactAddition(const QList<QContactLocalId>&)), Qt::UniqueConnection);
-    connect(contactManager, SIGNAL(contactsChanged(const QList<QContactLocalId>&)),
-                this, SLOT(handleContactChanged(const QList<QContactLocalId>&)), Qt::UniqueConnection);
     connect(contactManager, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)),
             this, SLOT(handleContactRemoval(const QList<QContactLocalId>&)), Qt::UniqueConnection);
     connect(contactManager, SIGNAL(selfContactIdChanged(const QContactLocalId&, const QContactLocalId&)), 
             this, SLOT(handleSelfContactIdChange(const QContactLocalId&, const QContactLocalId&)), Qt::UniqueConnection);
+    
+    setScrollPosition();
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::deactivate()
 {
+    CNT_ENTRY
+    
     hideFinder();
     
     delete mMenuBuilder;
     mMenuBuilder = NULL;
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::disableDeleteAction()
 {
+    CNT_ENTRY
+    
     bool multipleContacts = mListModel->rowCount() >= CNT_MIN_ROW_COUNT;
     mMultipleDeleter->setEnabled(multipleContacts);
+    
+    CNT_EXIT
+}
+
+void CntNamesViewPrivate::focusLineEdit()
+{
+    CNT_ENTRY
+    
+    HbLineEdit *editor = static_cast<HbLineEdit*>(mSearchPanel->primitive("lineedit"));
+    editor->setInputMethodHints(Qt::ImhNoPredictiveText);
+    
+    if (editor)
+    {
+        editor->setText("");
+        editor->setFocus();
+    }
+
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::setFilter(const QString &filterString)
 {
+    CNT_ENTRY
+    
     QStringList searchList = filterString.split(QRegExp("\\s+"), QString::SkipEmptyParts);
     QContactDetailFilter filter;
     filter.setDetailDefinitionName(QContactDisplayLabel::DefinitionName,
@@ -220,123 +261,116 @@
     filter.setMatchFlags(QContactFilter::MatchStartsWith);
     filter.setValue(searchList);
 
-    mListModel->setFilterAndSortOrder(filter);
+    mListModel->setFilter(filter);
 
-    if (mListModel->rowCount() == 0) {
-        layout()->removeItem(list());
-        layout()->insertItem(1, emptyLabel());
-        list()->setVisible(false);
-        emptyLabel()->setVisible(true);
+    if (mListModel->rowCount() == 0)
+    {
+        document()->load( CNT_CONTACTLIST_XML, "find_empty" );
     }
-    else {
-        layout()->removeItem(emptyLabel());
-        layout()->insertItem(1, list());
-        emptyLabel()->setVisible(false);
-        list()->setVisible(true);
+    else
+    {
+        document()->load( CNT_CONTACTLIST_XML, "find_list" );
     }
-    mListModel->showMyCard(false);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleKeypadOpen()
 {
-    qreal searchHeight = search()->size().height();
-    qreal bannerHeight = groupBox()->size().height();
-    qreal heightToSet = mView->size().height() - mVirtualKeyboard->keyboardArea().height()
-        - searchHeight - bannerHeight;
-
-    list()->setMaximumHeight(heightToSet);
-    emptyLabel()->setMaximumHeight(heightToSet);
+    CNT_ENTRY
+    
+    mView->setMaximumHeight(mVirtualKeyboard->applicationArea().height());
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleKeypadClose()
 {
-    list()->setMaximumHeight(mView->size().height());
-    emptyLabel()->setMaximumHeight(mView->size().height());
-}
-
-void CntNamesViewPrivate::showBanner(const QString aText)
-{
-    layout()->insertItem(0, groupBox());
-    groupBox()->setHeading(aText);
-    groupBox()->setVisible(true);
-}
-
-void CntNamesViewPrivate::hideBanner()
-{
-    layout()->removeItem(groupBox());
-    groupBox()->setVisible(false);
+    CNT_ENTRY
+    
+    mView->setMaximumHeight(-1);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showFinder()
 {
-    showBanner(hbTrId("txt_phob_subtitle_find_all_contacts"));
+    CNT_ENTRY
+    
+    focusLineEdit();
+    
+    mView->hideItems(Hb::AllItems);
+    
+    mListModel->showMyCard(false);
 
-    mView->toolBar()->hide();
     mImportSim->setVisible(false);
     mNewContact->setVisible(false);
     mMultipleDeleter->setVisible(false);
     
-    setFilter(QString());
-
-    list()->setVisible(true);
-    layout()->addItem(search());
-    search()->setVisible(true);
-
-    mListModel->showMyCard(false);
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::hideFinder()
 {
-    if ( mSearchPanel )
-    {
-        search()->setCriteria( QString() );
-        layout()->removeItem(emptyLabel());
-        layout()->removeItem(search());
-        emptyLabel()->setVisible(false);
-        search()->setVisible(false);
-        
-        hideBanner();
-
-        layout()->addItem(list());
-        list()->setVisible(true);
+    CNT_ENTRY
+    
+    mVirtualKeyboard->closeKeypad();
+    mView->setMaximumHeight(-1);
+    
+    document()->load( CNT_CONTACTLIST_XML, "no_find" );
+    mView->showItems(Hb::AllItems);
+    
+    mListModel->showMyCard(true);
 
-        QContactDetailFilter filter;
-        filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
-        QString typeContact = QContactType::TypeContact;
-        filter.setValue(typeContact);
+    QContactDetailFilter filter;
+    filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
+    QString typeContact = QContactType::TypeContact;
+    filter.setValue(typeContact);
 
-        mListModel->setFilterAndSortOrder(filter);
-        mListModel->showMyCard(true);
+    mListModel->setFilter(filter);
 
-        mNewContact->setVisible(true);
-        mImportSim->setVisible(true);
-        mMultipleDeleter->setVisible(true);
-        mView->toolBar()->show();
-    }   
+    mNewContact->setVisible(true);
+    mImportSim->setVisible(true);
+    mMultipleDeleter->setVisible(true);
+
+    CNT_EXIT    
 }
 
 bool CntNamesViewPrivate::isFinderVisible()
 {
+    CNT_ENTRY
+    
     bool isVisible = false;
     if ( mSearchPanel )
     {
         isVisible = mSearchPanel->isVisible();
     }
+    
+    CNT_EXIT
     return isVisible;
 }
 
 void CntNamesViewPrivate::showPreviousView()
 {
+    CNT_ENTRY
+    
     if ( !isFinderVisible() )
     {
-        qApp->quit();
+        mViewManager->back( CntViewParameters() );
     }
-    hideFinder();
+    else
+    {
+        hideFinder();
+    }
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleExtensionAction()
 {
-    for(int i = 0;i < mExtensionManager.pluginCount();i++)
+    CNT_ENTRY
+    
+    for (int i = 0; i < mExtensionManager.pluginCount(); i++)
     {
         CntUiSocialExtension* socialExtension = mExtensionManager.pluginAt(i)->socialExtension();
         if (socialExtension)
@@ -345,50 +379,66 @@
             socialExtension->handleToolbarAction(params);
             if (params.count())
             {
+                setFocusedContact();
                 mViewManager->changeView(params);
                 break;
             }
         }
     }
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::createNewContact()
 {
+    CNT_ENTRY
+    
     QContact newContact;
     newContact.setType( QContactType::TypeContact );
     
     showContactEditorView(newContact);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::deleteContact(QContact& aContact)
 {
+    CNT_ENTRY
+    
     QContactManager* manager = mViewManager->contactManager( SYMBIAN_BACKEND );
     QString name = manager->synthesizedDisplayLabel(aContact);
     
     mHandledContactId = aContact.localId();
     
     HbMessageBox::question(HbParameterLengthLimiter(hbTrId("txt_phob_info_delete_1")).arg(name), this, SLOT(handleDeleteContact(HbAction*)),
-            hbTrId("txt_phob_button_delete"), hbTrId("txt_common_button_cancel"));
+            hbTrId("txt_common_button_delete"), hbTrId("txt_common_button_cancel"));
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::deleteMultipleContacts()
 {
+    CNT_ENTRY
+    
     if (!mFetchView) {
         mFetchView = new CntFetchContacts(mViewManager->contactManager( SYMBIAN_BACKEND ));
         connect(mFetchView, SIGNAL(clicked()), this, SLOT(handleDeleteMultipleContacts()));
     }
 
-    mFetchView->setDetails(hbTrId("txt_phob_title_delete_contacts"),hbTrId("txt_phob_button_delete"));
+    mFetchView->setDetails(hbTrId("txt_phob_title_delete_contacts"),hbTrId("txt_common_button_delete"));
     QSet<QContactLocalId> emptyContactsSet;
 
     // Pop up a list of contacts for deletion
     mFetchView->displayContacts(CntFetchContacts::popup,
                                 HbAbstractItemView::MultiSelection,
                                 emptyContactsSet);
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleDeleteMultipleContacts()
 {
+    CNT_ENTRY
+    
     QSet<QContactLocalId> selectedContacts = mFetchView->getSelectedContacts();
 
     QContactManager* manager = mViewManager->contactManager( SYMBIAN_BACKEND );
@@ -401,16 +451,25 @@
 
     delete mFetchView;
     mFetchView = NULL;
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showContactView( const QModelIndex& aIndex )
 {
+    CNT_ENTRY
+
     QContact c = mListModel->contact(aIndex);
     showContactView( c );
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showContactView( QContact& aContact )
 {
+    CNT_ENTRY
+    
+    setFocusedContact();
     CntViewParameters args;
     args.insert(EViewId, commLauncherView);
     if (aContact.localId() == mListModel->myCardId() && aContact.details().count() <= 4)
@@ -422,10 +481,14 @@
     contact.setValue(aContact);
     args.insert(ESelectedContact, contact);
     mViewManager->changeView(args);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showContextMenu(HbAbstractViewItem* aItem, QPointF aPoint)
 {
+    CNT_ENTRY
+    
     QContact contact = mListModel->contact(aItem->modelIndex());
     
    // In case of an empty MyCard, do not show any ContextMenu
@@ -437,23 +500,33 @@
         menu->open();
     }
     
-    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::executeAction( QContact& aContact, QString aAction )
 {
+    CNT_ENTRY
+    
     CntActionLauncher* other = new CntActionLauncher( aAction );
     connect(other, SIGNAL(actionExecuted(CntAction*)), this, SLOT(actionExecuted(CntAction*)));
     other->execute(aContact, QContactDetail());
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::actionExecuted(CntActionLauncher* aAction)
 {
+    CNT_ENTRY
+
     aAction->deleteLater();
+
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleDeleteContact( HbAction* aAction )
 {
+    CNT_ENTRY
+    
     HbMessageBox *note = static_cast<HbMessageBox*>(sender());
     
     if (note && aAction == note->actions().first())
@@ -462,10 +535,15 @@
     }
     
     mHandledContactId = 0;
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showContactEditorView(QContact& aContact)
 {
+    CNT_ENTRY
+    
+    setFocusedContact();
     CntViewParameters args;
     args.insert(EViewId, editView);
     
@@ -474,67 +552,99 @@
     args.insert(ESelectedContact, contact);
 
     mViewManager->changeView(args);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showCollectionView()
 {
+    CNT_ENTRY
+    
+    setFocusedContact();
     CntViewParameters args;
     args.insert(EViewId, collectionView);
     mViewManager->changeView(args);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::importSim()
 {
-   CntViewParameters args;        
-   args.insert(EViewId, importsView);
-   mViewManager->changeView(args);
+    CNT_ENTRY
+    
+    setFocusedContact();
+    CntViewParameters args;        
+    args.insert(EViewId, importsView);
+    mViewManager->changeView(args);
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::showSettings()
 {
+    CNT_ENTRY
+    
+    setFocusedContact();
     CntViewParameters args;
     args.insert( EViewId, settingsView );
     mViewManager->changeView( args );
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleContactAddition(const QList<QContactLocalId>& aAddedList)
 {
-    QContact contact = mViewManager->contactManager(SYMBIAN_BACKEND)->contact(aAddedList.last());
-    list()->scrollTo(mListModel->indexOfContact(contact));
-    disableDeleteAction();
-}
+    CNT_ENTRY
 
-void CntNamesViewPrivate::handleContactChanged(const QList<QContactLocalId>& aChangedList)
-{
-    QContact contact = mViewManager->contactManager(SYMBIAN_BACKEND)->contact(aChangedList.last());
-    list()->scrollTo(mListModel->indexOfContact(contact));
+    Q_UNUSED(aAddedList);
     disableDeleteAction();
+    
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleContactRemoval(const QList<QContactLocalId>& aRemovedList)
 {
+    CNT_ENTRY
+  
     Q_UNUSED(aRemovedList);
-    QModelIndex index = list()->selectionModel()->currentIndex();
-    if (index.isValid())
-        list()->scrollTo(index);
+    disableDeleteAction();
     
-    disableDeleteAction();
+    CNT_EXIT
 }
 
 void CntNamesViewPrivate::handleSelfContactIdChange(const QContactLocalId& aOldId, const QContactLocalId& aNewId)
 {
+    CNT_ENTRY
+    
     Q_UNUSED(aOldId);
     Q_UNUSED(aNewId);
     disableDeleteAction();
+    
+    CNT_EXIT
+}
+
+void CntNamesViewPrivate::setScrollPosition()
+{
+    CNT_ENTRY
+    
+    // Scroll to the focused contact
+    if ( mFocusedContact > 0 )
+    {
+        QContactManager* contactManager = mViewManager->contactManager( SYMBIAN_BACKEND );
+        QContact c = contactManager->contact(mFocusedContact);
+        list()->scrollTo(mListModel->indexOfContact(c), HbAbstractItemView::PositionAtCenter);
+    }
+    
+    CNT_EXIT
 }
 
 //// lazy accessors
 HbListView* CntNamesViewPrivate::list()
 {
+    CNT_ENTRY
+
     if (!mListView) {
         mListView = static_cast<HbListView*> (mLoader->findWidget("listView"));
-        HbListViewItem *prototype = mListView->listItemPrototype();
-        prototype->setGraphicsSize(HbListViewItem::Thumbnail);
 
         mListView->setFrictionEnabled(true);
         mListView->setScrollingStyle(HbScrollArea::PanWithFollowOn);
@@ -548,58 +658,34 @@
         mListView->itemPrototypes().first()->setDefaultFrame(frame);
         
         mListView->setUniformItemSizes(true);
+        mListView->setItemRecycling(true);
 
         HbIndexFeedback *indexFeedback = new HbIndexFeedback(mView);
         indexFeedback->setIndexFeedbackPolicy(HbIndexFeedback::IndexFeedbackSingleCharacter);
         indexFeedback->setItemView(mListView);
-        
-        connect( mListView, SIGNAL(scrollPositionChanged(const QPointF&)), this, SLOT(handleScroll(const QPointF&)) );
     }
+    
+    CNT_EXIT
     return mListView;
 }
 
-HbTextItem* CntNamesViewPrivate::emptyLabel()
-{
-    if (!mEmptyList) {
-        mEmptyList = new HbTextItem(hbTrId("txt_phob_info_no_matching_contacts"));
-        mEmptyList->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
-        mEmptyList->setFontSpec(HbFontSpec(HbFontSpec::Primary));
-        mEmptyList->setAlignment(Qt::AlignCenter);
-    }
-    return mEmptyList;
-}
-HbGroupBox* CntNamesViewPrivate::groupBox()
-{
-    if (!mBanner)
-        mBanner = new HbGroupBox();
-    return mBanner;
-}
-
-HbSearchPanel* CntNamesViewPrivate::search()
-{
-    if (!mSearchPanel) {
-        mSearchPanel = new HbSearchPanel();
-        mSearchPanel->setVisible( false );
-        connect(mSearchPanel, SIGNAL(exitClicked()), this, SLOT(hideFinder()));
-        connect(mSearchPanel, SIGNAL(criteriaChanged(QString)), this, SLOT(setFilter(QString)));
-    }
-    return mSearchPanel;
-}
-QGraphicsLinearLayout* CntNamesViewPrivate::layout()
-{
-    if (!mLayout) {
-        QGraphicsWidget *w = mLoader->findWidget(QString("content"));
-        mLayout = static_cast<QGraphicsLinearLayout*> (w->layout());
-    }
-    return mLayout;
-}
-
 HbDocumentLoader* CntNamesViewPrivate::document()
 {
+    CNT_ENTRY
+    
     if (!mLoader) {
         mLoader = new HbDocumentLoader();
     }
+    
+    CNT_EXIT
     return mLoader;
 }
 
+void CntNamesViewPrivate::setFocusedContact()
+{
+    if ( mListModel )
+    {
+        mFocusedContact = mListModel->contact(list()->currentIndex()).localId();
+    }
+}
 // End of File
--- a/phonebookui/pbkcommonui/src/cntnoteeditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntnoteeditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -36,6 +36,7 @@
 void CntNoteEditorModel::insertDetailField()
 {
     QContactNote emptyNote;
+    mNoteList.append( emptyNote );
     appendDataFormItem( new CntDetailModelItem(emptyNote), invisibleRootItem() );
 }
 
@@ -46,10 +47,14 @@
     int count( root->childCount() );
     for ( int i(0); i < count; i++ ) {
         CntDetailModelItem* detail = static_cast<CntDetailModelItem*>( root->childAt(i) );
-        QContactDetail note = detail->detail();
-        mContact->saveDetail( &note );
+        QContactNote note = detail->detail();
         
-        if ( note.value(QContactNote::FieldNote).isEmpty() )
+        if ( !mNoteList.contains(note) )
+        {
+            mContact->saveDetail( &note );
+        }
+        
+        if ( note.note().isEmpty() )
         {
             mContact->removeDetail( &note );
         }
--- a/phonebookui/pbkcommonui/src/cntnoteeditorviewitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntnoteeditorviewitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -59,7 +59,8 @@
     HbWidget* widget = new HbWidget();
     
     mEdit = new HbLineEdit();
-    connect( mEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)) );
+    mEdit->setInputMethodHints(Qt::ImhNoPredictiveText);
+    
     mEdit->setMaxLength( CNT_NOTE_EDITOR_MAXLENGTH );
     mEdit->setMinRows( CNT_NOTE_EDITOR_MIN_ROWCOUNT );
     mEdit->setText( detail.note() );
@@ -69,6 +70,7 @@
     mLayout->addItem(mEdit);
     widget->setLayout( mLayout );
     
+    connect( mEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)) );
     return widget;
     }
 // End of File
--- a/phonebookui/pbkcommonui/src/cntphonenumbermodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntphonenumbermodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,6 +17,7 @@
 #include "cntphonenumbermodel.h"
 #include "cntdetailconst.h"
 #include "cntdetailmodelitem.h"
+#include "cntdetailorderinghelper.h"
 #include <hbdataformmodelitem.h>
 #include <QDebug>
 
@@ -26,22 +27,26 @@
     setParent( aParent );
     
     QList<QContactDetail> all;
-    foreach ( QContactDetail detail, mContact->details<QContactPhoneNumber>() )
+    foreach ( QContactDetail detail, CntDetailOrderingHelper::getOrderedSupportedPhoneNumbers(*mContact) )
+    {
         all.append( detail );
+        mNumberList.append( detail );
+    }
     
-    foreach ( QContactDetail detail, mContact->details<QContactOnlineAccount>() )
+    foreach ( QContactDetail detail, CntDetailOrderingHelper::getOrderedSupportedOnlineAccounts(*mContact) )
+    {
         all.append( detail );
+        mNumberList.append( detail );
+    }
     
     // if there's no details, add 
     if ( all.isEmpty() )
         {
-        QContactPhoneNumber mobileNumber;
-        mobileNumber.setSubTypes( QContactPhoneNumber::SubTypeMobile );
-        all.append( mobileNumber );
+        mMobileTemplate.setSubTypes( QContactPhoneNumber::SubTypeMobile );
+        all.append( mMobileTemplate );
 
-        QContactPhoneNumber landLineNumber;
-        landLineNumber.setSubTypes( QContactPhoneNumber::SubTypeLandline );
-        all.append( landLineNumber );
+        mLandlineTemplate.setSubTypes( QContactPhoneNumber::SubTypeLandline );
+        all.append( mLandlineTemplate );
         }
             
     HbDataFormModelItem* root = invisibleRootItem();
@@ -68,17 +73,32 @@
     for ( int i = 0; i < count; i++ ) {
         CntDetailModelItem* item = static_cast<CntDetailModelItem*>( root->childAt(i) );
         QContactDetail detail = item->detail();
-        mContact->saveDetail( &detail );
         
         if ( detail.definitionName() == QContactPhoneNumber::DefinitionName )
         {
+            QContactPhoneNumber number = detail;
+            if ( !mNumberList.contains(detail) )
+            {
+                mContact->saveDetail( &detail );
+            }
+            
             if ( detail.value(QContactPhoneNumber::FieldNumber).isEmpty() )
+            {
+                // this won't change the pointer value if the detail does not exists in contact.
+                // But, this is the situation in wk20...
                 mContact->removeDetail( &detail );
+            }
         }
         
         if ( detail.definitionName() == QContactOnlineAccount::DefinitionName )
         {
-            if ( detail.value(QContactOnlineAccount::FieldAccountUri).isEmpty() )
+            QContactOnlineAccount account = detail;
+            if ( !mNumberList.contains(detail) && !account.accountUri().isEmpty() )
+            {
+                mContact->saveDetail( &detail );
+            }
+            
+            if ( account.accountUri().isEmpty() )
             {
                 mContact->removeDetail( &detail );
             }
--- a/phonebookui/pbkcommonui/src/cntphonenumberviewitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntphonenumberviewitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,30 +17,27 @@
 #include "cntdetailconst.h"
 #include "cntphonenumberviewitem.h"
 #include "cntdetailmodelitem.h"
+#include "cntcommondetailviewitem.h"
 #include "cntdetaileditormodel.h"
 
 #include <qdebug.h>
-#include <qgraphicslinearlayout.h>
 #include <qcontactphonenumber.h>
 #include <qcontactonlineaccount.h>
 #include <qcontactdetail.h>
 #include <qstandarditemmodel.h>
 
-#include <hbwidget.h>
 #include <hbmainwindow.h>
+#include <hbcombobox.h>
+#include <hblineedit.h>
 #include <hbabstractviewitem.h>
 #include <hbabstractitemview.h>
 #include <hbdataformmodelitem.h>
 #include <hbdataformmodel.h>
-#include <hbcombobox.h>
-#include <hblineedit.h>
 #include <hbinputstandardfilters.h>
 
 CntPhoneNumberViewItem::CntPhoneNumberViewItem( QGraphicsItem* aParent ) : 
 CntDetailViewItem( aParent ),
-mBox(NULL),
-mEdit(NULL),
-mLayout(NULL)
+    mItem(NULL)
     {
     }
 
@@ -55,8 +52,8 @@
 
 void CntPhoneNumberViewItem::indexChanged( int aIndex )
     {
-    QString subType = mBox->itemData( aIndex, DetailSubType ).toString();
-    QString context = mBox->itemData( aIndex, DetailContext ).toString();
+    QString subType = mItem->comboBox()->itemData( aIndex, DetailSubType ).toString();
+    QString context = mItem->comboBox()->itemData( aIndex, DetailContext ).toString();
     
     // check that if current QContactDetail contains the changed subtype
     HbDataFormModel* model = static_cast<HbDataFormModel*>(itemView()->model());
@@ -102,31 +99,9 @@
         }
     }
 
-void CntPhoneNumberViewItem::changeOrientation(Qt::Orientation aOrient)
-{
-    if (mLayout) {
-        mLayout->setOrientation(aOrient);
-    }
-}
-
 HbWidget* CntPhoneNumberViewItem::createCustomWidget()
     {
-    connect(itemView()->mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(changeOrientation(Qt::Orientation)));
-    mLayout = new QGraphicsLinearLayout( itemView()->mainWindow()->orientation() );
-    HbWidget* widget = new HbWidget();
-    mBox = new HbComboBox();
-    mEdit = new HbLineEdit();
-    
-    widget->setLayout( mLayout );
-
-    mLayout->addItem( mBox );
-    mLayout->addItem( mEdit );
-    
-    mLayout->setStretchFactor(mBox, 2);
-    mLayout->setStretchFactor(mEdit, 2);
-    
-    connect( mBox, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) );
-    connect( mEdit, SIGNAL(textChanged(QString)),this, SLOT(textChanged(QString)) );
+    mItem = new CntCommonDetailViewItem(this);
     
     HbDataFormModel* model = static_cast<HbDataFormModel*>(itemView()->model());
     CntDetailModelItem* item = static_cast<CntDetailModelItem*>( model->itemFromIndex(modelIndex()) );
@@ -138,7 +113,7 @@
     QString value;
     if ( detail.definitionName() == QContactPhoneNumber::DefinitionName )
         {
-        mEdit->setMaxLength( CNT_PHONENUMBER_EDITOR_MAXLENGTH );
+        mItem->editor()->setMaxLength( CNT_PHONENUMBER_EDITOR_MAXLENGTH );
         QContactPhoneNumber phone = detail;
         subType = phone.subTypes().isEmpty() ? "" : phone.subTypes().first();
         if ( !phone.contexts().isEmpty() )
@@ -148,7 +123,7 @@
     
     if ( detail.definitionName() == QContactOnlineAccount::DefinitionName )
         {
-        mEdit->setMaxLength( CNT_ONLINEACCOUNT_EDITOR_MAXLENGTH );
+        mItem->editor()->setMaxLength( CNT_ONLINEACCOUNT_EDITOR_MAXLENGTH );
         QContactOnlineAccount account = detail;
         subType = account.subTypes().isEmpty() ? "" : account.subTypes().first();
         if (!account.contexts().isEmpty())
@@ -156,16 +131,20 @@
         value = account.accountUri();
         }
     
-    mEdit->setText( value );
+    mItem->editor()->setText( value );
+    
+    connect( mItem->comboBox(), SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) );
+    connect( mItem->editor(), SIGNAL(textChanged(QString)),this, SLOT(textChanged(QString)) );
+    
     constructSubtypeModel( subType, context );
     
-    return widget;        
+    return mItem;
     }
 
 void CntPhoneNumberViewItem::constructPhoneNumber( CntDetailModelItem* aItem, QString aSubType, QStringList aContext )
     {
-    mEdit->setInputMethodHints( Qt::ImhDialableCharactersOnly );
-    mEdit->setMaxLength( CNT_PHONENUMBER_EDITOR_MAXLENGTH );
+    mItem->editor()->setInputMethodHints( Qt::ImhDialableCharactersOnly );
+    mItem->editor()->setMaxLength( CNT_PHONENUMBER_EDITOR_MAXLENGTH );
             
     QContactDetail detail = aItem->detail();
     
@@ -190,13 +169,13 @@
         number.setContexts( aContext );
         aItem->setDetail( number );
         }
-    qDebug() << mEdit->text();
+    qDebug() << mItem->editor()->text();
     }
 
 void CntPhoneNumberViewItem::constructOnlineAccount( CntDetailModelItem* aItem, QString aSubType, QStringList aContext )
     {
-    mEdit->setMaxLength( CNT_ONLINEACCOUNT_EDITOR_MAXLENGTH );
-    mEdit->setInputMethodHints( Qt::ImhUrlCharactersOnly );
+    mItem->editor()->setMaxLength( CNT_ONLINEACCOUNT_EDITOR_MAXLENGTH );
+    mItem->editor()->setInputMethodHints( Qt::ImhUrlCharactersOnly );
     
     QContactDetail detail = aItem->detail();
     // check if the detail type needs to changed
@@ -211,7 +190,7 @@
         QContactOnlineAccount account;
         account.setSubTypes( aSubType );
         account.setContexts( aContext );
-        account.setAccountUri( mEdit->text() );
+        account.setAccountUri( mItem->editor()->text() );
         aItem->setDetail( account );
         }
     else
@@ -219,10 +198,10 @@
         QContactOnlineAccount account = detail;
         account.setSubTypes( aSubType );
         account.setContexts( aContext );
-        account.setAccountUri( mEdit->text() );
+        account.setAccountUri( mItem->editor()->text() );
         aItem->setDetail( account );
         }
-    qDebug() << mEdit->text();
+    qDebug() << mItem->editor()->text();
     }
 
 void CntPhoneNumberViewItem::constructSubtypeModel( QString aSubType, QStringList aContext )
@@ -234,7 +213,7 @@
         
     QString subTypeMobile = QContactPhoneNumber::SubTypeMobile;
     QString subTypeLandline = QContactPhoneNumber::SubTypeLandline;
-    QString subTypeFax = QContactPhoneNumber::SubTypeFacsimile;
+    QString subTypeFax = QContactPhoneNumber::SubTypeFax;
     QString subTypePager = QContactPhoneNumber::SubTypePager;
     QString subTypeCarPhone = QContactPhoneNumber::SubTypeCar;
     QString subTypeDtmf = QContactPhoneNumber::SubTypeDtmfMenu;
@@ -348,7 +327,7 @@
     sip->setData(CNT_ONLINEACCOUNT_EDITOR_MAXLENGTH, DetailMaxLength);
     model->appendRow(sip);
          
-    mBox->setModel( model );
+    mItem->comboBox()->setModel( model );
     
     // search the selected index to be set
     QString context = aContext.isEmpty() ? "" : aContext.first();
@@ -357,7 +336,7 @@
         if ( model->item(i)->data( DetailSubType ).toString() == aSubType &&
              model->item(i)->data( DetailContext ).toString() == context )
             {
-            mBox->setCurrentIndex( i );
+            mItem->comboBox()->setCurrentIndex( i );
             break;
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/src/cntpresencelistener.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,116 @@
+/*
+* 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:
+*
+*/
+
+#include "cntpresencelistener.h"
+
+#include <prcpresencebuddyinfo_qt.h>
+#include <prcpresencereader_qt.h>
+
+CntPresenceListener::CntPresenceListener(const QContact& contact, QObject* parent) :
+    QObject(parent),
+    mReader(NULL),
+    mContact(contact)
+{
+    mReader = PrcPresenceReader::createReader();
+    connect(mReader, SIGNAL(signalPresenceNotification(bool, PrcPresenceBuddyInfoQt*)), 
+                           this, SLOT(handlePresenceUpdate(bool, PrcPresenceBuddyInfoQt*)));
+}
+
+CntPresenceListener::~CntPresenceListener()
+{
+    delete mReader;
+    mReader = NULL;
+}
+
+QMap<QString, bool> CntPresenceListener::initialPresences(bool &combinedOnlineStatus)
+{
+    QMap<QString, bool> initialMap;
+
+    QList<QContactOnlineAccount> accounts = mContact.details<QContactOnlineAccount>();
+    
+    QList<PrcPresenceBuddyInfoQt*> buddies;
+    
+    foreach (QContactOnlineAccount account, accounts)
+    {
+        QString fullAccount = account.serviceProvider() + ':' + account.accountUri();
+        PrcPresenceBuddyInfoQt* buddy = mReader->presenceInfo(fullAccount);
+        
+        if (buddy)
+        {
+            buddies.append(buddy);
+            if (!mAccountList.contains(buddy->buddyId()))
+            {
+                bool isAvailable = (buddy->availability() == PrcPresenceBuddyInfoQt::PrcAvailable);
+                initialMap.insert(fullAccount, isAvailable);
+                mAccountList.append(buddy->buddyId());
+                mReader->subscribePresenceBuddyChange(buddy->buddyId());
+            }
+        }
+    }
+    
+    combinedOnlineStatus = parsePresence(buddies);
+    qDeleteAll(buddies);
+    
+    return initialMap;
+}
+    
+void CntPresenceListener::handlePresenceUpdate(bool aSuccess, PrcPresenceBuddyInfoQt* aPresenceBuddyInfo)
+{
+    if (aSuccess && aPresenceBuddyInfo != NULL)
+    {
+        if (mAccountList.contains(aPresenceBuddyInfo->buddyId()))
+        {
+            // First emit the account-specific presence updated signal
+            bool isAvailable = (aPresenceBuddyInfo->availability() == PrcPresenceBuddyInfoQt::PrcAvailable);
+            emit accountPresenceUpdated(aPresenceBuddyInfo->buddyId(), isAvailable);
+            
+            QList<PrcPresenceBuddyInfoQt*> buddies;
+
+            foreach (QString account, mAccountList)
+            {
+                PrcPresenceBuddyInfoQt* buddy = mReader->presenceInfo(account);
+
+                if (buddy)
+                {
+                    buddies.append(buddy);
+                }
+            }
+            
+            // emit the combined presence status
+            emit fullPresenceUpdated(parsePresence(buddies));
+            
+            qDeleteAll(buddies);
+        }
+    }
+}
+    
+bool CntPresenceListener::parsePresence(QList<PrcPresenceBuddyInfoQt*> buddyList)
+{
+    foreach (PrcPresenceBuddyInfoQt* buddy, buddyList)
+    {
+        PrcPresenceBuddyInfoQt::AvailabilityValues availability = buddy->availability();
+        
+        if (availability == PrcPresenceBuddyInfoQt::PrcAvailable)
+        {
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+// EOF
--- a/phonebookui/pbkcommonui/src/cntsettingsmodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntsettingsmodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -14,48 +14,64 @@
 * Description:  
 *
 */
-#include "cntsettingsview.h"
-#include <hbdataformmodelitem.h>
-#include <hbglobal.h>
+
+#include "cntsettingsmodel.h"
+#include <cntuids.h>
+#include <qstringlist.h>
+#include <xqsettingskey.h>
+#include "cntdebug.h"
 
-CntDefaultSettingsModel::CntDefaultSettingsModel()
+CntSettingsModel::CntSettingsModel() :
+HbDataFormModel()
 {
+    //create a model class    
+    HbDataFormModelItem* ord = new HbDataFormModelItem(HbDataFormModelItem::ComboBoxItem, hbTrId("txt_phob_setlabel_name_display_order"));
+    
     QStringList orderList;
+    // This order should be maintained as per the UI spec
     orderList.append( hbTrId("txt_phob_setlabel_name_display_order_val_last_name") );
     orderList.append( hbTrId("txt_phob_setlabel_name_display_order_val_last_name_separator") );
     orderList.append( hbTrId("txt_phob_setlabel_name_display_order_val_first_nam") );
-    /*
-    QStringList showList;
-    showList.append(hbTrId("txt_phob_setlabel_show_val_status_update"));
-    showList.append(hbTrId("txt_phob_setlabel_show_val_name_and_phonenumber"));
-    showList.append(hbTrId("txt_phob_setlabel_show_val_name_only"));
-    */
-    mOrder = new HbDataFormModelItem(HbDataFormModelItem::ComboBoxItem,  hbTrId("txt_phob_setlabel_name_display_order"));
-    mOrder->setContentWidgetData( "items", orderList );
+    
+    ord->setContentWidgetData( "items", orderList );
+    appendDataFormItem(ord, invisibleRootItem());
+    mNameOrderkey = new XQSettingsKey(XQSettingsKey::TargetCentralRepository,
+                             KCRUiContacts.iUid,
+                             KCntNameOrdering);
+    int settingValue = mSettings.readItemValue(*mNameOrderkey, XQSettingsManager::TypeInt).toInt();
 
-    /*
-    HbDataFormModelItem* show = new HbDataFormModelItem( HbDataFormModelItem::ComboBoxItem, hbTrId("txt_phob_setlabel_show") );
-    show->setContentWidgetData( "items", showList );
-    */
+    if (settingValue == CntOrderLastFirst) {
+        ord->setContentWidgetData("currentIndex", 0 );
+    } else if (settingValue == CntOrderLastCommaFirst) {
+        ord->setContentWidgetData("currentIndex", 1 );
+    } else if (settingValue == CntOrderFirstLast) {
+        ord->setContentWidgetData("currentIndex", 2 );
+    }
     
-    appendDataFormItem( mOrder, invisibleRootItem() );
-    /* appendDataFormItem( show, invisibleRootItem() );
-     */
+    connect(this, SIGNAL(dataChanged(QModelIndex , QModelIndex)), this, SLOT(handleDataChanged(QModelIndex , QModelIndex)));
 }
 
-CntDefaultSettingsModel::~CntDefaultSettingsModel()
+CntSettingsModel::~CntSettingsModel()
 {
-    
+    delete mNameOrderkey;
 }
 
-void CntDefaultSettingsModel::saveSettings()
+void CntSettingsModel::handleDataChanged(QModelIndex topLeft, QModelIndex bottomRight)
 {
-    QString selected = mOrder->contentWidgetData( "currentText" ).toString();
-    
+    Q_UNUSED(bottomRight)
+    bool written(true);
+            
+    if (topLeft.row() == 0) {
+        int selected = itemFromIndex(topLeft)->contentWidgetData( "currentIndex" ).toInt();
+        if (selected == 0) {
+            written = mSettings.writeItemValue(*mNameOrderkey, QVariant(CntOrderLastFirst));
+        } else if (selected == 1) {
+            written = mSettings.writeItemValue(*mNameOrderkey, QVariant(CntOrderLastCommaFirst));
+        } else if (selected == 2) {
+            written = mSettings.writeItemValue(*mNameOrderkey, QVariant(CntOrderFirstLast));
+        }
+        if (!written) {
+            CNT_LOG_ARGS(QString("failed writting cenrep key"))
+        }
+    }
 }
-
-void CntDefaultSettingsModel::loadSettings()
-{
-    mOrder->setContentWidgetData("currentText", hbTrId("txt_phob_setlabel_name_display_order_val_last_name_separator") );
-}
-// End of File
--- a/phonebookui/pbkcommonui/src/cntsettingsview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntsettingsview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -19,7 +19,9 @@
 #include <hbview.h>
 #include <hbdataform.h>
 #include <hbaction.h>
+#include "cntdebug.h"
 #include "cntsettingsview.h"
+#include "cntsettingsmodel.h"
 
 const char *CNT_SETTINGS_XML = ":/xml/contacts_settings.docml";
 
@@ -30,32 +32,43 @@
 mViewMgr( NULL ),
 mModel( NULL )
 {
+    CNT_ENTRY
+    
     bool ok;
     document()->load(CNT_SETTINGS_XML, &ok);
     if (!ok) {
         qFatal("Unable to read %S", CNT_SETTINGS_XML);
-    }    
-    mModel = new CntDefaultSettingsModel(); // default implementation
+    }
     
     mView = static_cast<HbView*> (document()->findWidget(QString("view")));
     mForm = static_cast<HbDataForm*> (document()->findWidget(QString("dataForm")));
     mForm->setItemRecycling(true);
+    
+    mModel = new CntSettingsModel();
     mForm->setModel( mModel );
     
     mBack = new HbAction(Hb::BackNaviAction, mView);
-    connect( mBack, SIGNAL(triggered()), this, SLOT(back()) );       
+    connect( mBack, SIGNAL(triggered()), this, SLOT(back()) );
+    
+    CNT_EXIT
 }
 
 CntSettingsView::~CntSettingsView()
 {
+    CNT_ENTRY
+    
     mView->deleteLater();
     delete mForm;
     delete mModel;
     delete mDoc;
+    
+    CNT_EXIT
 }
-    
+
 void CntSettingsView::activate( CntAbstractViewManager* aMgr, const CntViewParameters aArgs )
 {
+    CNT_ENTRY
+    
     mViewMgr = aMgr;
     mArgs = aArgs;
     
@@ -63,7 +76,7 @@
         mView->setNavigationAction(mBack);
     }
     
-    mModel->loadSettings();
+    CNT_EXIT
 }
 
 void CntSettingsView::deactivate()
@@ -87,14 +100,21 @@
 
 void CntSettingsView::back()
 {
-    mModel->saveSettings();
+    CNT_ENTRY
+    
     mViewMgr->back( mArgs );
+    
+    CNT_EXIT
 }
 HbDocumentLoader* CntSettingsView::document() 
 {
+    CNT_ENTRY
+    
     if ( !mDoc )
     {
         mDoc = new HbDocumentLoader();
     }
+    
+    CNT_EXIT
     return mDoc;
 }
--- a/phonebookui/pbkcommonui/src/cnturleditormodel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnturleditormodel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -16,20 +16,21 @@
 */
 #include "cnturleditormodel.h"
 #include "cntdetailmodelitem.h"
+#include "cntdetailorderinghelper.h"
 
 #include <qcontacturl.h>
 
 CntUrlEditorModel::CntUrlEditorModel(QContact* aContact) :
     CntDetailEditorModel(aContact)
 {
-    QList<QContactUrl> urlList = mContact->details<QContactUrl>();
-    if (urlList.isEmpty()) {
+    mUrlList = CntDetailOrderingHelper::getOrderedUrls(*mContact);
+    if (mUrlList.isEmpty()) {
         QContactUrl url;
         url.setSubType(QContactUrl::SubTypeHomePage);
-        urlList.append(url);
+        mUrlList.append(url);
     }
 
-    foreach( QContactUrl contactUrl, urlList ) {
+    foreach( QContactUrl contactUrl, mUrlList ) {
         CntDetailModelItem* item = new CntDetailModelItem(contactUrl);
         appendDataFormItem(item, invisibleRootItem());
     }
@@ -43,7 +44,7 @@
 {
     QContactUrl url;
     url.setSubType(QContactUrl::SubTypeHomePage);
-        
+    mUrlList.append( url );
     appendDataFormItem( new CntDetailModelItem(url), invisibleRootItem() );
 }
 
@@ -55,7 +56,11 @@
     for (int i(0); i < count; i++) {
         CntDetailModelItem* detail = static_cast<CntDetailModelItem*> (root->childAt(i));
         QContactDetail url = detail->detail();
-        mContact->saveDetail( &url );
+        
+        if ( !mUrlList.contains(url) )
+        {
+            mContact->saveDetail( &url );
+        }
         
         if ( url.value(QContactUrl::FieldUrl).isEmpty() )
         {
--- a/phonebookui/pbkcommonui/src/cnturleditorviewitem.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cnturleditorviewitem.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -17,7 +17,7 @@
 #include "cnturleditorviewitem.h"
 #include "cntdetailmodelitem.h"
 #include "cntdetailconst.h"
-#include <qgraphicslinearlayout.h>
+#include "cntcommondetailviewitem.h"
 #include <qstandarditemmodel.h>
 #include <qcontacturl.h>
 #include <hbdataformmodel.h>
@@ -28,11 +28,8 @@
 
 CntUrlEditorViewItem::CntUrlEditorViewItem( QGraphicsItem* aParent ) :
 CntDetailViewItem( aParent ),
-mBox(NULL),
-mEdit(NULL),
-mLayout(NULL)
+mItem(NULL)
 {
-    
 }
 
 CntUrlEditorViewItem::~CntUrlEditorViewItem()
@@ -46,41 +43,27 @@
 
 HbWidget* CntUrlEditorViewItem::createCustomWidget()
 {
-    connect(itemView()->mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)),
-            this, SLOT(changeOrientation(Qt::Orientation)));
-    
-    mLayout = new QGraphicsLinearLayout(itemView()->mainWindow()->orientation());
-    HbWidget* widget = new HbWidget();
-    mBox = new HbComboBox();
-    mEdit = new HbLineEdit();
-    mEdit->setMaxLength( CNT_URL_EDITOR_MAXLENGTH );
+    mItem = new CntCommonDetailViewItem(this);
+    mItem->editor()->setMaxLength( CNT_URL_EDITOR_MAXLENGTH );
     
-    widget->setLayout( mLayout );
-    mLayout->addItem( mBox );
-    mLayout->addItem( mEdit );
-
-    mLayout->setStretchFactor(mBox, 2);
-    mLayout->setStretchFactor(mEdit, 2);
-        
-    connect( mBox, SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) );
-    connect( mEdit, SIGNAL(textChanged(QString)),this, SLOT(textChanged(QString)) );
-        
     HbDataFormModel* model = static_cast<HbDataFormModel*>(itemView()->model());
     CntDetailModelItem* item = static_cast<CntDetailModelItem*>( model->itemFromIndex(modelIndex()) );
     QContactUrl detail = item->detail();
     
-    mEdit->setInputMethodHints( Qt::ImhUrlCharactersOnly );
+    mItem->editor()->setInputMethodHints( Qt::ImhUrlCharactersOnly );
     
     constructSubTypeModel( detail.contexts() );
     
-    mEdit->setText( detail.url() );
-    
-    return widget;
+    mItem->editor()->setText( detail.url() );
+    connect( mItem->comboBox(), SIGNAL(currentIndexChanged(int)), this, SLOT(indexChanged(int)) );
+    connect( mItem->editor(), SIGNAL(textChanged(QString)),this, SLOT(textChanged(QString)) );
+        
+    return mItem;
 }
     
 void CntUrlEditorViewItem::indexChanged( int aIndex )
 {
-    QString context = mBox->itemData( aIndex, DetailContext ).toString();
+    QString context = mItem->comboBox()->itemData( aIndex, DetailContext ).toString();
     HbDataFormModel* model = static_cast<HbDataFormModel*>(itemView()->model());
     CntDetailModelItem* item = static_cast<CntDetailModelItem*>( model->itemFromIndex(modelIndex()) );
     
@@ -105,11 +88,6 @@
     item->setDetail( url );
 }
 
-void CntUrlEditorViewItem::changeOrientation(Qt::Orientation aOrient)
-{
-    mLayout->setOrientation(aOrient);
-}
-
 void CntUrlEditorViewItem::constructSubTypeModel( QStringList aContext )
 {
     QStandardItemModel* model = new QStandardItemModel();
@@ -138,7 +116,7 @@
     work->setData(CNT_URL_EDITOR_MAXLENGTH, DetailMaxLength);
     model->appendRow(work);
     
-    mBox->setModel( model );
+    mItem->comboBox()->setModel( model );
     
     // search the selected index to be set
     QString context = aContext.isEmpty() ? "" : aContext.first();
@@ -146,7 +124,7 @@
         {
         if ( model->item(i)->data( DetailContext ).toString() == context )
             {
-            mBox->setCurrentIndex( i );
+            mItem->comboBox()->setCurrentIndex( i );
             break;
             }
         }
--- a/phonebookui/phonebookapp/phonebookapp.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookapp/phonebookapp.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -22,15 +22,13 @@
 TEMPLATE = app
 TARGET = phonebook
 
-ICON = resources/phonebook.svg
-
 #DEFINES += BUILD_QTCONTACTS
 
 DEPENDPATH += .
 INCLUDEPATH += .
-INCLUDEPATH += ../inc
+INCLUDEPATH += ../../inc
 INCLUDEPATH += ../pbkcommonui/inc
-INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 
 MOC_DIR = moc
 
@@ -61,7 +59,9 @@
         # Skip the UID2/3 thing
         TARGET.UID3 = 0x20022EF9
         TARGET.EPOCSTACKSIZE = 0x14000
-        TARGET.EPOCHEAPSIZE = 0x1000 0xA00000 
+        TARGET.EPOCHEAPSIZE = 0x1000 0xA00000
+        
+        SKINICON = qtg_large_phonebook 
 
         :BLD_INF_RULES.prj_exports += "resources/phonebook.splashml \epoc32\release\winscw\udeb\z\resource\hb\splashml\phonebook.splashml
         :BLD_INF_RULES.prj_exports += "resources/phonebook.splashml \epoc32\data\z\resource\hb\splashml\phonebook.splashml
--- a/phonebookui/phonebookapp/resources/phonebook.svg	Fri Jun 11 13:29:23 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="tiny" height="44.006px" version="1.1" viewBox="0 0 44 44.006" width="44px" x="0px" y="0px">
-<path d="M36.504,34.804V8.949c0-2.279-1.642-3.086-3.047-3.086L9.928,5.869c-0.553,0-1,0.447-1,1v2.47  c-1.113,0-1.935,0.815-1.935,1.819c0,1.001,0.712,1.817,1.935,1.817v3.434c-1.113,0-1.935,0.815-1.935,1.819  c0,1.001,0.759,1.817,1.935,1.817v3.485c-1.145,0-1.935,0.815-1.935,1.819c0,1.002,0.806,1.817,1.935,1.817v3.461  c-1.145,0-1.935,0.815-1.935,1.817c0,1.003,0.821,1.819,1.935,1.819v2.879c0,0.552,0.447,1,1,1h23.117  C35.189,38.144,36.504,36.771,36.504,34.804z" fill-opacity="0.2" stroke-opacity="0.2"/>
-<path d="M35.505,34.803V10.452L8.813,10.338c-0.451,0-0.819,0.363-0.819,0.818c0,0.451,0.368,0.818,0.819,0.818h1.114  v5.433H8.813c-0.451,0-0.819,0.365-0.819,0.82c0,0.451,0.368,0.818,0.819,0.818h1.114v5.484H8.813c-0.451,0-0.819,0.365-0.819,0.82  c0,0.451,0.368,0.816,0.819,0.816h1.114v5.46H8.813c-0.451,0-0.819,0.363-0.819,0.818c0,0.453,0.368,0.818,0.819,0.818h1.114v3.881  h23.119C35.685,37.145,35.505,34.803,35.505,34.803z" fill-opacity="0.5" stroke-opacity="0.5"/>
-<rect fill="none" height="44.006" width="44"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_1_" x1="22.7168" x2="22.7168" y1="2.6196" y2="42.6339">
-<stop offset="0" style="stop-color:#3687FF"/>
-<stop offset="1" style="stop-color:#051F7D"/>
-</linearGradient>
-<path d="M33.046,36.145H9.927V5.869h23.369c0,0,2.209-0.229,2.209,2.08v25.854  C35.505,33.803,35.685,36.145,33.046,36.145z" fill="url(#SVGID_1_)"/>
-<polygon fill-opacity="0.4" points="12.595,32.129 9.927,33.867 9.927,32.156 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="31.451" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_2_" x1="10.4668" x2="10.4668" y1="30.1924" y2="33.4658">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,31.445c0,0.453-0.364,0.818-0.816,0.818H8.813c-0.451,0-0.819-0.365-0.819-0.818l0,0  c0-0.455,0.368-0.818,0.819-0.818h3.313C12.577,30.627,12.941,30.99,12.941,31.445L12.941,31.445z" fill="url(#SVGID_2_)"/>
-<polygon fill-opacity="0.4" points="12.595,25.024 9.927,26.763 9.927,25.052 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="24.354" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_3_" x1="10.4668" x2="10.4668" y1="23.0957" y2="26.3691">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,24.351c0,0.451-0.364,0.816-0.816,0.816H8.813c-0.451,0-0.819-0.365-0.819-0.816l0,0  c0-0.455,0.368-0.82,0.819-0.82h3.313C12.577,23.53,12.941,23.896,12.941,24.351L12.941,24.351z" fill="url(#SVGID_3_)"/>
-<polygon fill-opacity="0.4" points="12.595,17.925 9.927,19.663 9.927,17.952 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="17.267" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_4_" x1="10.4668" x2="10.4668" y1="15.9722" y2="19.2495">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,17.228c0,0.451-0.364,0.818-0.816,0.818H8.813c-0.451,0-0.819-0.367-0.819-0.818l0,0  c0-0.455,0.368-0.82,0.819-0.82h3.313C12.577,16.407,12.941,16.772,12.941,17.228L12.941,17.228z" fill="url(#SVGID_4_)"/>
-<polygon fill-opacity="0.4" points="12.595,10.838 9.927,12.576 9.927,10.865 " stroke-opacity="0.4"/>
-<circle cx="12.227" cy="10.227" r="1.168"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_5_" x1="10.4668" x2="10.4668" y1="8.9033" y2="12.1768">
-<stop offset="0" style="stop-color:#FFFFFF"/>
-<stop offset="0.1978" style="stop-color:#FFFFFF"/>
-<stop offset="0.8462" style="stop-color:#000000"/>
-<stop offset="1" style="stop-color:#000000"/>
-</linearGradient>
-<path d="M12.941,10.156c0,0.451-0.364,0.818-0.816,0.818H8.813c-0.451,0-0.819-0.367-0.819-0.818l0,0  c0-0.455,0.368-0.818,0.819-0.818h3.313C12.577,9.338,12.941,9.701,12.941,10.156L12.941,10.156z" fill="url(#SVGID_5_)"/>
-<linearGradient gradientUnits="userSpaceOnUse" id="SVGID_6_" x1="23.6406" x2="23.6406" y1="11.1069" y2="42.3992">
-<stop offset="0" style="stop-color:#F2F2F2"/>
-<stop offset="0.1364" style="stop-color:#E4EDF0"/>
-<stop offset="0.3929" style="stop-color:#C0DFEB"/>
-<stop offset="0.7391" style="stop-color:#86C8E3"/>
-<stop offset="0.9945" style="stop-color:#57B6DD"/>
-<stop offset="1" style="stop-color:#57B6DD"/>
-</linearGradient>
-<path d="M25.46,20.76c-1.317,0.777-2.427,0.73-3.732,0.021c-3.713,0.674-4.901,3.396-4.901,6.652v1.244  c0,3.063,13.629,3.063,13.629,0v-1.244C30.455,24.147,29.25,21.404,25.46,20.76z M26.249,17.999  c0.723-1.343,0.883-2.334,0.883-3.422c0-1.982-1.54-3.62-3.491-3.62s-3.487,1.638-3.487,3.62c0,1.088,0.16,2.079,0.882,3.422  C22.405,20.574,24.633,20.661,26.249,17.999z" fill="url(#SVGID_6_)"/>
-<path d="M23.676,11.655c1.873,0,3.322,1.52,3.435,3.399c0.235-1.517-0.812-4.099-3.435-4.099  c-2.314,0-3.721,2.051-3.501,4.099C20.287,13.175,21.803,11.655,23.676,11.655z" fill="#051F7D"/>
-<path d="M25.46,20.76c-1.224,0.793-2.661,0.699-3.732,0.021c-5.413,0.912-4.901,6.568-4.901,7.353  c0-3.175,1.188-5.979,4.901-6.652c1.29,0.774,2.462,0.696,3.732-0.021c3.79,0.645,4.995,3.421,4.995,6.674  C30.627,24.162,29.25,21.404,25.46,20.76z" fill="#051F7D"/>
-<path d="M23.676,11.655c1.873,0,3.322,1.52,3.435,3.399c0.235-1.517-0.812-4.099-3.435-4.099  c-2.314,0-3.721,2.051-3.501,4.099C20.287,13.175,21.803,11.655,23.676,11.655z" fill-opacity="0.2" stroke-opacity="0.2"/>
-<path d="M25.46,20.76c-1.224,0.793-2.661,0.699-3.732,0.021c-5.413,0.912-4.901,6.568-4.901,7.353  c0-3.175,1.188-5.979,4.901-6.652c1.29,0.774,2.462,0.696,3.732-0.021c3.79,0.645,4.995,3.421,4.995,6.674  C30.627,24.162,29.25,21.404,25.46,20.76z" fill-opacity="0.2" stroke-opacity="0.2"/>
-</svg>
--- a/phonebookui/phonebookservices/inc/cntservicecontactfetchview.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/inc/cntservicecontactfetchview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -35,7 +35,7 @@
     int viewId() const { return serviceContactFetchView; }
     
 public slots:
-    void aboutToOpenView(const CntViewParameters viewParameters);
+    void aboutToOpenView(CntAbstractViewManager* aMgr, const CntViewParameters viewParameters);
     void aboutToCloseView();
     void cancelFetch();
 
--- a/phonebookui/phonebookservices/inc/cntserviceviewmanager.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/inc/cntserviceviewmanager.h	Wed Jun 23 18:02:44 2010 +0300
@@ -43,6 +43,9 @@
     void launchContactCard(QContact contact);
     void launchAssignContactCard(QContact contact, QContactDetail detail);
 
+protected slots:
+    virtual void closeApp();
+
 private:
     CntServiceHandler *mServiceHandler;
 };
--- a/phonebookui/phonebookservices/phonebookservices.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/phonebookservices.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -18,7 +18,7 @@
     src
 
 INCLUDEPATH +=  ../pbkcommonui/inc \
-                ../inc
+                ../../inc
                 
 INCLUDEPATH += ../../phonebookengines/cntimageutility/inc
 
--- a/phonebookui/phonebookservices/src/cntserviceassigncontactcardview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/src/cntserviceassigncontactcardview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -37,7 +37,7 @@
     mServiceHandler(aServiceHandler)
 {
     connect(this, SIGNAL(backPressed()), this, SLOT(doCloseView()));
-    connect(this, SIGNAL(viewActivated(QContact, QContactDetail)), this, SLOT(doViewActivated(QContact,QContactDetail)));
+    connect(this, SIGNAL(viewActivated(CntAbstractViewManager*, QContactDetail)), this, SLOT(doViewActivated(CntAbstractViewManager*,QContactDetail)));
     
     addActionsToToolBar();
 }
--- a/phonebookui/phonebookservices/src/cntservicecontactfetchview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/src/cntservicecontactfetchview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -38,7 +38,7 @@
     
     connect(cancel,  SIGNAL(triggered()), this, SLOT(cancelFetch()) );
     connect( this, SIGNAL(viewClosed()), this, SLOT(aboutToCloseView()) );
-    connect( this, SIGNAL(viewOpened(const CntViewParameters)), this, SLOT(aboutToOpenView(const CntViewParameters)) );
+    connect( this, SIGNAL(viewOpened(CntAbstractViewManager*, const CntViewParameters)), this, SLOT(aboutToOpenView(CntAbstractViewManager*, const CntViewParameters)) );
 }
 
 CntServiceContactFetchView::~CntServiceContactFetchView()
@@ -94,8 +94,10 @@
     mServiceHandler->completeFetch(serviceList);
 }
 
-void CntServiceContactFetchView::aboutToOpenView(const CntViewParameters aArgs)
+void CntServiceContactFetchView::aboutToOpenView(CntAbstractViewManager* aMgr, const CntViewParameters aArgs)
 {
+    mMgr = aMgr;
+    
     // Set title of the view.
     QString title = aArgs.value(CntServiceHandler::ETitle).toString();
     mView->setTitle(title);
@@ -107,19 +109,19 @@
         {
             QContactActionFilter actionFilter;
             actionFilter.setActionName("message");
-            mListModel->setFilterAndSortOrder(actionFilter);
+            mListModel->setFilter(actionFilter);
         }
         else if (action == KCntActionCall)
         {
             QContactActionFilter actionFilter;
             actionFilter.setActionName("call");
-            mListModel->setFilterAndSortOrder(actionFilter);
+            mListModel->setFilter(actionFilter);
         }
         else if (action == KCntActionEmail)
         {
             QContactActionFilter actionFilter;
             actionFilter.setActionName("email");
-            mListModel->setFilterAndSortOrder(actionFilter);
+            mListModel->setFilter(actionFilter);
         }
         else
         {
@@ -127,7 +129,7 @@
             filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
             QString typeContact = QContactType::TypeContact;
             filter.setValue(typeContact);
-            mListModel->setFilterAndSortOrder(filter);
+            mListModel->setFilter(filter);
         }
 
         // hide my card if it's not set
--- a/phonebookui/phonebookservices/src/cntservicecontactselectionview.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/src/cntservicecontactselectionview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -64,7 +64,7 @@
     filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
     QString typeContact = QContactType::TypeContact;
     filter.setValue(typeContact);
-    mListModel->setFilterAndSortOrder(filter);
+    mListModel->setFilter(filter);
     // hide my card if it's not set
     if (mListModel->myCardId() == 0)
     {
--- a/phonebookui/phonebookservices/src/cntservicehandler.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/src/cntservicehandler.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -137,11 +137,13 @@
     QContact contact;
     QVersitReader reader;
     QFile file(vCardFile);
-    file.open(QIODevice::ReadOnly);
+
+    if (!file.open(QIODevice::ReadOnly))
+        return;
     reader.setDevice(&file);
-    
     reader.startReading();
     reader.waitForFinished();
+
     // Use the resulting document(s)...
     QVersitContactImporter importer;
     QList<QVersitDocument> versitDocuments = reader.results();
--- a/phonebookui/phonebookservices/src/cntserviceviewmanager.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/src/cntserviceviewmanager.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -59,6 +59,12 @@
 /*Remove all views*/
 }
 
+void CntServiceViewManager::closeApp()
+{
+    // quit happens when returnValueDelivered signal is returned
+    // from service handler, see constructor.
+}
+
 /*!
 Launch fetch service view.
 */
--- a/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/main.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/main.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -20,7 +20,8 @@
 #include <hbmainwindow.h>
 #include <qapplication.h>
 #include <hbview.h>
-#include <QGraphicsLinearLayout>
+#include <hbscrollarea.h>
+#include <QGraphicsGridLayout>
 
 #include "testpbkservices.h"
 
@@ -33,62 +34,151 @@
     // Includes decorators such as signal strength and battery life indicator.
     HbMainWindow mainWindow;
 
-    testPbkServices *service=new testPbkServices(&mainWindow);
+    testPbkServices *service = new testPbkServices(&mainWindow);
 
     HbView* view = new HbView();
     view->setTitle("QtPhonebook Test Application");
 
-    QGraphicsLinearLayout* mainLayout = new QGraphicsLinearLayout(Qt::Vertical);
+    QGraphicsGridLayout* mainLayout = new QGraphicsGridLayout();
+
+    HbPushButton* button = NULL;
+    int row = 0;
+
+    // FETCH =================================================================
+
+    button = new HbPushButton("Multi Fetch");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchMultiFetch()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchMultiFetch_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
 
-    HbPushButton *button1 = new HbPushButton("Launch Fetch");
-    QObject::connect(button1, SIGNAL(pressed()), service, SLOT(launchFetch()));
+    button = new HbPushButton("Multi fetch SMS");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchMultiFetch_sms()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchMultiFetch_sms_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Multi fetch EMAIL");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchMultiFetch_email()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchMultiFetch_email_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
 
-    HbPushButton *button2 = new HbPushButton("Launch SMS fetch");
-    QObject::connect(button2, SIGNAL(pressed()), service, SLOT(launchSmsFilteredFetch()));
+    button = new HbPushButton("Single fetch");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchSingleFetch()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchSingleFetch_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    // EDIT - create new =====================================================
 
-    HbPushButton *button3 = new HbPushButton("Launch EMAIL fetch");
-    QObject::connect(button3, SIGNAL(pressed()), service, SLOT(launchEmailFilteredFetch()));
+    button = new HbPushButton("Edit create new - number");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditCreateNew_number()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditCreateNew_number_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Edit create new - email");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditCreateNew_email()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditCreateNew_email_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Edit create new - onlineAccount");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditCreateNew_onlineAccount()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditCreateNew_onlineAccount_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
 
-    HbPushButton *button4 = new HbPushButton("Launch editor with number");
-    QObject::connect(button4, SIGNAL(pressed()), service, SLOT(launchEditorNumber()));
-    
-    HbPushButton *button5 = new HbPushButton("Launch editor with email");
-    QObject::connect(button5, SIGNAL(pressed()), service, SLOT(launchEditorEmail()));
-    
-    HbPushButton *button6 = new HbPushButton("Launch editor with online account");
-    QObject::connect(button6, SIGNAL(pressed()), service, SLOT(launchEditorOnlineAccount()));
-    
-    HbPushButton *button7 = new HbPushButton("Update contact with number");
-    QObject::connect(button7, SIGNAL(pressed()), service, SLOT(launchUpdateEditorNumber()));
-    
-    HbPushButton *button8 = new HbPushButton("Update contact with email");
-    QObject::connect(button8, SIGNAL(pressed()), service, SLOT(launchUpdateEditorEmail()));
+    button = new HbPushButton("Launch editor with vCard");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditorVCard()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditorVCard_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    // EDIT - update existing ================================================
+
+    button = new HbPushButton("Edit/update existing - number");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditUpdateExisting_number()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditUpdateExisting_number_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Edit/update existing - email");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditUpdateExisting_email()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditUpdateExisting_email_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Edit/update existing - onlineAccount");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditUpdateExisting_onlineAccount()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchEditUpdateExisting_onlineAccount_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    // CONTACT CARD ==========================================================
+
+    button = new HbPushButton("Launch contact card");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCard()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCard_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Launch contact card with number");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCardNumber()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCardNumber_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Launch contact card with email");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCardEmail()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCardEmail_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
+
+    button = new HbPushButton("Launch contact card with online account");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCardOnlineAccount()));
+    mainLayout->addItem(button, row, 0);
+    button = new HbPushButton("old");
+    QObject::connect(button, SIGNAL(pressed()), service, SLOT(launchContactCardOnlineAccount_old()));
+    mainLayout->addItem(button, row, 1);
+    row++;
     
-    HbPushButton *button9 = new HbPushButton("Update contact with online account");
-    QObject::connect(button9, SIGNAL(pressed()), service, SLOT(launchUpdateEditorOnlineAccount()));
-
-    HbPushButton *button10 = new HbPushButton("Launch single fetch");
-    QObject::connect(button10, SIGNAL(pressed()), service, SLOT(launchSingleFetch()));
-    	
-    HbPushButton *button11 = new HbPushButton("Launch editor with vCard");
-    QObject::connect(button11, SIGNAL(pressed()), service, SLOT(launchEditorVCard()));
-
-    mainLayout->addItem(button1);
-    mainLayout->addItem(button2);
-    mainLayout->addItem(button3);
-    mainLayout->addItem(button4);
-    mainLayout->addItem(button5);
-    mainLayout->addItem(button6);
-    mainLayout->addItem(button7);
-    mainLayout->addItem(button8);
-    mainLayout->addItem(button9);
-    mainLayout->addItem(button10);
-    mainLayout->addItem(button11);
-    
-    
-    view->setLayout(mainLayout);
-
+    QGraphicsWidget *graphicsWidget = new QGraphicsWidget();
+    graphicsWidget->setLayout(mainLayout);
+    HbScrollArea *scrollArea = new HbScrollArea();
+    scrollArea->setContentWidget(graphicsWidget);
+    view->setWidget(scrollArea);
     mainWindow.addView(view);
+    row++;
 
     // Show widget
     mainWindow.show();
--- a/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/qtpbkservicestestapp.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/qtpbkservicestestapp.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -11,20 +11,21 @@
 #
 # Contributors:
 #
-# Description: 
+# Description: App for testing Contacts highway UI services
 #
 
 TEMPLATE = app
 TARGET =
 DEPENDPATH += .
 INCLUDEPATH += .
+INCLUDEPATH += ../../../../inc
 
 CONFIG += hb
 
 LIBS+=-lhbcore -lxqservice -lqtcontacts -lcntlistmodel
 
 # Input
-INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 
 HEADERS += testpbkservices.h
 
--- a/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/testpbkservices.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/testpbkservices.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -29,6 +29,8 @@
 #include <QGraphicsLinearLayout>
 #include <QDebug>
 
+#include "cntdebug.h"
+
 
 testPbkServices::testPbkServices(HbMainWindow *aParent)
 {
@@ -40,300 +42,317 @@
 
 testPbkServices::~testPbkServices()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    delete mRequest;
+    mRequest=0;
+}
+
+void testPbkServices::launchMultiFetch()
+{
+    CNT_ENTRY
+    launchMultiFetch(
+        true,           // aNewInterface = true
+        KCntActionAll);  // aAction (all actions in this case)
+    CNT_EXIT
+}
+
+void testPbkServices::launchMultiFetch_old()
+{
+    CNT_ENTRY
+    launchMultiFetch(
+        false,           // aNewInterface = false
+        KCntActionAll);  // aAction (all actions in this case)
+    CNT_EXIT
+}
+
+void testPbkServices::launchMultiFetch_sms()
+{
+    CNT_ENTRY
+    launchMultiFetch(
+        true,           // aNewInterface = false
+        KCntActionSms);  // aAction
+    CNT_EXIT
 }
 
-void testPbkServices::launchEditorNumber()
+void testPbkServices::launchMultiFetch_sms_old()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchMultiFetch(
+        false,           // aNewInterface
+        KCntActionSms);  // aAction
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editCreateNew(QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << QContactPhoneNumber::DefinitionName.operator QVariant();
-    args << "1234567";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchMultiFetch_email()
+{
+    CNT_ENTRY
+    launchMultiFetch(
+        true,              // aNewInterface
+        KCntActionEmail);  // aAction
+    CNT_EXIT
+}
+
+void testPbkServices::launchMultiFetch_email_old()
+{
+    CNT_ENTRY
+    launchMultiFetch(
+        false,             // aNewInterface
+        KCntActionEmail);  // aAction
+    CNT_EXIT
+}
+
+void testPbkServices::launchSingleFetch()
+{
+    CNT_ENTRY
+    launchSingleFetch(
+        true,           // aNewInterface
+        KCntActionAll ); // aAction
+    CNT_EXIT
 }
 
-void testPbkServices::launchEditorEmail()
+void testPbkServices::launchSingleFetch_old()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchSingleFetch(
+        false,           // aNewInterface
+        KCntActionAll ); // aAction
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editCreateNew(QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << QContactEmailAddress::DefinitionName.operator QVariant();
-    args << "email@mailprovider.com";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchEditCreateNew_number()
+{
+    CNT_ENTRY
+    launchEditCreateNew(
+        true,                                // aNewInterface
+        QContactPhoneNumber::DefinitionName, // aDetailType
+        "1234567");                          // aFieldContent
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditCreateNew_number_old()
+{
+    CNT_ENTRY
+    launchEditCreateNew(
+        false,                               // aNewInterface
+        QContactPhoneNumber::DefinitionName, // aDetailType
+        "1234567");                          // aFieldContent
+    CNT_EXIT
 }
 
-void testPbkServices::launchEditorOnlineAccount()
+void testPbkServices::launchEditCreateNew_email()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchEditCreateNew(
+        true,                                 // aNewInterface
+        QContactEmailAddress::DefinitionName, // aDetailType
+        "email@mailprovider.com");            // aFieldContent
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editCreateNew(QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << QContactOnlineAccount::DefinitionName.operator QVariant();
-    args << "account@provider.com";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchEditCreateNew_email_old()
+{
+    CNT_ENTRY
+    launchEditCreateNew(
+        false,                                // aNewInterface
+        QContactEmailAddress::DefinitionName, // aDetailType
+        "email@mailprovider.com");            // aFieldContent
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditCreateNew_onlineAccount()
+{
+    CNT_ENTRY
+    launchEditCreateNew(
+        true,                                  // aNewInterface
+        QContactOnlineAccount::DefinitionName, // aDetailType
+        "account@provider.com");               // aFieldContent
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditCreateNew_onlineAccount_old()
+{
+    CNT_ENTRY
+    launchEditCreateNew(
+        false,                                 // aNewInterface
+        QContactOnlineAccount::DefinitionName, // aDetailType
+        "account@provider.com");            // aFieldContent
+    CNT_EXIT
 }
 
 void testPbkServices::launchEditorVCard()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchEditorVCard(
+        true); // aNewInterface
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditorVCard_old()
+{
+    CNT_ENTRY
+    launchEditorVCard(
+        false); // aNewInterface
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editCreateNew(QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << "C:\\data\\Others\\testvcard.vcf";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchEditUpdateExisting_number()
+{
+    CNT_ENTRY
+    launchEditUpdateExisting(
+        true,                                // aNewInterface
+        QContactPhoneNumber::DefinitionName, // aDetailType
+        "1234567");                          // aDetailValue
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditUpdateExisting_number_old()
+{
+    CNT_ENTRY
+    launchEditUpdateExisting(
+        false,                               // aNewInterface
+        QContactPhoneNumber::DefinitionName, // aDetailType
+        "1234567");                          // aDetailValue
+    CNT_EXIT
 }
 
-void testPbkServices::launchUpdateEditorNumber()
+void testPbkServices::launchEditUpdateExisting_email()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchEditUpdateExisting(
+        true,                                // aNewInterface
+        QContactEmailAddress::DefinitionName, // aDetailType
+        "email@mailprovider.com");                          // aDetailValue
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editUpdateExisting(QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << QContactPhoneNumber::DefinitionName.operator QVariant();
-    args << "1234567";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchEditUpdateExisting_email_old()
+{
+    CNT_ENTRY
+    launchEditUpdateExisting(
+        false,                                // aNewInterface
+        QContactEmailAddress::DefinitionName, // aDetailType
+        "email@mailprovider.com");            // aDetailValue
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditUpdateExisting_onlineAccount()
+{
+    CNT_ENTRY
+    launchEditUpdateExisting(
+        true,                                  // aNewInterface
+        QContactOnlineAccount::DefinitionName, // aDetailType
+        "account@provider.com");               // aDetailValue
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditUpdateExisting_onlineAccount_old()
+{
+    CNT_ENTRY
+    launchEditUpdateExisting(
+        false,                                 // aNewInterface
+        QContactOnlineAccount::DefinitionName, // aDetailType
+        "account@provider.com");               // aDetailValue
+    CNT_EXIT
 }
 
-void testPbkServices::launchUpdateEditorEmail()
+void testPbkServices::launchContactCard()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchContactCard(
+        true ); // aNewInterface
+    CNT_EXIT
+}
+
+void testPbkServices::launchContactCard_old()
+{
+    CNT_ENTRY
+    launchContactCard(
+        false ); // aNewInterface
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editUpdateExisting(QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << QContactEmailAddress::DefinitionName.operator QVariant();
-    args << "email@mailprovider.com";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchContactCardNumber()
+{
+    CNT_ENTRY
+    launchContactCard(
+        true,                                // aNewInterface
+        QContactPhoneNumber::DefinitionName, // aDetailType
+        "777555669" );                       // aDetailValue
+    CNT_EXIT
+}
+
+void testPbkServices::launchContactCardNumber_old()
+{
+    CNT_ENTRY
+    launchContactCard(
+        false,                               // aNewInterface
+        QContactPhoneNumber::DefinitionName, // aDetailType
+        "777555669" );                       // aDetailValue
+    CNT_EXIT
 }
 
-void testPbkServices::launchUpdateEditorOnlineAccount()
+void testPbkServices::launchContactCardEmail()
 {
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
+    CNT_ENTRY
+    launchContactCard(
+        true,                                 // aNewInterface
+        QContactEmailAddress::DefinitionName, // aDetailType
+        "aa.jj@aajj.com" );                   // aDetailValue
+    CNT_EXIT
+}
 
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("editUpdateExisting(QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
-    
-    args << QContactOnlineAccount::DefinitionName.operator QVariant();
-    args << "account@provider.com";
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+void testPbkServices::launchContactCardEmail_old()
+{
+    CNT_ENTRY
+    launchContactCard(
+        false,                                // aNewInterface
+        QContactEmailAddress::DefinitionName, // aDetailType
+        "aa.jj@aajj.com" );                   // aDetailValue
+    CNT_EXIT
+    CNT_EXIT
+}
+
+void testPbkServices::launchContactCardOnlineAccount()
+{
+    CNT_ENTRY
+    launchContactCard(
+        true,                                  // aNewInterface
+        QContactOnlineAccount::DefinitionName, // aDetailType
+        "account@provider.com" );              // aDetailValue
+    CNT_EXIT
+}
+
+void testPbkServices::launchContactCardOnlineAccount_old()
+{
+    CNT_ENTRY
+    launchContactCard(
+        true,                                  // aNewInterface
+        QContactOnlineAccount::DefinitionName, // aDetailType
+        "account@provider.com" );              // aDetailValue
+    CNT_EXIT
 }
 
 void testPbkServices::onEditCompleted(const QVariant& value)
 {
+    CNT_ENTRY
     mMainWindow->activateWindow();
     
     if (value.toInt() == 1)
     {
         HbMessageBox::information("Contact saved");
+        CNT_LOG_ARGS("test: Contact saved")
     }
     else
     {
         HbMessageBox::information("Contact saving failed");
-    }
-}
-
-void testPbkServices::launchFetch()
-{
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
-
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("fetch(QString,QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
-    
-    args << "Non-filtered multi-fetch";
-    args << KCntActionAll; 
-    args << KCntFilterDisplayAll; 
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
-}
-
-void testPbkServices::launchSingleFetch()
-{
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
+        CNT_LOG_ARGS("test: Contact saving failed")
     }
-
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("Dofetch(QString,QString,QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
-    
-    args << "Single-fetching";
-    args << KCntActionAll; 
-    args << KCntFilterDisplayAll;
-    args << KCntSingleSelectionMode;
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
+    CNT_EXIT
 }
 
-void testPbkServices::launchSmsFilteredFetch()
-{
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
-
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("fetch(QString,QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
-    
-    args << "Filtered multi-fetch";
-    args << KCntActionSms; 
-    args << KCntFilterDisplayAll;
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
-}
-
-void testPbkServices::launchEmailFilteredFetch()
-{
-    if (mRequest)
-    {
-        delete mRequest;
-        mRequest=0;
-    }
-
-    QVariantList args; 
-    QString serviceName("com.nokia.services.phonebookservices"); 
-    QString operation("fetch(QString,QString,QString)");
-    XQApplicationManager appMng;
-    mRequest = appMng.create(serviceName, "Fetch", operation, true); // embedded 
-    
-    // Result handlers 
-    connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
-    
-    args << "Filtered multi-fetch";
-    args << KCntActionEmail; 
-    args << KCntFilterDisplayAll;
-    
-    mRequest->setArguments(args); 
-    mRequest->send();
-}
-
-
 
 void testPbkServices::onRequestCompleted(const QVariant& value)
 {
-
+    CNT_ENTRY
     mMainWindow->activateWindow();
 
     CntServicesContactList retValue;
@@ -342,7 +361,8 @@
 
     if (retValue.count() == 0)
     {
-        HbMessageBox::information("Nothing returned");
+        HbMessageBox::information("test: Nothing returned");
+        CNT_LOG_ARGS("No data returned.")
     }
 
     else
@@ -353,12 +373,14 @@
             QString name      = retValue[i].mDisplayName;
             listWidget->addItem("name:" );
             listWidget->addItem(name);
+            CNT_LOG_ARGS("Returned name: " << name)
 
             QString number    = retValue[i].mPhoneNumber;
             if (number!="")
                 {
                 listWidget->addItem("number:");
                 listWidget->addItem(number);
+                CNT_LOG_ARGS("Returned number: " << number)
                 }
 
             QString emailAddress    = retValue[i].mEmailAddress;
@@ -366,6 +388,7 @@
                 {
                 listWidget->addItem("emailAddress:");
                 listWidget->addItem(emailAddress);
+                CNT_LOG_ARGS("Returned email: " << emailAddress)
                 }
 
 
@@ -394,9 +417,330 @@
             popup->setTimeout(15000);
             popup->open();
     }
+    CNT_EXIT
+}
 
+void testPbkServices::launchMultiFetch( bool aNewInterface, QString aAction )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+
+    QVariantList args; 
+
+    XQApplicationManager appMng;
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactFetch"); 
+        QString operation("multiFetch(QString,QString,QString)");
+        // There are two kinds of create() methods in XQApplicationManager. The one with four arguments
+        // takes the service name also. The one with three arguments (used below) does not take the service name.
+        // The interface name is enough for finding the correct provider at run time.
+        mRequest = appMng.create(interface, operation, true); // embedded
+    }
+    else
+    {
+        mRequest = appMng.create(
+            "com.nokia.services.phonebookservices",// service
+            "Fetch",                             // interface
+            "fetch(QString,QString,QString)",  // operation
+            true); // embedded 
+    }
+
+    if (mRequest)
+        {
+        CNT_LOG_ARGS("Created request.")
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
+        
+        args << "My own title"; // This is the title for the view
+        args << aAction; 
+        args << KCntFilterDisplayAll; 
+        
+        mRequest->setArguments(args); 
+        mRequest->send();
+        }
+    else
+        {
+        CNT_LOG_ARGS("Failed to create request.")
+        }
+    CNT_EXIT
+}
+
+void testPbkServices::launchSingleFetch( bool aNewInterface, QString aAction )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+
+    QVariantList args; 
+    XQApplicationManager appMng;
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactFetch"); 
+        QString operation("singleFetch(QString,QString,QString)");
+        // There are two kinds of create() methods in XQApplicationManager. The one with four arguments
+        // takes the service name also. The one with three arguments (used below) does not take the service name.
+        // The interface name is enough for finding the correct provider at run time.
+        mRequest = appMng.create(interface, operation, true); // embedded
+    }
+    else
+    {
+        QString serviceName("com.nokia.services.phonebookservices");
+        QString interface("Fetch");
+        QString operation("Dofetch(QString,QString,QString,QString)");
+        mRequest = appMng.create(serviceName, interface, operation, true); // embedded 
+    }
+
+    if ( mRequest )
+    {
+        CNT_LOG_ARGS("Created request.")        
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
+        
+        args << "Single-fetching";
+        args << aAction; 
+        args << KCntFilterDisplayAll;
+        if ( !aNewInterface )
+        {
+            // Only the old interface takes this useless argument.
+            args << KCntSingleSelectionMode;
+        }
+        
+        mRequest->setArguments(args); 
+        mRequest->send();
+    }
+    else
+    {
+        CNT_LOG_ARGS("Failed to create request.")
+    }
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditCreateNew( bool aNewInterface, QString aDetailType, QString aFieldContent )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+
+    QVariantList args; 
+    XQApplicationManager appMng;
+    QString operation("editCreateNew(QString,QString)");
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactFetch"); 
+        // service name is not needed
+        mRequest = appMng.create( interface, operation, true); // embedded
+    }
+    else
+    {
+        QString interface("Fetch");
+        QString serviceName("com.nokia.services.phonebookservices"); 
+        mRequest = appMng.create(serviceName, interface, operation, true); // embedded 
+    }
+
+    if ( mRequest )
+    {
+        CNT_LOG_ARGS("Created request.")
+        
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
+        
+        args << aDetailType;
+        args << aFieldContent;
+        
+        mRequest->setArguments(args); 
+        mRequest->send();
+        CNT_LOG_ARGS("Sent request.")
+    }
+    else
+    {
+        CNT_LOG_ARGS("Failed to create request.")
+    }
+    CNT_EXIT
 }
 
+void testPbkServices::launchEditorVCard( bool aNewInterface )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+
+    QVariantList args; 
+    XQApplicationManager appMng;
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactEdit"); 
+        QString operation("editCreateNewFromVCard(QString)");
+        // service name is not needed
+        mRequest = appMng.create( interface, operation, true); // embedded 
+    }
+    else
+    {
+        QString interface("Fetch");
+        QString operation("editCreateNew(QString)");
+        QString serviceName("com.nokia.services.phonebookservices");
+        mRequest = appMng.create(serviceName, interface, operation, true); // embedded 
+    }
+
+    if ( mRequest )
+    {
+        CNT_LOG_ARGS("Created request.")
+        
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
+        
+        args << "C:\\data\\Others\\testvcard.vcf";
+        
+        mRequest->setArguments(args); 
+        mRequest->send();
+        CNT_LOG_ARGS("Sent request.")
+    }
+    else
+    {
+        CNT_LOG_ARGS("Failed to create request.")
+    }
+    CNT_EXIT
+}
+
+void testPbkServices::launchEditUpdateExisting( bool aNewInterface, QString aDetailType, QString aDetailValue )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+
+    QVariantList args; 
+    XQApplicationManager appMng;
+    QString operation("editUpdateExisting(QString,QString)");
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactEdit");
+        // service name is not needed
+        mRequest = appMng.create(interface, operation, true); // embedded 
+    }
+    else
+    {
+        QString interface("Fetch");
+        QString serviceName("com.nokia.services.phonebookservices"); 
+        mRequest = appMng.create(serviceName, interface, operation, true); // embedded 
+    }
+    if ( mRequest )
+    {
+        CNT_LOG_ARGS("Created request.")
+        
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onEditCompleted(const QVariant&)));
+        
+        args << aDetailType;
+        args << aDetailValue;
+        
+        mRequest->setArguments(args); 
+        mRequest->send();
+        CNT_LOG_ARGS("Sent request.")
+    }
+    else
+    {
+        CNT_LOG_ARGS("Failed to create request.")
+    }
+    CNT_EXIT
+}
+
+void testPbkServices::launchContactCard( bool aNewInterface )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+
+    // save test contact
+    QContact contact;
+    QContactName name;
+    QContactPhoneNumber number;
+    QContactManager mgr("symbian");
+    
+    name.setFirstName("Test launchContactCard");
+    number.setNumber("0202221111");
+    contact.saveDetail(&name);
+    contact.saveDetail(&number);
+    mgr.saveContact(&contact);
+    
+    // get contact id
+    int id = contact.id().localId();
+        
+    QVariantList args; 
+    XQApplicationManager appMng;
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactView");
+        QString operation("openContactCard(int)");
+        // interface name is not needed
+        mRequest = appMng.create( interface, operation, true); // embedded 
+    }
+    else
+    {
+        QString interface("Fetch");
+        QString operation("open(int)");
+        QString serviceName("com.nokia.services.phonebookservices");
+        mRequest = appMng.create(serviceName, interface, operation, true); // embedded 
+    }
+    if ( mRequest )
+    {    
+        CNT_LOG_ARGS("Request created.")
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
+        
+        args << id;
+        
+        mRequest->setArguments(args); 
+        mRequest->send();
+        CNT_LOG_ARGS("Request sent.")
+    }
+    else
+    {
+        CNT_LOG_ARGS("Failed to create request")
+    }
+    CNT_EXIT
+}
+
+void testPbkServices::launchContactCard( bool aNewInterface, QString aDetailType, QString aDetailValue )
+{
+    CNT_ENTRY
+    delete mRequest;
+    mRequest=0;
+        
+    QVariantList args; 
+    XQApplicationManager appMng;
+    if ( aNewInterface )
+    {
+        QString interface("com.nokia.symbian.IContactView");
+        QString operation("openContactCard(QString,QString)");
+        // service name is not needed
+        mRequest = appMng.create(interface, operation, true); // embedded 
+    }
+    else
+    {
+        QString interface("Fetch");
+        QString operation("open(QString,QString)");
+        QString serviceName("com.nokia.services.phonebookservices");
+        mRequest = appMng.create(serviceName, interface, operation, true); // embedded 
+    }
+    if ( mRequest )
+    {    
+        CNT_LOG_ARGS("Request created.")
+        // Result handlers 
+        connect (mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(onRequestCompleted(const QVariant&)));
+
+        args << aDetailType;
+        args << aDetailValue;
+
+        mRequest->setArguments(args); 
+        mRequest->send();
+    }
+    else
+    {
+        CNT_LOG_ARGS("Failed to create request")
+    }
+    CNT_EXIT
+}
 
 Q_IMPLEMENT_USER_METATYPE(CntServicesContact)
 Q_IMPLEMENT_USER_METATYPE_NO_OPERATORS(CntServicesContactList)
--- a/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/testpbkservices.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookservices/tsrc/qtpbkservicestestapp/testpbkservices.h	Wed Jun 23 18:02:44 2010 +0300
@@ -26,22 +26,52 @@
 
 class HbMainWindow;
 
+/**
+ * Launches phonebookservices highway services, for functional testing.
+ */
 class testPbkServices : public QObject
 {
     Q_OBJECT
 
 public slots:
-    void launchFetch();
+    // FETCH
+    void launchMultiFetch();
+    void launchMultiFetch_old();
+    void launchMultiFetch_sms();
+    void launchMultiFetch_sms_old();
+    void launchMultiFetch_email();
+    void launchMultiFetch_email_old();
     void launchSingleFetch();
-    void launchSmsFilteredFetch();
-    void launchEmailFilteredFetch();
-    void launchEditorNumber();
-    void launchEditorEmail();
-    void launchEditorOnlineAccount();
+    void launchSingleFetch_old();
+
+    // EDIT - create new
+    void launchEditCreateNew_number();
+    void launchEditCreateNew_number_old();
+    void launchEditCreateNew_email();
+    void launchEditCreateNew_email_old();
+    void launchEditCreateNew_onlineAccount();
+    void launchEditCreateNew_onlineAccount_old();
     void launchEditorVCard();
-    void launchUpdateEditorNumber();
-    void launchUpdateEditorEmail();
-    void launchUpdateEditorOnlineAccount();
+    void launchEditorVCard_old();
+
+    // EDIT - update existing
+    void launchEditUpdateExisting_number();
+    void launchEditUpdateExisting_number_old();
+    void launchEditUpdateExisting_email();
+    void launchEditUpdateExisting_email_old();
+    void launchEditUpdateExisting_onlineAccount();
+    void launchEditUpdateExisting_onlineAccount_old();
+
+    // CONTACT CARD
+    void launchContactCard();
+    void launchContactCard_old();
+    void launchContactCardNumber();
+    void launchContactCardNumber_old();
+    void launchContactCardEmail();
+    void launchContactCardEmail_old();
+    void launchContactCardOnlineAccount();
+    void launchContactCardOnlineAccount_old();
+
     void onEditCompleted(const QVariant& value);
     void onRequestCompleted(const QVariant& value);
 
@@ -50,6 +80,15 @@
     ~testPbkServices();
 
 private:
+    void launchMultiFetch( bool aNewInterface, QString aAction );
+    void launchSingleFetch( bool aNewInterface, QString aAction );
+    void launchEditCreateNew( bool aNewInterface, QString aDetailType, QString aFieldContent );
+    void launchEditorVCard( bool aNewInterface );
+    void launchEditUpdateExisting( bool aNewInterface, QString aDetailType, QString aDetailValue );
+    void launchContactCard( bool aNewInterface );
+    void launchContactCard( bool aNewInterface, QString aDetailType, QString aDetailValue );
+
+private:
 
     XQAiwRequest         *mRequest; 
     HbMainWindow         *mMainWindow;
--- a/phonebookui/phonebookui.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/phonebookui.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -30,7 +30,10 @@
      "./rom/phonebookservices.iby                CORE_APP_LAYER_IBY_EXPORT_PATH(phonebookservices.iby)" \
      "./rom/phonebook.iby                        CORE_APP_LAYER_IBY_EXPORT_PATH(phonebook.iby)" \
      "./rom/phonebookresources.iby               LANGUAGE_APP_LAYER_IBY_EXPORT_PATH(phonebookresources.iby)" 
-	 
+
+:BLD_INF_RULES.prj_exports += "conf/contacts.confml APP_LAYER_CONFML(contacts.confml)"
+:BLD_INF_RULES.prj_exports += "conf/contacts_2002FF54.crml APP_LAYER_CRML(contacts_2002FF54.crml)"
+:BLD_INF_RULES.prj_exports += "conf/contacts_200315A8.crml APP_LAYER_CRML(contacts_200315A8.crml)"
 exists(confml/phonebook.confml) :BLD_INF_RULES.prj_exports += "confml/phonebook.confml CONFML_EXPORT_PATH(phonebook.confml,uda_content)"
 exists(implml/phonebook.implml) :BLD_INF_RULES.prj_exports += "implml/phonebook.implml CRML_EXPORT_PATH(phonebook.implml,uda_content)"
 exists(content/SQLite__Contacts.zip) :BLD_INF_RULES.prj_exports += "content/SQLite__Contacts.zip CRML_EXPORT_PATH(../content/zip/,uda_content)"
--- a/phonebookui/rom/phonebook.iby	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/rom/phonebook.iby	Wed Jun 23 18:02:44 2010 +0300
@@ -34,6 +34,7 @@
 file=ABI_DIR\BUILD_DIR\cntmaptileservice.dll             SHARED_LIB_DIR\cntmaptileservice.dll UNPAGED
 file=ABI_DIR\BUILD_DIR\cntsimutility.dll            		SHARED_LIB_DIR\cntsimutility.dll UNPAGED
 file=ABI_DIR\BUILD_DIR\cntimageutility.dll            	SHARED_LIB_DIR\cntimageutility.dll UNPAGED
+file=ABI_DIR\BUILD_DIR\cntsettingsutility.dll            	SHARED_LIB_DIR\cntsettingsutility.dll UNPAGED
 
 // UI
 file=ABI_DIR\BUILD_DIR\pbkcommonui.dll                	SHARED_LIB_DIR\pbkcommonui.dll UNPAGED
@@ -49,5 +50,5 @@
 data=DATAZ_\CONTACTS_RESOURCE_DIR\cntmodel.rsc         CONTACTS_RESOURCE_DIR\cntmodel.rsc
 data=ZRESOURCE\hb\splashml\phonebook.splashml          RESOURCE_FILES_DIR\hb\splashml\phonebook.splashml
 data=ZRESOURCE\hb\splashml\phonebook.docml             RESOURCE_FILES_DIR\hb\splashml\phonebook.docml
-
+data=ZRESOURCE\qt\crml\cntmaptilepublisher.qcrml       RESOURCE_FILES_DIR\qt\crml\cntmaptilepublisher.qcrml
 #endif
\ No newline at end of file
--- a/phonebookui/rom/phonebookresources.iby	Fri Jun 11 13:29:23 2010 +0300
+++ b/phonebookui/rom/phonebookresources.iby	Wed Jun 23 18:02:44 2010 +0300
@@ -24,6 +24,5 @@
 data=DATAZ_\QT_TRANSLATIONS_DIR\contacts.qm     QT_TRANSLATIONS_DIR\contacts.qm
 
 S60_APP_RESOURCE(phonebook)
-data=DATAZ_/APP_RESOURCE_DIR/phonebook.mif      APP_RESOURCE_DIR/phonebook.mif  
 
 #endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/feedview.docml	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<hbdocument version="1.0">
+    <widget name="view" type="HbView">
+        <widget name="content" role="HbView:widget" type="HbWidget">
+            <widget name="textLabel" type="HbLabel">
+                <enums name="textWrapping" value="TextWordWrap"/>
+                <enums name="alignment" value="AlignVCenter|AlignHCenter"/>
+                <enums name="elideMode" value="ElideNone"/>
+                <string value="Presence feeder not active." name="plainText"/>
+                <fontspec name="fontSpec" role="Primary"/>
+            </widget>
+            <widget name="createContactsButton" type="HbPushButton">
+                <string value="Create contacts with accounts" name="text"/>
+            </widget>
+            <widget name="startButton" type="HbPushButton">
+                <string value="Start Presence feeder" name="text"/>
+            </widget>
+            <widget name="stopButton" type="HbPushButton">
+                <string locid="Stop Presence feeder" name="text"/>
+            </widget>
+            <layout orientation="Vertical" type="linear">
+                <linearitem itemname="createContactsButton"/>
+                <linearitem itemname="startButton"/>
+                <linearitem itemname="stopButton"/>
+                <linearitem itemname="textLabel"/>
+            </layout>
+        </widget>
+        <string name="title" value="Presence feed demo"/>
+    </widget>
+    <metadata activeUIState="Common ui state" display="NHD portrait" unit="un">
+        <uistate name="Common ui state" sections="#common"/>
+    </metadata>
+</hbdocument>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/inc/feedview.h	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,62 @@
+/*
+ * 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:
+ *
+ */
+
+#ifndef FEEDVIEW_H
+#define FEEDVIEW_H
+
+#include <QObject>
+#include <hbview.h>
+#include <qtcontacts.h>
+#include <hbdocumentloader.h>
+
+class PrcPresenceWriter;
+class PrcPresenceReader;
+class HbView;
+class QTimer;
+
+QTM_USE_NAMESPACE
+
+class FeedView : public QObject
+{
+    Q_OBJECT
+public:
+    FeedView(QObject *parent = 0);
+    ~FeedView();
+
+    HbView* view() const { return mView; }
+
+private slots:
+    void startPressed();
+    void stopPressed();
+    void createPressed();
+
+    void updateRandomPresence();
+	
+private: //data
+    HbView*          mView;
+    PrcPresenceWriter*  iWriter;
+    PrcPresenceReader*  iReader;
+    QContactManager* mManager;
+    QTimer*          mUpdateTimer;
+    HbDocumentLoader mDocumentLoader;
+
+    QStringList      mBuddyList;
+
+    bool             mStarted;
+};
+
+#endif /* FEEDVIEW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/presencefeeddemo.qrc	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RCC>
+    <qresource prefix="/xml" >
+        <file alias="feedview.docml">feedview.docml</file>
+    </qresource>
+</RCC>
Binary file presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/presencefeeddemo.sisx has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/presencefeeddemo_qt.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,47 @@
+#
+# 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:
+#
+#
+
+TEMPLATE = app
+TARGET = presencefeeddemo
+CONFIG += hb
+
+DEPENDPATH += .
+INCLUDEPATH += inc
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+
+MOC_DIR = moc
+
+LIBS += -lqtcontacts \
+        -lpresencecacheqt
+
+# Input
+HEADERS += inc/feedview.h
+
+SOURCES += src/main.cpp
+SOURCES += src/feedview.cpp
+
+RESOURCES += presencefeeddemo.qrc
+
+# capability
+TARGET.CAPABILITY = CAP_APPLICATION
+    
+symbian: {
+        TARGET.EPOCSTACKSIZE = 0x14000
+        TARGET.EPOCHEAPSIZE = 0x1000 0xA00000 
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/src/feedview.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,198 @@
+/*
+ * 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:
+ *
+ */
+
+#include "feedview.h"
+
+#include <hbpushbutton.h>
+#include <hblabel.h>
+#include <hbmainwindow.h>
+
+#include <QTimer>
+
+#include <prcpresencebuddyinfo_qt.h>
+#include <prcpresencereader_qt.h>
+#include <prcpresencewriter_qt.h>
+
+FeedView::FeedView(QObject *parent):
+    QObject(parent),
+    mView(NULL),
+    iWriter(NULL),
+    iReader(NULL),
+    mManager(NULL),
+    mUpdateTimer(NULL),
+    mStarted(false)
+{
+    bool ok = false;
+    mDocumentLoader.load(":/xml/feedview.docml", &ok);
+
+    if (ok)
+    {
+        mView = static_cast<HbView*>(mDocumentLoader.findWidget(QString("view")));
+    }
+    else
+    {
+        qFatal("Unable to read :/xml/feedview.docml");
+    }
+
+    HbPushButton *create = static_cast<HbPushButton*>(mDocumentLoader.findObject("createContactsButton"));
+    connect(create, SIGNAL(clicked()), this, SLOT(createPressed()));
+
+    HbPushButton *start = static_cast<HbPushButton*>(mDocumentLoader.findObject("startButton"));
+    connect(start, SIGNAL(clicked()), this, SLOT(startPressed()));
+
+    HbPushButton *stop = static_cast<HbPushButton*>(mDocumentLoader.findObject("stopButton"));
+    connect(stop, SIGNAL(clicked()), this, SLOT(stopPressed()));
+
+    iWriter = PrcPresenceWriter::createWriter();
+    iReader = PrcPresenceReader::createReader();
+
+    mManager = new QContactManager("symbian");
+
+    mUpdateTimer = new QTimer();
+    mUpdateTimer->setInterval(2000);
+    connect(mUpdateTimer, SIGNAL(timeout()), this, SLOT(updateRandomPresence()));
+}
+
+FeedView::~FeedView()
+{
+    delete mView;
+    delete iWriter;
+    delete iReader;
+	delete mManager;
+    delete mUpdateTimer;
+}
+
+void FeedView::startPressed()
+{
+    if (!mStarted)
+	{
+        static_cast<HbPushButton*>(mDocumentLoader.findObject("createContactsButton"))->setEnabled(false);
+
+        HbMainWindow* window = mView->mainWindow();
+        window->setInteractive(false);
+        HbLabel *label = static_cast<HbLabel*>(mDocumentLoader.findObject("textLabel"));
+        label->setPlainText("Presence feeder active.");
+    
+        QContactDetailFilter filter;
+        filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
+        QString typeContact = QContactType::TypeContact;
+        filter.setValue(typeContact);
+    
+        QList<QContactLocalId> contacts = mManager->contactIds(filter);
+    
+        foreach (QContactLocalId id, contacts)
+        {
+            QContact contact = mManager->contact(id);
+    
+            QList<QContactOnlineAccount> accounts = contact.details<QContactOnlineAccount>();
+    
+            foreach (QContactOnlineAccount account, accounts)
+            {
+                PrcPresenceBuddyInfoQt* buddy = PrcPresenceBuddyInfoQt::createInstance();
+                
+                QString fullAccount = account.serviceProvider() + ':' + account.accountUri();
+                buddy->setIdentity(fullAccount);
+                mBuddyList.append(fullAccount);
+                
+                if (qrand() % 2 == 0)
+                {
+                    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcNotAvailable, "hep");
+                }
+                else
+                {
+                    buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcAvailable, "hep");
+                }
+                iWriter->writePresence( *buddy );
+                
+                delete buddy;
+            }
+        }
+
+        window->setInteractive(true);
+        mUpdateTimer->start();
+        mStarted = true;
+    }
+}
+
+void FeedView::stopPressed()
+{
+    HbLabel *label = static_cast<HbLabel*>(mDocumentLoader.findObject("textLabel"));
+    label->setPlainText("Presence feeder not active.");
+    mBuddyList.clear();
+    mUpdateTimer->stop();
+    mStarted = false;
+    static_cast<HbPushButton*>(mDocumentLoader.findObject("createContactsButton"))->setEnabled(true);
+}
+
+void FeedView::createPressed()
+{
+    QContact c;
+    QContactName name;
+    name.setFirstName("sip");
+    name.setLastName("test");
+    c.saveDetail(&name);
+    QContactPhoneNumber number;
+    number.setNumber("1234567");
+    number.setContexts(QContactDetail::ContextHome);
+    number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+    c.saveDetail(&number);
+    QContactOnlineAccount account;
+    account.setSubTypes(QStringList() << QContactOnlineAccount::SubTypeSip);
+    account.setServiceProvider("sip");
+    account.setAccountUri("test@test.com");
+    c.saveDetail(&account);
+    mManager->saveContact(&c);
+
+    QContact c2;
+    QContactName name2;
+    name2.setFirstName("two");
+    name2.setLastName("accounts");
+    c2.saveDetail(&name2);
+    QContactOnlineAccount account2;
+    account2.setSubTypes(QStringList() << QContactOnlineAccount::SubTypeImpp);
+    account2.setServiceProvider("yahoo");
+    account2.setAccountUri("test@yahoo.com");
+    c2.saveDetail(&account2);
+    QContactOnlineAccount account3;
+    account3.setSubTypes(QStringList() << QContactOnlineAccount::SubTypeImpp);
+    account3.setServiceProvider("msn");
+    account3.setAccountUri("test@msn.com");
+    c2.saveDetail(&account3);
+    mManager->saveContact(&c2);
+
+    HbLabel *label = static_cast<HbLabel*>(mDocumentLoader.findObject("textLabel"));
+    label->setPlainText("Contacts created.");
+}
+
+void FeedView::updateRandomPresence()
+{
+    int random = qrand() % mBuddyList.count();
+
+    PrcPresenceBuddyInfoQt* buddy = iReader->presenceInfo(mBuddyList.at(random));
+    
+    if (qrand() % 2 == 0)
+    {
+        buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcNotAvailable, "hep");
+    }
+    else
+    {
+        buddy->setAvailability(PrcPresenceBuddyInfoQt::PrcAvailable, "hep");
+    }
+    iWriter->writePresence( *buddy );
+    
+    delete buddy;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencecache/presencecacheqt/tsrc/presencefeeddemo_qt/src/main.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,36 @@
+/*
+* 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:
+*
+*/
+
+#include <hbapplication.h>
+#include <hbmainwindow.h>
+#include "feedview.h"
+
+int main(int argc, char **argv)
+{
+
+    HbApplication a( argc, argv );
+    
+    HbMainWindow mainWindow(NULL, Hb::WindowFlagTransparent);
+	FeedView feedView;
+	mainWindow.addView(feedView.view());
+	mainWindow.setCurrentView(feedView.view());
+
+    mainWindow.show();
+
+    return a.exec();
+}
+
--- a/qtcontactsmobility/config.tests/occ/occ.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/config.tests/occ/occ.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -8,7 +8,7 @@
 TARGET = 
 DEPENDPATH += 
 INCLUDEPATH += .
-INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE 
 
 SOURCES += main.cpp
 
--- a/qtcontactsmobility/config.tests/sensors_s60_31/sensors_s60_31.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/config.tests/sensors_s60_31/sensors_s60_31.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -4,6 +4,6 @@
 # Input
 SOURCES += main.cpp
 
-#INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
 LIBS += -lRRSensorApi
 
--- a/qtcontactsmobility/plugins/contacts/symbian/inc/cntdisplaylabel.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/inc/cntdisplaylabel.h	Wed Jun 23 18:02:44 2010 +0300
@@ -44,6 +44,7 @@
 
 #include <QObject>
 #include <QLatin1String>
+#include <e32base.h>
 
 #include <qcontactmanager.h>
 #include <qcontact.h>
@@ -53,6 +54,57 @@
 
 QTM_USE_NAMESPACE
 
+class CRepository;
+class CntDisplayLabel;
+
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+#include <centralrepository.h>
+
+// CONSTANTS
+// Please keep this in sync with the values in the system header file <cntuids.h>
+// We cannot include this system header file because it is owned by an app layer
+// package (Contacts package). This being a mw layer, the dependency is not allowed
+const TUid KCRUiContacts = {0x2002FF54};
+const TUint32 KCntNameOrdering = 0x00000001;
+
+// name order enumerations
+// Please keep this in sync with <cntuids.h> See above comments
+enum NameOrder {
+    CntOrderLastFirst = 0x0,
+    CntOrderLastCommaFirst = 0x1,
+    CntOrderFirstLast = 0x2
+};
+
+/**
+ * This class is used to listen to central repository value changes
+ * of Contacts app settings. It is also used to get key values for
+ * name ordering
+ */
+class CntCenrep : public CActive
+{
+public:
+    CntCenrep(TUint32 aKey, CntDisplayLabel& aDisplayLabel );
+    ~CntCenrep();
+ 
+public:
+    int getValue();
+
+private:
+    void RunL();
+    TInt RunError(TInt aError);
+    void DoCancel();
+
+private:
+    CRepository*                iCenrep;
+    CntDisplayLabel*            iDisplayLabel;
+    const TUint32               iKey;
+    int                         iValue;
+};
+
+#else
+class CntCenrep;
+#endif
+
 class CntDisplayLabel : public QObject
 {
     Q_OBJECT
@@ -61,11 +113,17 @@
     CntDisplayLabel();
     virtual ~CntDisplayLabel();
 
-    QString synthesizedDisplayLabel( const QContact& contact, QContactManager::Error* error) const;
-    QString unNamned() const;
+    QString synthesizedDisplayLabel( const QContact& contact, QContactManager::Error* error);
     QList<QPair<QLatin1String, QLatin1String> > contactFilterDetails() const;
     QList<QPair<QLatin1String, QLatin1String> > groupFilterDetails() const;
     
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    void updateNameOrdering();
+#endif
+
+signals:
+    void displayLabelChanged();
+    
 private:
     void setDisplayLabelDetails();
     QString generateDisplayLabel( const QContact &contact, const QList<QList<QPair<QLatin1String, QLatin1String> > > detailList) const;
@@ -75,6 +133,7 @@
 private:
     QList<QList<QPair<QLatin1String, QLatin1String> > > m_contactDisplayLabelDetails;
     QList<QList<QPair<QLatin1String, QLatin1String> > > m_groupDisplayLabelDetails;
+    CntCenrep* m_settings;
     int m_nameOrder;
 };
 
--- a/qtcontactsmobility/plugins/contacts/symbian/inc/filtering/cntsymbiansrvconnection.h	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/inc/filtering/cntsymbiansrvconnection.h	Wed Jun 23 18:02:44 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,16 @@
                                           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);
 
 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);
+    void readContactsToBufferL(const TDesC& aSqlQuery, QueryType aQueryType);
     void ConnectSrvL();
     void OpenDatabaseL();
     TVersion Version() const;
--- a/qtcontactsmobility/plugins/contacts/symbian/src/cntdisplaylabel.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/cntdisplaylabel.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -41,20 +41,19 @@
 
 #include "cntdisplaylabel.h"
 #include <qtcontacts.h>
-#include <centralrepository.h>
-#include <cntcenrepkeys.h>
-
-const TUint32 KOrderLastFirst = 0x00000000;
-const TUint32 KOrderLastCommaFirst = 0x00000001;
-const TUint32 KOrderFirstLast = 0x00000002;
 
 /*! 
  * Constructor
  */
 
 CntDisplayLabel::CntDisplayLabel() :
-    m_nameOrder(KOrderFirstLast)
+m_settings(NULL),
+m_nameOrder(CntOrderFirstLast)
 {
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    m_settings = new CntCenrep(KCntNameOrdering, *this);
+    m_nameOrder = m_settings->getValue();
+#endif
     setDisplayLabelDetails();
 }
 
@@ -63,6 +62,7 @@
  */
 CntDisplayLabel::~CntDisplayLabel()
 {
+    delete m_settings;
 }
 
 /*! 
@@ -80,15 +80,19 @@
     //Display label details
     //Contact
     //Preferred details
+    m_contactDisplayLabelDetails.clear();
+    m_groupDisplayLabelDetails.clear();
     QList<QPair<QLatin1String, QLatin1String> > contactPrefferedDisplayLabelDetails;
     QLatin1String firstLatin(QContactName::FieldFirstName);
     QLatin1String secondLatin(QContactName::FieldLastName);
     
-    if (m_nameOrder == KOrderLastFirst || m_nameOrder == KOrderLastCommaFirst) {
+#ifdef SYMBIAN_BACKEND_USE_SQLITE    
+    if (m_nameOrder == CntOrderLastFirst || m_nameOrder == CntOrderLastCommaFirst) {
         firstLatin = QLatin1String(QContactName::FieldLastName);
         secondLatin = QLatin1String(QContactName::FieldFirstName);
     }
-
+#endif
+    
     contactPrefferedDisplayLabelDetails.append(qMakePair(QLatin1String(QContactName::DefinitionName), firstLatin));
     contactPrefferedDisplayLabelDetails.append(qMakePair(QLatin1String(QContactName::DefinitionName), secondLatin));
     m_contactDisplayLabelDetails.append(contactPrefferedDisplayLabelDetails);
@@ -110,11 +114,18 @@
  * \a error On return, contains the possible error.
  * \return synthesised display label 
  */
-QString CntDisplayLabel::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error) const
+QString CntDisplayLabel::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error)
 {
     QString displayLabel;
     *error = QContactManager::NoError;
     
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+    int value = m_settings->getValue();
+    if (value != -1 && value != m_nameOrder) {
+        m_nameOrder = value;
+        setDisplayLabelDetails();
+    }
+#endif
     //contact
     if(contact.type() == QContactType::TypeContact) {
         displayLabel = generateDisplayLabel(contact, m_contactDisplayLabelDetails);    
@@ -141,6 +152,8 @@
  */
 QString CntDisplayLabel::generateDisplayLabel( const QContact &contact, const QList<QList<QPair<QLatin1String, QLatin1String> > > detailList) const
 {
+    // Default to empty display label. It is up to the client to create a
+    // localised presentation of a contact without a name.
     QString displayLabel("");
     
     //loop through the details and create display label
@@ -162,7 +175,7 @@
                 if(!label.isEmpty())
                 {
                     // Inlcude a comma if needed in the display label
-                    if (m_nameOrder == KOrderLastCommaFirst)
+                    if (m_nameOrder == CntOrderLastCommaFirst)
                         displayLabel.append(comma());
                     displayLabel.append(delimiter());                        
                     displayLabel.append(label);
@@ -170,13 +183,6 @@
             }
         }
     }
-
-    //no display label, set default value
-    if(displayLabel.isEmpty())
-    {
-        //should the unnamned be read from somewhere?
-        displayLabel = unNamned();
-    }
     
     return displayLabel;
 }
@@ -192,14 +198,6 @@
 }
 
 /*!
- * return the name used for unknown contacts
- */
-QString CntDisplayLabel::unNamned() const
-{
-    return "Unnamed";
-}
-
-/*!
  * Returns the details to be used for contact filtering
  */
 QList<QPair<QLatin1String, QLatin1String> > CntDisplayLabel::contactFilterDetails() const
@@ -223,3 +221,71 @@
 {
     return ",";
 }
+
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+
+void CntDisplayLabel::updateNameOrdering()
+{
+    emit displayLabelChanged();
+}
+
+CntCenrep::CntCenrep(const TUint32 aKey, CntDisplayLabel& aDisplayLabel) :
+    CActive(EPriorityStandard),
+    iCenrep(NULL),
+    iDisplayLabel(&aDisplayLabel),
+    iKey(aKey)
+{   
+    TRAPD(error, iCenrep = CRepository::NewL(KCRUiContacts));
+    
+    if ( error == KErrNone ) {
+        CActiveScheduler::Add(this);
+        
+        // initial subscription and process current property value
+        iCenrep->NotifyRequest(iKey, iStatus );
+        SetActive();
+    }
+    
+    iValue = getValue();
+}
+
+CntCenrep::~CntCenrep()
+{
+    Cancel();
+    delete iCenrep;
+}
+
+int CntCenrep::getValue()
+{    
+    TInt value;
+    if (iCenrep && iCenrep->Get(iKey, value) == KErrNone) {
+        return value;
+    } else {
+        return -1;
+    }
+}
+
+void CntCenrep::DoCancel()
+{
+    if (iCenrep)
+        iCenrep->NotifyCancel(iKey);
+}
+
+TInt CntCenrep::RunError(TInt aError)
+{
+    return aError;
+}
+
+void CntCenrep::RunL()
+{
+    // resubscribe before processing new value to prevent missing updates
+    iCenrep->NotifyRequest(iKey, iStatus );
+    SetActive();
+    
+    int value = getValue();
+    if (value != -1 && value != iValue) {
+        iValue = value;
+        iDisplayLabel->updateNameOrdering();
+    }
+}
+
+#endif
--- a/qtcontactsmobility/plugins/contacts/symbian/src/cntsymbianengine.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/cntsymbianengine.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -50,7 +50,6 @@
 #include <driveinfo.h>
 
 #include <qtcontacts.h>
-#include <qcontactname.h>
 
 #include "cntsymbianengine.h"
 #include "qcontactchangeset.h"
@@ -111,6 +110,9 @@
 #endif
         m_relationship     = new CntRelationship(m_dataBase->contactDatabase(), m_managerUri);
         m_displayLabel     = new CntDisplayLabel();
+#ifdef SYMBIAN_BACKEND_USE_SQLITE
+        connect(m_displayLabel, SIGNAL(displayLabelChanged()), this, SIGNAL(dataChanged()));
+#endif
     }
 }
 
@@ -148,6 +150,11 @@
         // Remove possible false positives
         if(!filterSupported && *error == QContactManager::NotSupportedError)
             {
+            //fetch all contacts
+            *error = QContactManager::NoError;
+            result = m_contactFilter->contacts(QContactFilter(),sortOrders, filterSupported, error);
+            
+            //slow filtering
             result = slowFilter(filter, result, error);
             
             //slow sorting until it's supported in SQL requests
@@ -168,7 +175,7 @@
             }
         }
 #endif
-
+    
     return result;
 }
 
@@ -241,13 +248,14 @@
             QContactManagerEngine::setContactRelationships(contact, relationships);
         }
     }
+    
     return *QScopedPointer<QContact>(contact);
 }
 
 bool CntSymbianEngine::saveContact(QContact* contact, QContactManager::Error* error)
 {
     QContactChangeSet changeSet;
-    TBool ret = doSaveContact(contact, changeSet, error);
+    bool ret = doSaveContact(contact, changeSet, error);
     changeSet.emitSignals(this);
     return ret;
 }
@@ -865,6 +873,12 @@
         return false;
     }
 
+    QContactManager::Error e;
+    QContactLocalId selfCntId = selfContactId( &e ); // err ignored
+   
+    QContactChangeSet changeSet;
+    QOwnCardPair ownCard(selfCntId, contactId);
+    
     TContactItemId id(contactId);
     CContactItem* symContact = 0;
     TRAPD(err,
@@ -872,6 +886,15 @@
         m_dataBase->contactDatabase()->SetOwnCardL(*symContact);
         );
     delete symContact;
+    
+    if(err == KErrNone)
+       {
+       m_dataBase->appendContactEmitted(id);
+       
+       changeSet.setOldAndNewSelfContactId(ownCard);
+       changeSet.emitSignals( this );
+       }
+    
     CntSymbianTransformError::transformError(err, error);
     return (err==KErrNone);
 }
--- a/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntdbinfo.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntdbinfo.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -52,7 +52,7 @@
     contactsTableIdColumNameMapping.insert(id.arg(QContactOrganization::DefinitionName, QContactOrganization::FieldName), "company_name");
     contactsTableIdColumNameMapping.insert(id.arg(QContactName::DefinitionName, QContactName::FieldCustomLabel), "text_fields");
 
-    commAddrTableIdColumNameMapping.insert(id.arg(QContactOnlineAccount::DefinitionName, QContactOnlineAccount::FieldSubTypes), QPair<int,bool>(ESipAddress,true));
+    commAddrTableIdColumNameMapping.insert(id.arg(QContactOnlineAccount::DefinitionName, QContactOnlineAccount::FieldAccountUri), QPair<int,bool>(ESipAddress,false));
     commAddrTableIdColumNameMapping.insert(id.arg(QContactEmailAddress::DefinitionName, QContactEmailAddress::FieldEmailAddress), QPair<int,bool>(EEmailAddress,false));
     commAddrTableIdColumNameMapping.insert(id.arg(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldSubTypes), QPair<int,bool>(EPhoneNumber,true));
 }
--- a/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntfilterdetail.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntfilterdetail.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -255,26 +255,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
--- a/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsqlsearch.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsqlsearch.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -104,11 +104,11 @@
 //  "0010023004560" -> tokens "001" and "23004560")
 //
 // 6: "10", "1000"
-// Two tokens, last token ends zero.
+// One token, ends with zero.
 // In this case, query should look-up first toke and number ("10", "1000").
 
 QString CntSqlSearch::CreatePredictiveSearch(const QString &pattern)
-	{
+	{    
 	int len = pattern.length();
         QString newPattern = ChangeStringPadings(pattern);
 	// For best performance, handle 1 digit case first
@@ -246,29 +246,29 @@
 // pattern length is between KMinimumSearchPatternLength...KLimitLength
 QString CntSqlSearch::CreateQuery(const QString& pattern) const
 	{
-        QStringList tokens = GetTokens(pattern);
+	QStringList tokens = GetTokens(pattern);
 	if (tokens.count() < KTwoTokens)
+        {
+	    if (TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken))
             {
-            if( TestPattern(pattern, CntSqlSearch::ZerosEndOfFirstToken))
-                {
-                return TwoDifferentTokensSearch(pattern, tokens);  // Case 6
-                }
-            else
-                {
-                return ExactMatchSearch(pattern) + Order(tokens); // Case 2
-                }
+            return TwoDifferentTokensSearch(pattern, tokens);  // Case 6
+            }
+        else
+            {
+            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
-                }
+        {
+        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
@@ -325,8 +325,8 @@
 // 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:
+// In this case the limits are 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
@@ -503,7 +503,7 @@
 	//
 	// 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))
+	//      NOT(N3>lower && < N3<upper) AND NOT(N4>lower && < N4<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
--- a/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsymbianfiltersql.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsymbianfiltersql.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -98,6 +98,9 @@
         ids = ( m_filterMap.value(filter.type()))->contacts(filter,sortOrders,filterSupported,error);
         return ids;   
     }
+    else {
+        filterSupported = false;
+    }
     *error = QContactManager::NotSupportedError;
     return ids;
 }
--- a/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsymbiansrvconnection.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/src/filtering/cntsymbiansrvconnection.cpp	Wed Jun 23 18:02:44 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,30 @@
 {
     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;
 }
 
 /*!
+ * 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 +171,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;
@@ -177,7 +195,7 @@
  */
 QList<QContact> CntSymbianSrvConnection::searchContactNamesL(const TDesC& aSqlQuery)
 {
-    readContactsToBufferL(aSqlQuery);
+    readContactsToBufferL(aSqlQuery, CntSymbianSrvConnection::CntSearchResultList);
 
     RBufReadStream readStream;
     QList<QContact> contacts;
@@ -230,7 +248,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,12 +260,12 @@
     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));
     }
 }
 
--- a/qtcontactsmobility/plugins/contacts/symbian/symbian.pro	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/plugins/contacts/symbian/symbian.pro	Wed Jun 23 18:02:44 2010 +0300
@@ -13,7 +13,7 @@
     TARGET.UID3 = 0x2002AC7B
   
     INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE
-  
+	
     INCLUDEPATH += inc
     INCLUDEPATH += rss
     INCLUDEPATH += $$SOURCE_DIR/contacts
@@ -61,7 +61,7 @@
         inc/filtering/cntfilterdefault.h \
         inc/filtering/cntfilterintersection.h \
         inc/filtering/cntfilterunion.h \   				
-				inc/filtering/cntabstractcontactsorter.h \
+        inc/filtering/cntabstractcontactsorter.h \
         inc/filtering/cntabstractcontactfilter.h \
         inc/filtering/cntsymbianfilterdbms.h \
         inc/filtering/cntsymbianfiltersql.h \
--- a/qtcontactsmobility/src/versit/qversitresourcehandler.cpp	Fri Jun 11 13:29:23 2010 +0300
+++ b/qtcontactsmobility/src/versit/qversitresourcehandler.cpp	Wed Jun 23 18:02:44 2010 +0300
@@ -132,8 +132,7 @@
     if (location.isEmpty())
         return false;
     QFile file(location);
-    file.open(QIODevice::ReadOnly);
-    if (!file.isReadable())
+    if (!file.open(QIODevice::ReadOnly) || !file.isReadable())
         return false;
     *contents = file.readAll();
     return contents->size() > 0;