browserutilities/favouritesengine/ClientServer/srvsrc/FavouritesSrvDb.cpp
changeset 0 dd21522fd290
child 36 0ed94ceaa377
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browserutilities/favouritesengine/ClientServer/srvsrc/FavouritesSrvDb.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,2169 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 of class CFavouritesSrvDb
+*      
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <s32std.h>
+#include <eikenv.h>
+#include <rfsApMapper.h>
+#include <commdb.h>
+#include "FavouritesSrvDb.h"
+#include "FavouritesSrvTable.h"
+#include "FavouritesItemImpl.h"
+#include "FavouritesItemImplList.h"
+#include "FavouritesPanic.h"
+#include "FavouritesLimits.h"
+#include "FavouritesItemData.h"
+#include "FavouritesFilter.h"
+#include "UidMap.h"
+#include "FavouritesLogger.h" 
+#include "FavouritesFolder.h"
+
+
+
+// CONSTANTS
+
+/// Uid list granularity.
+LOCAL_D const TInt KUidListGranularity = 4;
+/// Postfix list granularity.
+LOCAL_D const TInt KPostfixListGranularity = 4;
+/// Number of updates needed to trigger automatic compaction.
+LOCAL_D const TInt KUpdatesNeededForAutoCompact = 32;
+/// Length of filename: 8 char.
+LOCAL_D const TInt KFnameLength = 8;
+
+// Secure policy ID of the Faveng database files.
+LOCAL_D const TUint KUidFavengDbPolicy = 0x101FD685;
+
+
+// ==================== LOCAL FUNCTIONS ====================
+
+/**
+* Given aName in the format <prefix> or <prefix><integer in parenthesis>,
+* return a pointer to the leading part. That is, if there is trailing
+* <integer in  parenthesis>, then that is excluded; if there is no trailing
+* part, then the original decriptor is returned.
+* Examples:
+*   - "Foo" returns "Foo";
+*   - "Foo(12)" returns "Foo";
+*   - "Foo(12 34)" returns "Foo(12 34)";
+*
+* @param aName Name to get prefix from.
+* @return Pointer to prefix part.
+*/
+LOCAL_C TPtrC GetPrefix( const TDesC& aName )
+    {
+    TPtrC prefix = aName;
+    TInt length = aName.Length();
+    if ( length >= 3 && aName[length - 1] == ')' )
+        {
+        // Any name shorter than 3 chars cannot have a postfix.
+        TInt openPar = aName.LocateReverse('(');
+        if ( openPar != KErrNotFound )
+            {
+            // aName looks like "<prefix>(<something>)".
+            // See if <something> is an integer number.
+            TPtrC num = aName.Mid( openPar + 1, length - openPar - 2);
+            TInt val;
+            TLex lex( num );
+            if ( lex.Val( val ) == KErrNone )
+                {
+                // Yes, the trailer is a parenthesized integer.
+                prefix.Set( aName.Left( openPar ) );
+                }
+            }
+        }
+    return prefix;
+    }
+
+/**
+* If aName is constructed from aPrefix with a positive integer postfix,
+* get the numeric value of the postfix, e.g:
+*   - GetPostfix( "Foo(3)", "Foo" ) == 3
+* If aName is the same as aPrefix, return 0, e.g.:
+*   - GetPostfix( "Foo", "Foo" ) == 0
+* If aName is not constructed from aPrefix, return -1, e.g.:
+*   - GetPostfix( "Foobar", "Foo" ) == -1
+*   - GetPostfix( "Foo(23 45)", "Foo" ) == -1
+* If postfix is 0 or negative, return -1, e.g.:
+*   - GetPostfix( "Foo(00)", "Foo" ) == -1
+*   - GetPostfix( "Foo(-8)", "Foo" ) == -1
+*
+* Return values for the following cases cannot be differentiated (-1 for all):
+* - postfix is 0;
+* - postfix is negative;
+* - aName not constructed from aPrefix.
+*
+* @param aName Name to get postfix from.
+* @param aPrefix Prefix to be searched.
+* @return Postfix value.
+*/
+LOCAL_C TInt GetPostfix( const TDesC& aName, const TDesC& aPrefix )
+    {
+    TInt postfix = -1;
+    TInt nameLength = aName.Length();
+    TInt prefixLength = aPrefix.Length();
+    if ( nameLength >= prefixLength && aName.FindF( aPrefix ) == 0 )
+        {
+        // aName is longer or equal length, and
+        // aPrefix can be found in the beginning of aName.
+        if ( nameLength == prefixLength )
+            {
+            // They have the same length; they equal.
+            postfix = 0;
+            }
+        else if (
+                nameLength - prefixLength >= 3 &&   // Because of this...
+                aName[prefixLength] == '(' &&
+                aName[nameLength - 1] == ')'        // ... this is safe (*)
+                )
+            {
+            // (*) "aName[nameLength - 1]" no need to check whether this
+            // index is valid. nameLength is at least 3 characters longer
+            // than prefixLength (a positive integer) -> nameLength >= 3.
+
+            // aName looks like "aPrefix(<something>)".
+            // See if <something> is an integer number.
+            TPtrC num = aName.Mid
+                ( prefixLength + 1, nameLength - prefixLength - 2 );    // (**)
+            // (**) These are also safe because nameLength - prefixLength >= 3.
+            TInt val;
+            TLex lex( num );
+            if ( lex.Val( val ) == KErrNone && val > 0)
+                {
+                // Yes, the trailer is a positive integer.
+                postfix = val;
+                }
+            }
+        }
+    return postfix;
+    }
+
+/**
+* Generate filename for uid: return number as 8 character hex string.
+* @param aUid Uid.
+* @param aName Filename returned here. Minimum length KFnameLength.
+*/
+LOCAL_C void FilenameForUid( TInt aUid, TDes& aName )
+    {
+    __ASSERT_DEBUG( aName.MaxLength() >= KFnameLength, \
+        FavouritesPanic( EFavouritesInternal ) );
+    aName.NumFixedWidth( STATIC_CAST( TUint, aUid ), EHex, KFnameLength );
+    }
+
+/**
+* Get uid for filename; reverse of FilenameForUid.
+* @param aName Filename.
+* @return Uid or KFavouritesNullUid.
+*/
+LOCAL_C TInt UidForFilename( const TDesC& aName )
+    {
+    // Parse the supplied text as hex number.
+    TInt uid = KFavouritesNullUid;
+    if ( aName.Length() == KFnameLength )
+        {
+        // Length is OK, check contents.
+        TUint val;
+        TLex lex( aName );
+        if ( !lex.Val( val, EHex ) && lex.Eos() )
+            {
+            // OK, this filename can be parsed as hex TUint.
+            uid = STATIC_CAST( TInt, val );
+            }
+        }
+    return uid;
+    }
+
+// ================= MEMBER FUNCTIONS =======================
+
+
+// ---------------------------------------------------------
+// CBookmarkSrvDb::NewL
+// ---------------------------------------------------------
+//
+CFavouritesSrvDb* CFavouritesSrvDb::NewL
+( RFs& aFs, RDbs& aDbs, const TDesC& aPath, const TDesC& aDBName )
+    {
+    CFavouritesSrvDb* db = new (ELeave) CFavouritesSrvDb( aFs, aDbs );
+    CleanupStack::PushL( db );
+    db->ConstructL( aPath , aDBName );
+    CleanupStack::Pop();    // db
+    return db;
+    }
+
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::~CFavouritesSrvDb
+// ---------------------------------------------------------
+//
+CFavouritesSrvDb::~CFavouritesSrvDb()
+    {
+    if ( iOpen )
+        {
+        if ( iInTransaction )
+            {
+            Rollback();
+            }
+        TRAP_IGNORE( DeleteOrphanedFilesL() );
+        // TODO move compacting to server side, when last client exits.
+        (void)iDatabase.Compact();  // Any error is silently ignored.
+        iDatabase.Close();
+        iOpen = EFalse;
+        }
+    delete iPath;   
+    delete iSavedFilePath;    
+    iSecureDbFormat.Close();
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::IsDamagedL
+// ---------------------------------------------------------
+//
+TBool CFavouritesSrvDb::IsDamagedL()
+    {
+    TBool damaged = EFalse;
+    // We must open a table to make RDbNameDatabase::IsDamaged() work!.
+    RFavouritesSrvTable table;
+    table.OpenL( iDatabase );
+    damaged = iDatabase.IsDamaged();
+    table.Close();
+    return damaged;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::RecoverL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::RecoverL()
+    {
+    User::LeaveIfError( iDatabase.Recover() );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CompactL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::CompactL()
+    {
+    User::LeaveIfError( iDatabase.Compact() );
+    iUpdatesSinceLastCompact = 0;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::Size
+// ---------------------------------------------------------
+//
+RDbDatabase::TSize CFavouritesSrvDb::Size() const
+    {
+    return iDatabase.Size();
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::UpdateStatsL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::UpdateStatsL()
+    {
+    User::LeaveIfError( iDatabase.UpdateStats() );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::BeginL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::BeginL( TBool aWrite /*=EFalse*/ )
+    {
+    __ASSERT_DEBUG( !iInTransaction, \
+        FavouritesPanic( EFavouritesNestedTransaction ) );
+
+    // Three parts: table open + transacion + (optional) write lock.
+    // Temp use of cleanup items make the three atomic.
+    iTable.OpenL( iDatabase );
+    CleanupClosePushL<RFavouritesSrvTable>( iTable );
+    User::LeaveIfError( iDatabase.Begin() );
+    iInTransaction = ETrue;
+    CleanupStack::PushL( TCleanupItem( StaticRollback, this ) );
+    if ( aWrite )
+        {
+        iTable.PutWriteLockL();
+        }
+    CleanupStack::Pop( 2 ); // Rollback, Closing iTable
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CommitL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::CommitL()
+    {
+    __ASSERT_DEBUG( iInTransaction, \
+        FavouritesPanic( EFavouritesNoTransaction ) );
+
+    User::LeaveIfError( iDatabase.Commit() );
+    iInTransaction = EFalse;
+    iTable.Close();
+    if ( iUpdatesSinceLastCompact > KUpdatesNeededForAutoCompact )
+        {
+        // Auto-compact, to avoid overgrowth.
+        TRAP_IGNORE( CompactL() );
+        }
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::Rollback
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::Rollback()
+    {
+    __ASSERT_DEBUG( iInTransaction, \
+        FavouritesPanic( EFavouritesNoTransaction ) );
+
+    iDatabase.Rollback();
+    iInTransaction = EFalse;
+    iTable.Close();
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::GetL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::GetL( TInt aUid, CFavouritesItemImpl& aItem )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.GetL();
+    iTable.ReadItemDataL( aItem );
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::GetAllL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::GetAllL
+( CFavouritesItemImplList& aItemList, const TFavouritesFilter& aFilter )
+    {
+    TBool ownTransaction;
+
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.SetFiltersL( aFilter );
+    CFavouritesItemImpl* item;
+    iTable.BeginningL();
+    while( iTable.NextL() )
+        {
+        item = CFavouritesItemImpl::NewLC();
+        iTable.GetL();
+        iTable.ReadItemDataL( *item );
+        aItemList.AppendL( item );
+        CleanupStack::Pop();    // item; owner is the list now.
+        }
+    iTable.ClearFilters();
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::PreferredUidL
+// ---------------------------------------------------------
+//
+TInt CFavouritesSrvDb::PreferredUidL( TInt aFolder )
+{
+    TInt uid( KFavouritesNullUid );
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    if ( iTable.SeekToUidL( aFolder ) )
+        {
+        iTable.GetL();
+        if ( iTable.Type() == CFavouritesItem::EFolder )
+            {
+            uid = iTable.PreferredUid();
+            }
+        }
+    CommitIfNeededL( ownTransaction );
+    return uid;
+}
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::GetUidsL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::GetUidsL
+( CArrayFix<TInt>& aUids, const TFavouritesFilter& aFilter )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.SetFiltersL( aFilter );
+    iTable.BeginningL();
+    while( iTable.NextL() )
+        {
+        iTable.GetL();
+        aUids.AppendL( iTable.Uid() );
+        }
+    iTable.ClearFilters();
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::DeleteL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::DeleteL( TInt aUid )
+    {
+    if ( aUid == KFavouritesRootUid || aUid == KFavouritesHomepageUid )
+        {
+        // Cannot delete these.
+        User::Leave( KErrAccessDenied );
+        }
+    // Make a list, to remember which items were deleted.
+    CArrayFix<TInt>* deletedUids =
+        new (ELeave) CArrayFixFlat<TInt>( KUidListGranularity );
+    CleanupStack::PushL( deletedUids );
+
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    DeleteCurrentL( *deletedUids );
+    CommitIfNeededL( ownTransaction );
+
+    // Delete associated files.
+    TInt i;
+    TBuf<KFnameLength> name;
+    TParse parse;
+    for ( i = 0; i < deletedUids->Count(); i++ )
+        {
+        FilenameForUid( deletedUids->At( i ), name );
+        User::LeaveIfError( parse.SetNoWild( name, iPath, NULL ) );
+        (void)iFs.Delete( parse.FullName() );
+        // Errors ignored; the file may be locked etc. etc.
+        // Orphaned file cleanup will remove them eventually.
+        }
+
+    CleanupStack::PopAndDestroy();  // deletedUids
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::UpdateL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::UpdateL
+( CFavouritesItemImpl& aItem, TInt aUid, TBool aAutoRename )
+    {
+    if ( aUid == KFavouritesRootUid ||
+         aUid == KFavouritesHomepageUid ||
+         aUid == KFavouritesLastVisitedUid )
+        {
+        // Cannot modify these.
+        // (Root cannot be modified at all; the others can be modified but
+        // not through this method.)
+        User::Leave( KErrAccessDenied );
+        }
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    UpdateCurrentL( aItem, aAutoRename ? EAutoRename : EDontRename );
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::AddL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::AddL( CFavouritesItemImpl& aItem, TBool aAutoRename )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    DoAddL( aItem, aAutoRename ? EAutoRename : EDontRename );
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetSpecialItemL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetSpecialItemL( CFavouritesItemImpl& aItem, TInt aUid )
+    {
+    __ASSERT_DEBUG( \
+        aUid == KFavouritesHomepageUid || aUid == KFavouritesLastVisitedUid, \
+        FavouritesPanic( EFavouritesInternal )
+        );
+
+    if ( aItem.ParentFolder() != KFavouritesRootUid )
+        {
+        // Must be in root.
+        User::Leave( KErrArgument );
+        }
+
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    if ( iTable.SeekToUidL( aUid ) )
+        {
+        UpdateCurrentL( aItem, ESuppressCheck );
+        }
+    else
+        {
+        DoAddL( aItem, ESuppressCheck );
+        // Cursor is still on the new record. Write uid back.
+        iTable.UpdateLC();
+        iTable.SetUidL( aUid );
+        iTable.PutL();
+        aItem.SetUid( aUid );                   // Get uid back.
+        aItem.SetModified( iTable.Modified() ); // Get modtime.
+        }
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetFactoryItemL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetFactoryItemL( TInt aUid, TBool aFactoryItem )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.UpdateLC();
+    iTable.SetFactoryItemL( aFactoryItem );
+    iTable.PutL();
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetReadOnlyL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetReadOnlyL( TInt aUid, TBool aReadOnly )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.UpdateLC();
+    iTable.SetReadOnlyL( aReadOnly );
+    iTable.PutL();
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetModifiedL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetModifiedL( TInt aUid, TTime aModified )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.UpdateLC();
+    iTable.SetModifiedL( aModified );
+    iTable.PutL( /*aTouch=*/ EFalse );
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetPreferredUidL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetPreferredUidL( TInt aFolder, TInt aUid )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aFolder );
+    iTable.GetL();
+    if ( iTable.Type() == CFavouritesItem::EFolder )
+        {
+        iTable.UpdateLC();
+        iTable.SetPreferredUidL( aUid );
+        iTable.PutL();
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::ItemExistsL
+// ---------------------------------------------------------
+//
+TBool CFavouritesSrvDb::ItemExistsL( TInt aUid )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    TBool res = iTable.SeekToUidL( aUid );
+    CommitIfNeededL( ownTransaction );
+    return res;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::FolderExistsL
+// ---------------------------------------------------------
+//
+TBool CFavouritesSrvDb::FolderExistsL( TInt aFolder )
+    {
+    TBool res = EFalse;
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    if ( iTable.SeekToUidL( aFolder ) )
+        {
+        iTable.GetL();
+        if ( iTable.Type() == CFavouritesItem::EFolder )
+            {
+            res = ETrue;
+            }
+        }
+    CommitIfNeededL( ownTransaction );
+    return res;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CountL
+// ---------------------------------------------------------
+//
+TInt CFavouritesSrvDb::CountL( const TFavouritesFilter& aFilter )
+    {
+    TInt count = 0;
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.SetFiltersL( aFilter );
+    // Get all items in the aFolder.
+    iTable.BeginningL();
+    while( iTable.NextL() )
+        {
+        count++;
+        }
+    iTable.ClearFilters();
+    CommitIfNeededL( ownTransaction );
+    return count;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetDataL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetDataL( TInt aUid, MStreamBuf& aSource )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.UpdateLC();
+    iTable.SetExtraDataL( aSource );
+    iTable.PutL();
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::GetDataL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::GetDataL( TInt aUid, MStreamBuf& aSink )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.GetL();
+    iTable.GetExtraDataL( aSink );
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetBrowserDataL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetBrowserDataL( TInt aUid, MStreamBuf& aSource )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/ETrue, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.UpdateLC();
+    iTable.SetBrowserDataL( aSource );
+    iTable.PutL();
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::GetBrowserDataL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::GetBrowserDataL( TInt aUid, MStreamBuf& aSink )
+    {
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    iTable.GetL();
+    iTable.GetBrowserDataL( aSink );
+    CommitIfNeededL( ownTransaction );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::MakeUniqueNameL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::MakeUniqueNameL( TDes& aName, TInt aFolder )
+    {
+    // Trim aName first.
+    HBufC* buf = HBufC::NewLC( aName.Length() + KFavouritesMaxPostfix );
+    TPtr ptr( buf->Des() );
+    CFavouritesItemImpl::MakeName( aName, ptr );
+
+    if ( !CFavouritesItemImpl::IsValidName( ptr ) )
+        {
+        User::Leave( KErrBadName ); // aName is invalid.
+        }
+
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    if ( !FolderExistsL( aFolder ) )
+        {
+        User::Leave( KErrArgument );    // No parent folder.
+        }
+
+    if ( !IsUniqueNameL( ptr, aFolder, KFavouritesNullUid ) )
+        {
+        MakeUniqueNameL( ptr, aFolder, KFavouritesNullUid );
+        }
+    // Always set it back, even if it was unique in the first place:
+    // It may be trimmed.
+    aName = ptr;
+
+    CommitIfNeededL( ownTransaction );
+    CleanupStack::PopAndDestroy();  // buf
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::RestoreFactorySettingsL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::RestoreFactorySettingsL
+( const TDesC& aReferenceDbPath, CUidMap& aApMap )
+    {
+    __ASSERT_DEBUG( InTransaction(), FavouritesPanic( EFavouritesInternal ) );
+    FLOG(( _L("restoer: FavoritesSvrDb.cpp CFavouritesSrvDb::RestoreFactorySettingsL") ));
+        
+    // Open a read-only database on the reference db (client-side access).
+    RDbNamedDatabase refDb;
+    
+    FLOG(( _L("CFavouritesSrvDb::RestoreFactorySettingsL before Leave call") ));    
+
+    RFs fsSession;
+    User::LeaveIfError(fsSession.Connect());
+    
+    CleanupClosePushL(fsSession);
+    User::LeaveIfError(refDb.Open(fsSession, aReferenceDbPath, TPtrC(), RDbNamedDatabase::EReadOnly));
+
+    FLOG(( _L("CFavouritesSrvDb::RestoreFactorySettingsL after Leave call") ));
+    CleanupClosePushL<RDbNamedDatabase>( refDb );
+    // Open a read-only table on the database.
+    RFavouritesSrvTable refTable;
+    refTable.OpenL( refDb, RDbRowSet::EReadOnly );
+    CleanupClosePushL<RFavouritesSrvTable>( refTable );
+    // No transaction needed - the database is opened read-only
+    // with exclusive access.
+    RestoreFactorySettingsL( refTable, aApMap );
+    CleanupStack::PopAndDestroy( 2 );   // close refTable, close refDb
+
+    CleanupStack::PopAndDestroy(); // close fsSession
+    }
+    
+
+// ---------------------------------------------------------
+// CFavouritesSession::InitSavedFilePathL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::InitSavedFilePathL( const TDesC&  aDBName )
+    {
+    TParse parse;
+    TDriveName cDrive = TDriveUnit( EDriveC ).Name();
+    TFileName path;
+    User::LeaveIfError( iFs.PrivatePath( path ) );
+    User::LeaveIfError( parse.SetNoWild( path, &cDrive, NULL ) );
+    parse.AddDir(aDBName);       
+    delete iSavedFilePath;
+	iSavedFilePath = NULL;
+
+    iSavedFilePath =  parse.FullName().AllocL();
+    iFs.CreatePrivatePath(EDriveC);
+    iFs.MkDirAll(*iSavedFilePath);    
+    }
+    
+    
+    
+// ---------------------------------------------------------
+// CFavouritesSrvDb::FilenameL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::FilenameL( TInt aUid, TParse& aParse )
+    {
+    // Check if item exists.
+    TBool ownTransaction;
+    BeginIfNeededL( /*aWrite=*/EFalse, ownTransaction );
+    iTable.GotoToUidL( aUid );
+    CommitIfNeededL( ownTransaction );
+    // Generate filename.
+    TBuf<KFnameLength> name;
+    FilenameForUid( aUid, name );
+    // Append filename to session path.
+    User::LeaveIfError( aParse.SetNoWild( name, iSavedFilePath, NULL ) );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CFavouritesSrvDb
+// ---------------------------------------------------------
+//
+CFavouritesSrvDb::CFavouritesSrvDb( RFs& aFs, RDbs& aDbs )
+: iFs( aFs ),
+  iDbs( aDbs ),
+  iOpen( EFalse ),
+  iInTransaction( EFalse ),
+  iUpdatesSinceLastCompact( 0 )
+    {
+    }
+
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::ConstructL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::ConstructL( const TDesC& aPath, const TDesC&  aDBName )
+    {
+    const TUid KDbPolicyUid = TUid::Uid(KUidFavengDbPolicy);
+    
+    iPath = aPath.AllocL();
+    
+    InitSavedFilePathL(aDBName );
+
+	_LIT( KSecureKeyword, "SECURE" );
+    iSecureDbFormat.CreateL( KSecureKeyword(), KSecureKeyword().Length() + 
+    	KDbPolicyUid.Name().Length() );
+	iSecureDbFormat += KDbPolicyUid.Name();
+    
+    // Check if we have the database.
+    TBool isDbExists = EFalse;
+    
+    CDbDatabaseNames *dbNames = iDbs.DatabaseNamesL(EDriveC, KDbPolicyUid);
+    
+    CleanupStack::PushL(dbNames);
+    
+    TParse dbFile;
+    User::LeaveIfError( dbFile.SetNoWild( aPath, NULL, NULL ) );
+    
+    for(int i = 0; i < dbNames->Count(); i++)
+    	{
+    	if( (*dbNames)[i] == dbFile.NameAndExt() )
+    		{
+    		isDbExists = ETrue;
+    		break;
+    		}
+    	}
+    
+    CleanupStack::PopAndDestroy(dbNames);
+    
+    if ( !isDbExists )
+        {
+        // No such database. Make it now.
+        TInt err = KErrNone;
+        TBool doImport = ( aDBName.Compare( KBrowserBookmarks ) == 0 );
+        TRAP( err, CreateDatabaseL( dbFile, doImport ) );
+
+        // Bookmark import failed. Create an empty DB
+        if ( err && doImport )
+        	{
+        	iDbs.DeleteDatabase( aPath, KDbPolicyUid );
+        	TRAP( err, CreateDatabaseL( dbFile, EFalse ) );
+        	}
+        if ( err )
+            {
+            // Should anything go wrong during the database creation,
+            // delete the database. This ensures that we never have
+            // half-constructed database (e.g. database created but no
+            // root folder because of leave). No data is lost by deleting
+            // the file; it has just been created.
+            iDbs.DeleteDatabase( aPath, KDbPolicyUid );
+            User::Leave( err );
+            }
+        }
+
+    // Here we have the database, successfully created. It is closed now.
+    // Open it and make some repairs if needed.
+	TInt error;
+	error = iDatabase.Open( iDbs, dbFile.FullName(), iSecureDbFormat );
+	if (error != KErrNone)
+		{
+		User::Leave( error );
+		}
+    iOpen = ETrue;
+    if ( IsDamagedL() )
+        {
+        RecoverL();
+        }
+    // Verify structure and upgrade if needed.
+    RFavouritesSrvTable::VerifyStructureL( iDatabase, ETrue );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::DeleteOrphanedFilesL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::DeleteOrphanedFilesL()
+    {
+    // Get all uids and sort them by uid.
+    CArrayFix<TInt>* uids =
+        new (ELeave) CArrayFixFlat<TInt>( KUidListGranularity );
+    CleanupStack::PushL( uids );
+    GetUidsL( *uids, TFavouritesFilter() );
+    TKeyArrayFix key( 0, ECmpTInt32 );
+    uids->Sort( key );
+
+    // Get a directory listing.
+    RDir dir;
+    User::LeaveIfError( dir.Open( iFs, *iSavedFilePath, KEntryAttNormal ) );
+    CleanupClosePushL<RDir>( dir );
+
+    TEntryArray files;
+    TInt err = dir.Read( files );
+    if( err != KErrEof )    // KErrEof means all files read.
+        {
+        User::Leave( err );
+        }
+
+    // Now check if any of the files is orphaned.
+    TParse parse;
+    TInt dummy;
+    TInt uid;
+    TInt i;
+    const TInt KElementFound = 0;
+    
+    for ( i = 0; i < files.Count(); i++ )
+        {
+        uid = UidForFilename( files[i].iName );
+        if ( uid == KFavouritesNullUid || 
+        	 uids->FindIsq( uid, key, dummy ) != KElementFound )
+            {
+            // The filename is in the required format (8 char hex number),
+            // but no item for this file -> an orphaned file.
+            User::LeaveIfError
+                ( parse.SetNoWild( files[i].iName, iSavedFilePath, NULL ) );
+            (void)iFs.Delete( parse.FullName() );
+            }
+        }
+
+    CleanupStack::PopAndDestroy( 2, uids ); // dir, uids
+    }
+
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::BeginIfNeededL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::BeginIfNeededL( TBool aWrite, TBool& aOwnTransaction )
+    {
+    aOwnTransaction = EFalse;
+    if ( !iInTransaction )
+        {
+        // Not in transaction yet.
+        BeginL( aWrite );
+        aOwnTransaction = ETrue;
+        CleanupStack::PushL( TCleanupItem( StaticRollback, this ) );
+        }
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CommitIfNeeded
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::CommitIfNeededL( TBool aOwnTransaction )
+    {
+    if ( aOwnTransaction )
+        {
+        CommitL();
+        CleanupStack::Pop();    // StaticRollback, pushed in BeginL
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CreateDatabaseL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::CreateDatabaseL( TParse& aDbFile, TBool aDoImport )
+    {
+    // Make the database.
+    // 
+    TInt errorCode = iDatabase.Create( iDbs, aDbFile.FullName(), iSecureDbFormat);
+    
+    User::LeaveIfError( errorCode );
+    CleanupClosePushL<RDbNamedDatabase>( iDatabase );
+	// Create table.
+    RFavouritesSrvTable::CreateStructureL( iDatabase );
+    // Create the root folder. No need to close the database after schema
+    // modifications in ER5.
+    CreateRootFolderL();
+    // If the bookmark import file exists on the z: drive, re-import the bookmarks.
+#ifndef __WINSCW__
+    _LIT(KBookmarkImportFile,"z:\\data\\BookmarkImportSample.txt");            // armv5
+#else
+    _LIT(KBookmarkImportFile,"c:\\private\\10008d38\\BookmarkImportSample.txt"); // winscw
+#endif
+    if( aDoImport )
+    	{
+        TUint attImport;
+        User::LeaveIfError( iFs.Connect() );
+        TInt errImport = iFs.Att( KBookmarkImportFile(), attImport );
+        if ( errImport == KErrNone )
+           {
+           // Bookmark import file exists.  Import to browserbookmarks.db database.
+           ImportL( KBookmarkImportFile() );
+           }
+    	}
+    CleanupStack::PopAndDestroy();  // close iDatabase
+    }
+
+
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::CreateRootFolderL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::CreateRootFolderL()
+    {
+    // Database just created; we have exclusive access.
+    iTable.OpenL( iDatabase );
+    CleanupClosePushL<RFavouritesSrvTable>( iTable );
+    CFavouritesItemImpl* root = CFavouritesItemImpl::NewLC();
+    // Add a new empty folder to the database.
+    root->SetType( CFavouritesItem::EFolder );
+    root->SetParentFolder( KFavouritesNullUid );
+    iTable.InsertLC();
+    iTable.WriteItemDataL( *root );
+    // Now the cursor is positioned over the new entry; change its Uid
+    // so it becomes the root folder.
+    iTable.SetUidL( KFavouritesRootUid );
+    iTable.PutL();
+    // Now we have the root. The first entry added came with 0 Uid, so this
+    // value will never be used again.
+    CleanupStack::PopAndDestroy( 2 );   // root, close iTable
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::DeleteCurrentL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::DeleteCurrentL( CArrayFix<TInt>& aDeletedUids )
+    {
+    TInt uid;
+    iTable.GetL();
+    if( iTable.ReadOnly() )
+        {
+        User::Leave( KErrAccessDenied );
+        }
+    if ( iTable.Type() == CFavouritesItem::EFolder )
+        {
+        // This is a folder. Delete contents.
+        // Save cursor pos, since the cursor will be moved.
+        TDbBookmark originalPos = iTable.Bookmark();
+        iTable.SetFiltersL( TFavouritesFilter( iTable.Uid(),
+            CFavouritesItem::ENone, NULL, KFavouritesNullContextId ) );
+        iTable.BeginningL();
+        while ( iTable.NextL() )
+            {
+            iTable.GetL();
+            if( iTable.ReadOnly() )
+                {
+                // Read-only item in a non-read-only folder.
+                User::Leave( KErrAccessDenied );
+                }
+            else
+                {
+                // Get uid of item to be deleted
+                uid = iTable.Uid();
+                iTable.DeleteL();
+                aDeletedUids.AppendL( uid );
+                iUpdatesSinceLastCompact++;
+                }
+            }
+        // Restore cursor pos.
+        iTable.ClearFilters();
+        iTable.GotoL( originalPos );
+        iTable.GetL();
+        }
+
+    // Now delete the item itself. If it's a folder and there is no error
+    // so far, it is empty by now. Error indicates read-only item in this
+    // non-read-only folder, so keep the folder as well.
+    uid = iTable.Uid();
+    iTable.DeleteL();
+    aDeletedUids.AppendL( uid );
+    iUpdatesSinceLastCompact++;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::UpdateCurrentL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::UpdateCurrentL
+( CFavouritesItemImpl& aItem, CFavouritesSrvDb::TRenameType aRenameType )
+    {
+    if ( !CFavouritesItemImpl::IsValidName( aItem.Name() ) )
+        {
+        // CFavouritesItemImpl::IsValidL also checks this; but we want to
+        // return different error code for this case, so manually check this
+        // first.
+        User::Leave( KErrBadName );
+        }
+
+    if ( !aItem.IsValid() )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    HBufC* newName = NULL;
+    // Save cursor pos; parent folder and name checking will move it.
+    TDbBookmark originalPos = iTable.Bookmark();
+    iTable.GetL();
+    TInt oldParent = iTable.ParentFolder();
+    TInt uid = iTable.Uid();
+    if ( iTable.Type() != aItem.Type() )
+        {
+        // Cannot change type.
+        User::Leave( KErrArgument );
+        }
+
+    if ( iTable.ReadOnly() )
+        {
+        // Read-only item.
+        User::Leave( KErrAccessDenied );
+        }
+
+    if ( aItem.Type() == CFavouritesItem::EFolder &&
+        aItem.ParentFolder() != KFavouritesRootUid )
+        {
+        // Folders must be in the root folder
+        // (folder hierarchy is only one-level deep).
+        User::Leave( KErrArgument );
+        }
+
+    if ( oldParent != aItem.ParentFolder() &&
+        !FolderExistsL( aItem.ParentFolder() ) )
+        {
+        // No parent folder.
+        // (Not checked if the parent folder has not changed.)
+        User::Leave( KErrArgument );
+        }
+
+    if ( aRenameType != ESuppressCheck )
+        {
+        if ( !IsUniqueNameL( aItem.Name(), aItem.ParentFolder(), uid ) )
+            {
+            if ( aRenameType == EAutoRename )
+                {
+                // Name is conflicting, rename automatically.
+                newName = AllocUniqueNameLC
+                    ( aItem.Name(), aItem.ParentFolder(), uid );
+                }
+            else
+                {
+                User::Leave( KErrAlreadyExists );
+                }
+            }
+        }
+
+    // All is well so far; update is valid.
+    iTable.PutWriteLockL();
+    // If there is a new name, set it.
+    if ( newName )
+        {
+        aItem.SetNameL( *newName );
+        }
+    // Validation may have moved the cursor; set it back.
+    iTable.GotoL( originalPos );
+    iTable.UpdateLC();                      // Prepare for update.
+    iTable.WriteItemDataL( aItem );         // Put the data.
+    iTable.SetFactoryItemL( EFalse );
+    iTable.PutL();                          // Apply changes.
+    aItem.SetUid( iTable.Uid() );           // Get Uid.
+    aItem.SetModified( iTable.Modified() ); // Get modtime.
+    // Sanity check; it must be the specified Uid.
+    __ASSERT_DEBUG( aItem.Uid() == uid,
+        FavouritesPanic( EFavouritesInternal ) );
+    iUpdatesSinceLastCompact++;
+
+    if ( newName )
+        {
+        CleanupStack::PopAndDestroy();  // newName
+        }
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::DoAddL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::DoAddL
+        (
+        CFavouritesItemImpl& aItem,
+        CFavouritesSrvDb::TRenameType aRenameType,
+        TBool aFactoryItem /*=EFalse*/,
+        TBool aReadOnly /*=EFalse*/
+        )
+    {
+    if ( !CFavouritesItemImpl::IsValidName( aItem.Name() ) )
+        {
+        // CFavouritesItemImpl::IsValidL also checks this; but we want to
+        // return different error code for this case, so manually check this
+        // first.
+        User::Leave( KErrBadName );
+        }
+
+    if ( !aItem.IsValid() )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    HBufC* newName = NULL;
+    if ( aItem.Type() == CFavouritesItem::EFolder &&
+        aItem.ParentFolder() != KFavouritesRootUid )
+        {
+        // Folders must be in the root folder
+        // (folder hierarchy is only one-level deep).
+        User::Leave( KErrArgument );
+        }
+
+    if ( !FolderExistsL( aItem.ParentFolder() ) )
+        {
+        // No parent folder.
+        User::Leave( KErrArgument );
+        }
+
+    if ( aRenameType != ESuppressCheck )
+        {
+        if ( !IsUniqueNameL
+                ( aItem.Name(), aItem.ParentFolder(), KFavouritesNullUid ) )
+            {
+            if ( aRenameType == EAutoRename )
+                {
+                // Name is conflicting, rename automatically.
+                newName = AllocUniqueNameLC
+                    ( aItem.Name(), aItem.ParentFolder(), KFavouritesNullUid );
+                }
+            else
+                {
+                User::Leave( KErrAlreadyExists );
+                }
+            }
+        }
+
+    // All is well so far; update is valid.
+    iTable.PutWriteLockL();
+    // If there is a new name, set it.
+    if ( newName )
+        {
+        aItem.SetNameL( *newName );
+        }
+    // Validation may have moved the cursor; set it back.
+    iTable.InsertLC();                      // Prepare for update.
+    iTable.WriteItemDataL( aItem );         // Put the data.
+    iTable.SetFactoryItemL( aFactoryItem );
+    iTable.SetReadOnlyL( aReadOnly );
+    iTable.PutL();                          // Apply changes.
+    aItem.SetUid( iTable.Uid() );           // Get Uid.
+    aItem.SetModified( iTable.Modified() ); // Get modtime.
+    // Sanity check; no item can exist with the Null uid.
+    __ASSERT_DEBUG( aItem.Uid() != KFavouritesNullUid,
+        FavouritesPanic( EFavouritesNullUidInDatabase ) );
+    iUpdatesSinceLastCompact++;
+
+    if ( newName )
+        {
+        CleanupStack::PopAndDestroy();  // newName
+        }
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::IsUniqueNameL
+// ---------------------------------------------------------
+//
+TBool CFavouritesSrvDb::IsUniqueNameL
+( const TDesC& aName, TInt aFolder, TInt aAcceptUid )
+    {
+    __ASSERT_DEBUG( CFavouritesItemImpl::IsValidName( aName ), \
+        FavouritesPanic( EFavouritesInternal ) );
+    TBool unique = ETrue;
+    TInt uid;
+    iTable.SetFiltersL( TFavouritesFilter( aFolder, CFavouritesItem::ENone,
+        &aName, KFavouritesNullContextId ) );
+    iTable.BeginningL();
+    while ( iTable.NextL() )
+        {
+        // We have an item with this name; check if it is aAcceptUid or
+        // one of the special items (for which names need not be unique).
+        iTable.GetL();
+        uid = iTable.Uid();
+        if (
+           uid != aAcceptUid &&
+           uid != KFavouritesHomepageUid &&
+           uid != KFavouritesLastVisitedUid &&
+           uid != KFavouritesStartPageUid &&
+           uid != KFavouritesAdaptiveItemsFolderUid
+           )
+            {
+            // It's not aAcceptUid or special item. We have a name clash.
+            unique = EFalse;
+            break;
+            }
+        }
+    iTable.ClearFilters();
+    return unique;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::MakeNameUniqueL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::MakeUniqueNameL
+( TDes& aName, TInt aFolder, TInt aAcceptUid )
+    {
+    TBool forcePostfix = EFalse;
+    __ASSERT_DEBUG( CFavouritesItemImpl::IsValidName( aName ), \
+        FavouritesPanic( EFavouritesInternal ) );
+    // Make sure the result fits.
+    __ASSERT_DEBUG( aName.MaxLength() >= Min\
+        ( aName.Length() + KFavouritesMaxPostfix, KFavouritesMaxName ), \
+        FavouritesPanic( EFavouritesBufferTooSmall ) );
+
+    TPtrC prefix = GetPrefix( aName );
+    if ( prefix.Length() + KFavouritesMaxPostfix > KFavouritesMaxName )
+        {
+        // Oops, this prefix is so long that if we append the longest possible
+        // postfix to it, the result will not fit into a bookmark name!
+        // In this case, we truncate the prefix. The truncated prefix is most
+        // likely not conflicting as is, but we do the postfix appending
+        // anyway.
+        prefix.Set
+            ( prefix.Left( KFavouritesMaxName - KFavouritesMaxPostfix ) );
+        forcePostfix = ETrue;
+        }
+    HBufC* buf = HBufC::NewLC( prefix.Length() + KFavouritesMaxPostfix );
+    _LIT( KFormatPrefix, "%S*" );
+    buf->Des().Format( KFormatPrefix, &prefix );
+    iTable.SetFiltersL( TFavouritesFilter
+        ( aFolder, CFavouritesItem::ENone, buf, KFavouritesNullContextId ) );
+    CleanupStack::PopAndDestroy();  // buf
+
+    TInt uid;
+    TInt postfix;
+    CArrayFix<TInt>* postfixes =
+        new (ELeave) CArrayFixFlat<TInt>( KPostfixListGranularity );
+    CleanupStack::PushL( postfixes );
+    iTable.BeginningL();
+    while ( iTable.NextL() )
+        {
+        iTable.GetL();
+        uid = iTable.Uid();
+        if (
+           uid != aAcceptUid &&
+           uid != KFavouritesHomepageUid &&
+           uid != KFavouritesLastVisitedUid &&
+           uid != KFavouritesStartPageUid &&
+           uid != KFavouritesAdaptiveItemsFolderUid
+           )
+            {
+            // Appending all values (incl. negative values and duplicates).
+            postfixes->AppendL( GetPostfix( iTable.Name(), prefix ) );
+            }
+        }
+    iTable.ClearFilters();
+
+    // Sort postfixes ascending.
+    TKeyArrayFix key( 0, ECmpTInt );
+    User::LeaveIfError( postfixes->Sort( key ) );
+
+    // Initial postfix candidate is 0 ("no postfix"), or 1 if forcePostfix
+    // is ETrue.
+    postfix = forcePostfix ? 1 : 0;
+    // Find the first free postfix, above the starting candidate (0 or 1).
+    // The loop skips negative values and duplicates.
+    TInt i;
+    for ( i = 0; i < postfixes->Count(); i++ )
+        {
+        if ( postfixes->At( i ) < postfix )
+            {
+            // This value is smaller than the current candidate;
+            // candidate stays the current one (do nothing); but keep checking
+            // forthcoming bigger values (continue).
+            ;
+            }
+        else if ( postfixes->At( i ) == postfix )
+            {
+            // This postfix already taken. Candidate is next one.
+            postfix++;
+            }
+        else
+            {
+            // postfixes->At( i ) > postfix: a "hole" is found.
+            //
+            // This case could be the condition in the controlling "for" (and
+            // the "break" statement could be avoided); but I intentionally
+            // placed it here so the logic of the "hole-search" can be seen
+            // more clearly.
+            break;
+            }
+        }
+    CleanupStack::PopAndDestroy();      // postfixes
+
+    if ( postfix == 0 )
+        {
+        // First unique name is the prefix without any postfix.
+        // Simply set length to the prefix length.
+        aName.SetLength( prefix.Length() );
+        }
+    else
+        {
+        // Append a new postfix to the prefix.
+        // It seems we have to copy the prefix into a buffer.
+        // The prefix points to aName, so Format would format aName
+        // using the prefix from itself. But Format does some weird
+        // tricks (filling the buffer with some rubbish before writing
+        // into it). It's not sprintf :-(.
+        buf = prefix.AllocLC();
+        _LIT( KFormatSmallPostfix, "%S(0%d)" );
+        _LIT( KFormatLargePostfix, "%S(%d)" );
+        if ( postfix < 10 )
+            {
+            aName.Format( KFormatSmallPostfix, buf, postfix );
+            }
+        else
+            {
+            aName.Format( KFormatLargePostfix, buf, postfix );
+            }
+        CleanupStack::PopAndDestroy();  // buf
+        }
+
+    // Sanity check. The generated name should really be unique.
+    __ASSERT_DEBUG \
+        ( \
+        IsUniqueNameL( aName, aFolder, aAcceptUid ), \
+        FavouritesPanic( EFavouritesInternal ) \
+        );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::AllocUniqueNameLC
+// ---------------------------------------------------------
+//
+HBufC* CFavouritesSrvDb::AllocUniqueNameLC
+( const TDesC& aName, TInt aFolder, TInt aAcceptUid )
+    {
+    HBufC* uniqueName = HBufC::NewLC( aName.Length() + KFavouritesMaxPostfix );
+    *uniqueName = aName;
+    TPtr ptr( uniqueName->Des() );
+    MakeUniqueNameL( ptr, aFolder, aAcceptUid );
+    return uniqueName;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::StaticRollback
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::StaticRollback( TAny* aDb )
+    {
+    STATIC_CAST( CFavouritesSrvDb*, aDb )->Rollback();
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::RestoreFactorySettingsL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::RestoreFactorySettingsL
+( RFavouritesSrvTable& aReferenceTable, CUidMap& aApMap )
+    {
+    __ASSERT_DEBUG( InTransaction(), FavouritesPanic( EFavouritesInternal ) );
+
+    // 1. Check ContextId-s of folders in reference table, and clear all those
+    //    ContextId-s from our folders.
+    //
+    //    This part is a bit "out of line" for the Engine, as here we do deal
+    //    with ContextId semantics: we ensure that we don't create more folders
+    //    with a given ContextId. This ensures the expected correct behaviour
+    //    of Seamless Link functionality after an RFS: the newly restored
+    //    folders become the Seamless Link folders.
+    //    (Note: if the reference table contains more folders with the same
+    //    ContextId, they will be mechanically copied. Checking that is really
+    //    not our business.)
+
+    TInt32 contextId;
+    aReferenceTable.BeginningL();
+    while ( aReferenceTable.NextL() )
+        {
+        aReferenceTable.GetL();
+        contextId = aReferenceTable.ContextId();
+        if ( contextId != KFavouritesNullContextId )
+            {
+            // Folders from root with given context id.
+            iTable.SetFiltersL( TFavouritesFilter( KFavouritesRootUid,
+                CFavouritesItem::EFolder, NULL, contextId ) );
+            iTable.BeginningL();
+            while( iTable.NextL() )
+                {
+                iTable.UpdateLC();
+                iTable.SetContextIdL( KFavouritesNullContextId );
+                iTable.PutL( /*aTouch=*/EFalse );
+                }
+            iTable.ClearFilters();
+            }
+        }
+
+    // 2. Delete all items that have the "factory item" flag.
+    //    (These are the unmodified factory items - any modification
+    //    clears the flag.) The "factory item" and read-only flag of floders are cleared.
+    
+	iTable.BeginningL();
+    while ( iTable.NextL() )
+        {
+        iTable.GetL();
+        if ( iTable.FactoryItem() )
+            {
+            switch ( iTable.Type() )
+                {
+                case CFavouritesItem::EItem:
+                    {
+					// Delete unmodified factory item 
+					iTable.DeleteL();
+                    break;
+                    }
+
+                case CFavouritesItem::EFolder:
+                    {
+                    // Clear flags for folders.
+                    iTable.UpdateLC();
+                    iTable.SetFactoryItemL( EFalse );
+                    iTable.SetReadOnlyL( EFalse );
+                    iTable.PutL( /*aTouch=*/EFalse );
+                    break;
+                    }
+
+                default:
+                    {
+                    FavouritesPanic( EFavouritesInternal );
+                    break;
+                    }
+                }
+            }
+        }
+
+    // 3. Lookup folders by name, creating new ones if necessary. The target
+    //    folder gets the attributes of the source folder (read-only and
+    //    factory item flag), regardless of whether it is existing or newly
+    //    created. During this process, a mapping table
+    //    (source folder uid -> target folder uid) is built. 
+
+    TTime modTime;
+    SUidPair mapping;
+    TPtrC name;
+    CFavouritesItemImpl* item = CFavouritesItemImpl::NewLC();
+    CUidMap* parentMap = new (ELeave) CUidMap( 1 );
+    CleanupStack::PushL( parentMap );
+
+    // Add the "root->root" mapping to the map.
+    mapping.iUid1 = KFavouritesRootUid;
+    mapping.iUid2 = KFavouritesRootUid;
+    parentMap->AppendL( mapping );
+
+    // All folder of reference table in root.
+    aReferenceTable.SetFiltersL( TFavouritesFilter( KFavouritesRootUid,
+        CFavouritesItem::EFolder, NULL, KFavouritesNullContextId ) );
+    aReferenceTable.BeginningL();
+    while( aReferenceTable.NextL() )
+        {
+        aReferenceTable.GetL();
+        name.Set( aReferenceTable.Name() );
+        __ASSERT_DEBUG( name.Length(), FavouritesPanic( EFavouritesInternal ) );
+        // Folders matching the name.
+        iTable.SetFiltersL( TFavouritesFilter( KFavouritesRootUid,
+            CFavouritesItem::EFolder, &name, KFavouritesNullContextId ) );
+        iTable.BeginningL();
+        if( iTable.NextL() )
+            {
+            // Folder exists with this name.
+            // Copy read-only and factory item flags from reference table.
+            // Also copy ContextId (possibly we cleared that earlier).
+            iTable.UpdateLC();
+            iTable.SetReadOnlyL( aReferenceTable.ReadOnly() );
+            iTable.SetFactoryItemL( aReferenceTable.FactoryItem() );
+            iTable.SetContextIdL( aReferenceTable.ContextId() );
+            iTable.PutL( /*aTouch=*/EFalse );
+            }
+        else
+            {
+            // No folder exists with this name.
+            // Add now by copying from reference table (incl. modtime).
+            aReferenceTable.ReadItemDataL( *item );
+            modTime = item->Modified();
+            DoAddL
+                (
+                *item,
+                EDontRename,
+                /*aFactoryItem=*/item->IsFactoryItem(),
+                /*aReadOnly=*/item->IsReadOnly()
+                );
+            // Cursor is still on the added record. Set modtime.
+            // Not using CFavouritesSrvDb::SetModifiedL() - that would mess up
+            // the filters.
+            iTable.UpdateLC();
+            iTable.SetModifiedL( modTime );
+            iTable.PutL( /*aTouch=*/ EFalse );
+            }
+        // In both cases (existing folder updated, or new added), the cursor
+        // is now on the target folder. Add a new mapping entry.
+        mapping.iUid1 = aReferenceTable.Uid();
+        mapping.iUid2 = iTable.Uid();
+        parentMap->AppendL( mapping );
+        iTable.ClearFilters();
+        }
+    aReferenceTable.ClearFilters();
+
+    // 4. Replace the unmodified factory items of our table with corresponding items from reference table and 
+	// add remaining items in the reference table to our table,
+	// with AP mapping and parent folder mapping applied.
+
+    TInt i;
+    TFavouritesWapAp ap;
+	TInt origId;
+	TInt newId;
+
+    // Get all items.
+    aReferenceTable.SetFiltersL( TFavouritesFilter ( KFavouritesNullUid,
+        CFavouritesItem::EItem, NULL, KFavouritesNullContextId ) );
+    aReferenceTable.BeginningL();
+
+    while ( aReferenceTable.NextL() )
+        {
+        aReferenceTable.GetL();
+        aReferenceTable.ReadItemDataL( *item );
+        modTime = item->Modified();
+		origId = item->Uid();
+
+        // Remap parent folder.
+        for( i = 0; i < parentMap->Count(); i++ )
+            {
+            if( item->ParentFolder() == parentMap->At( i ).iUid1 )
+                {
+                item->SetParentFolder( parentMap->At( i ).iUid2 );
+                break;
+                }
+            // Parent folder mapping should always be successful.
+            __ASSERT_DEBUG( i < parentMap->Count(), \
+                FavouritesPanic( EFavouritesInternal ) );
+            }
+				
+		// Add the item.
+		DoAddL
+			(
+			*item,
+			EAutoRename,
+			/*aFactoryItem=*/ETrue,
+			/*aReadOnly=*/item->IsReadOnly()
+			);	
+
+		// Cursor is still on the added record. Set modtime.
+        // Not using CFavouritesSrvDb::SetModifiedL() - that would mess up
+        // the filters.
+        iTable.UpdateLC();
+        iTable.SetModifiedL( modTime );
+        iTable.PutL( /*aTouch=*/ EFalse );
+		
+		// Get the new item UID 
+		newId = item->Uid();
+
+		if( !iTable.SeekToUidL( origId ) )
+			{
+			iTable.GotoToUidL(newId);
+			iTable.UpdateLC();
+			iTable.SetUidL( origId );
+			iTable.PutL( /*aTouch=*/ EFalse );
+			item->SetUid( origId );
+			}        
+
+        // Check AP, enrol for mapping if needed.
+        ap = item->WapAp();
+        if ( !ap.IsDefault() && !ap.IsNull() )
+            {
+            mapping.iUid1 = item->Uid();
+            mapping.iUid2 = STATIC_CAST( TInt, ap.ApId() );
+            aApMap.AppendL( mapping );
+            }
+        }
+    aReferenceTable.ClearFilters();
+
+    CleanupStack::PopAndDestroy( 2 );   // parentMap, item
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SetAccessPointsL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SetAccessPointsL( const CUidMap& aApMap )
+    {
+    __ASSERT_DEBUG( InTransaction(), FavouritesPanic( EFavouritesInternal ) );
+    TInt i;
+    TFavouritesWapAp ap;
+    for ( i = 0; i < aApMap.Count(); i++ )
+        {
+        ap.SetApId( STATIC_CAST( TUint32, aApMap[i].iUid2 ) );
+        iTable.GotoToUidL( aApMap[i].iUid1 );
+        iTable.GetL();
+        iTable.UpdateLC();
+        iTable.SetWapApL( ap );
+        iTable.PutL( /*aTouch=*/ EFalse );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// IMPORT BOOKMARKS CODE INTEGRATED FROM BOOKMARKS UTILITY
+// ---------------------------------------------------------
+
+// CONSTANTS
+
+/// ',' character.
+LOCAL_C const TUint KComma = ',';
+/// '#' character.
+LOCAL_C const TUint KHash = '#';
+/// EOF (0) character.
+LOCAL_C const TUint KEof = 0;
+/// '\r' character.
+LOCAL_C const TUint KCr = '\r';
+/// '\n' character.
+LOCAL_C const TUint KLf = '\n';
+
+/// LF-EOF stop token set.
+_LIT( KStopLfEof, "\n\0" );
+/// Comma stop token set.
+_LIT( KStopComma, "," );
+/// Comma-LF-EOF stop token set.
+_LIT( KStopCommaLfEof, ",\n\0" );
+
+/// "Folder" kewyword.
+_LIT( KFolder, "Folder" );
+/// "Item" kewyword.
+_LIT( KItem, "Item" );
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::ImportL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::ImportL( const TDesC& aFileName )
+    {
+    User::LeaveIfError( iFile.Open( iFs, aFileName,
+        EFileRead | EFileShareReadersOnly ) );
+    CleanupClosePushL<RUnicodeFile>( iFile );
+
+    iFolderNames = new (ELeave) CArrayFixFlat<CFavouritesFolder>( 1 ); 
+    User::LeaveIfNull( iFolderNames  );                                
+    CleanupStack::PushL( iFolderNames );                               
+    
+    iBuf = new (ELeave) TText16[KFavouritesMaxUrl];
+    User::LeaveIfNull( iBuf );
+    CleanupStack::PushL( iBuf );
+
+    iMaxCh = iBuf + KFavouritesMaxUrl;
+
+    GetCharL();
+
+    while( NextLineL() )
+       {;}
+
+    TUint count = iFolderNames->Count();
+    for (TUint i = 0; i < count; i++)
+        {
+        CFavouritesFolder folder = iFolderNames->At(i);
+        delete folder.Name();
+        }
+    
+    CleanupStack::Pop(iBuf); //iBuf
+    delete iBuf;
+    CleanupStack::Pop(iFolderNames); //iFolderNames
+    delete iFolderNames;
+    CleanupStack::PopAndDestroy();  // close iFile
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::GetCharL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::GetCharL()
+    {
+    iCurCh = iFile.GetCharL();
+    if ( iCurCh == KCr )
+        {
+        // CR character found - ignore it. Not expecting CR to appear anywhere
+        // else than before an LF.
+        iCurCh = iFile.GetCharL();
+        }
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::NextLineL
+// ---------------------------------------------------------
+//
+TBool CFavouritesSrvDb::NextLineL()
+    {
+    switch( iCurCh )
+        {
+        case KEof:
+            // EOF
+            return EFalse;
+
+        case KHash:
+            // Comment line; skip over.
+            SkipL( KStopLfEof );
+            GetCharL();
+            break;
+
+        case KCr:
+        case KLf:
+            // Empty line; skip over.
+            GetCharL();
+            break;
+
+        default:
+            // Parse bookmark attributes.
+            AttrsL();
+            break;
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::NextTokenL
+// ---------------------------------------------------------
+//
+TPtrC CFavouritesSrvDb::NextTokenL( const TDesC& aStopCharSet )
+    {
+    iNextCh = iBuf; // Start storing token at start of buffer.
+    while ( iNextCh < iMaxCh )
+        {
+        if ( aStopCharSet.Locate( iCurCh ) != KErrNotFound )
+            {
+            // Stop character found - return what we have stored so far. This
+            // may be an empty string as well.
+            return TPtrC( iBuf, iNextCh - iBuf );
+            }
+        *iNextCh = STATIC_CAST( TText16, iCurCh );
+        iNextCh++;
+        GetCharL();
+        }
+    // No more space in buffer to store token.
+    User::Leave( KErrOverflow );
+    /*NOTREACHED*/
+    return TPtrC();
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::NextIntTokenL
+// ---------------------------------------------------------
+//
+TInt CFavouritesSrvDb::NextIntTokenL( const TDesC& aStopCharSet )
+    {
+    TInt ret = 0;
+    TPtrC token( NextTokenL( aStopCharSet ) );
+    if ( token.Length() )
+        {
+        TLex lex( token );
+        User::LeaveIfError( lex.Val( ret ) );
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::NextHexTokenL
+// ---------------------------------------------------------
+//
+TInt32 CFavouritesSrvDb::NextHexTokenL( const TDesC& aStopCharSet )
+    {
+    TUint32 ret = 0;
+    TPtrC token( NextTokenL( aStopCharSet ) );
+    if ( token.Length() )
+        {
+        TLex lex( token );
+        User::LeaveIfError( lex.Val( ret, EHex ) );
+        }
+    return STATIC_CAST( TInt32, ret );
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::SkipL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::SkipL( const TDesC& aStopCharSet )
+    {
+    // Note that EOF also can be a stop character; aStopChar check has
+    // precendence over EOF check. That is the 'expected EOF' case.
+    while( aStopCharSet.Locate( iCurCh ) == KErrNotFound )
+        {
+        if ( iCurCh == KEof )
+            {
+            // Unexpected EOF.
+            User::Leave( KErrEof );
+            }
+        GetCharL();
+        }
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::AttrsL
+// ---------------------------------------------------------
+//
+void CFavouritesSrvDb::AttrsL()
+    {
+    TPtrC token;
+    TInt num = 0;
+    TBool readOnly( EFalse );
+  //  TBool factoryItem;
+    TBool preferred( EFalse );
+    TBool hidden( EFalse );
+    TFavouritesWapAp ap;
+    
+    iTable.OpenL( iDatabase );
+    CleanupClosePushL<RFavouritesSrvTable>( iTable );
+    iTable.BeginningL();
+    iTable.InsertLC();
+
+    // Parse the line and fill item.
+
+    // Type (including special items).
+    token.Set( NextTokenL( KStopComma ) );
+    if ( !token.Compare( KFolder ) )
+        {
+        iTable.SetTypeL( CFavouritesItem::EFolder );
+        }
+    else if ( !token.Compare( KItem ) )
+        {
+        iTable.SetTypeL( CFavouritesItem::EItem );
+        }
+    else
+        {
+        // Expected "Folder", "Item"
+        User::Leave( KErrCorrupt );
+        }
+    GetCharL();
+    // Name.
+    iTable.SetNameL( NextTokenL( KStopComma ) );
+    if (iTable.Type() == CFavouritesItem::EFolder)    // Remember the folder name for UID lookup.
+        {      
+        HBufC* buf = HBufC::NewLC( iTable.Name().Length() );
+        TPtr ptr( buf->Des() );
+        ptr.Copy( iTable.Name() );
+        CFavouritesFolder folder( buf, iTable.Uid() );
+        iFolderNames->AppendL( folder );
+        CleanupStack::Pop(); // for newlc of buf
+        }
+    GetCharL();
+
+    // Parent folder.
+    iTable.SetParentFolderL( FolderByNameL( NextTokenL( KStopComma ) ) );
+
+    GetCharL();
+
+    // URL.
+    iTable.SetUrlL( NextTokenL( KStopComma ) );
+    GetCharL();
+
+    // WAP AP.
+    token.Set( NextTokenL( KStopComma ) );
+    if ( token.Length() )
+        {
+        TLex lex( token );
+        if ( lex.Val( num ) != KErrNone )
+           {
+             IAPIdByNameL( token, num );
+           }
+        ap = num;
+        }
+    else
+    	{
+        ap.SetDefault();
+    	}
+    
+    iTable.SetWapApL( ap );
+    
+    GetCharL();
+
+    // User name.
+    iTable.SetUsernameL( NextTokenL( KStopComma ) );
+    GetCharL();
+
+    // Password.
+    iTable.SetPasswordL( NextTokenL( KStopComma ) );
+    GetCharL();
+
+    // Read-only flag.
+    num = NextIntTokenL( KStopComma );
+    if ( num == 0 )
+        {
+        readOnly = EFalse;
+        }
+    else if ( num == 1 )
+        {
+        readOnly = ETrue;
+        }
+    else
+        {
+        // Expected "0" or "1".
+        User::Leave( KErrCorrupt );
+        }
+    GetCharL();
+
+    // Factory item flag.
+    num = NextIntTokenL( KStopComma );
+    if ( num == 0 )
+        {
+  //      factoryItem = EFalse;
+        }
+    else if ( num == 1 )
+        {
+  //      factoryItem = ETrue;
+        }
+    else
+        {
+        // Expected "0" or "1".
+        User::Leave( KErrCorrupt );
+        }
+    GetCharL();
+
+    // Context id.
+    iTable.SetContextIdL( NextHexTokenL( KStopCommaLfEof ) );
+    
+    GetCharL();
+    num = NextIntTokenL( KStopCommaLfEof );
+    if ( num == 0 )
+        {
+        hidden = EFalse;
+        }
+    else if ( num == 1 )
+        {
+        hidden = ETrue;
+        }
+    else
+        {
+        // Expected "0" or "1".
+        User::Leave( KErrCorrupt );
+        }
+
+    iTable.SetHiddenL(hidden);
+    
+    // No GetCharL yet - PreferredUid is optional, so we need to investigate
+    // lookeahed character first.
+
+    // Preferred flag (optional).
+    if ( iCurCh == KComma )
+        {
+        GetCharL();
+        num = NextIntTokenL( KStopLfEof );
+        if ( num == 0 )
+            {
+            preferred = EFalse;
+            }
+        else if ( num == 1 )
+            {
+            preferred = ETrue;
+            }
+        else
+            {
+            // Expected "0" or "1".
+            User::Leave( KErrCorrupt );
+            }
+        }
+    GetCharL();
+
+    if ( preferred )
+        {
+        iTable.SetPreferredUidL( iTable.Uid() );
+        }
+    iTable.SetReadOnlyL( readOnly );
+    iTable.PutL();
+    // Now we have the root. The first entry added came with 0 Uid, so this
+    // value will never be used again.
+    iTable.Close();
+    CleanupStack::Pop( );             // close iTable
+    }
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::FolderByNameL
+// ---------------------------------------------------------
+//
+TInt CFavouritesSrvDb::FolderByNameL( const TDesC& aName )
+    {
+    TInt folderUid = KFavouritesRootUid;
+
+    if ( aName.Length() )
+        {
+        // loop through iFolderNames and if bookmark name is found, return the index/UID where found
+        // else return root UID.
+        for (TUint x = 0; x < iFolderNames->Count(); ++x)
+            {
+            CFavouritesFolder folder = iFolderNames->At(x);
+            HBufC* fn = folder.Name();
+            TPtr ptr( fn->Des());
+            if (aName.Compare(ptr) == 0)
+                {
+                folderUid = folder.Uid();
+                return folderUid;
+                }
+             }
+        }
+
+    return folderUid;
+    }
+
+
+// ---------------------------------------------------------
+// CFavouritesSrvDb::IAPIdByNameL
+// ---------------------------------------------------------
+//
+TInt CFavouritesSrvDb::IAPIdByNameL( TDesC& aName, TInt& aIapId )
+	{
+	TUint pushCount = 0;
+	TInt retVal = KErrNone;
+    TBool found = EFalse;
+    TUint32 iapId = 0;
+    TInt err = KErrNone;
+    
+    CCommsDatabase* db = CCommsDatabase::NewL();
+	CleanupStack::PushL(db);
+	pushCount++;
+	CCommsDbTableView* tableView = db->OpenTableLC( TPtrC(WAP_ACCESS_POINT) );
+
+	pushCount++;
+	retVal = tableView->GotoFirstRecord();
+	
+	while( retVal == KErrNone && !found )
+		{
+	    TBuf< KCommsDbSvrMaxFieldLength > iapName;
+	    tableView->ReadTextL( TPtrC( COMMDB_NAME ), iapName );
+	    if (iapName.CompareF( aName ) == 0 )
+	    	{
+	        TRAP( err, tableView->ReadUintL( TPtrC(COMMDB_ID), iapId ) );
+	        found = ETrue;
+	    	}
+	    retVal = tableView->GotoNextRecord();
+		}
+    	aIapId = iapId;
+	
+	CleanupStack::PopAndDestroy( pushCount );
+	return retVal;
+	}
+//  End of File