commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/ced.cpp
changeset 0 dfb7c4ff071f
child 21 07656293a99c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/ced.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1609 @@
+// Copyright (c) 2003-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:
+//
+
+/**
+ @file ced.cpp
+ @internalComponent
+*/
+
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32std.h>
+#include <f32file.h>
+#include <bacline.h>
+#include "dbdef.h"
+#include "filedump.h"
+#include "input.h"
+#include "database.h"
+#include "CXMLFile.h"
+#include "CXMLContentHandler.h"
+#include "CDBSTD.H"
+#include <centralrepository.h>
+
+/** max length of path/filename/column/table name */
+#define MAX_BUFFER_LEN			256								
+
+/** max length of path/filename/column/table name */
+#define MAX_ATTRIB_LEN			32		
+
+/** max length of arg list to program */
+#define MAX_ARG_LEN				(MAX_BUFFER_LEN * 3)			
+
+/** Application name  */
+#define APPLICATIONNAME			_L("CommsDat Configuration Utility")
+
+/** Version Info  */
+#define CEDUNVERSIONED			_L("CED deliberately un-versioned") /** refer DEF092743 */
+
+#ifdef __TOOLS2__
+
+_LIT(CFG_TARGET, "ced.cfg");
+_LIT(XML_TARGET, "ced.xml");
+_LIT(LOG_TARGET, "ced.log");
+_LIT(KMeshPrefaceFile, "meshpreface1.cfg");
+
+	#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+		#ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
+			_LIT(SUPPORTED_OS, "95");
+		#else
+			_LIT(SUPPORTED_OS, "");
+		#endif
+	#else
+		#ifndef SYMBIAN_COMMSDAT_USE_INT_RECORD_LINKS
+			_LIT(SUPPORTED_OS, "94");
+		#else
+			_LIT(SUPPORTED_OS, "93");
+		#endif
+	#endif
+
+#else
+
+_LIT(CFG_TARGET, "c:\\ced.cfg");
+_LIT(XML_TARGET, "c:\\ced.xml");
+_LIT(LOG_TARGET, "c:\\ced.log");
+_LIT(KMeshPrefaceFile, "z:\\system\\data\\meshpreface1.cfg");
+_LIT(DEFAULT_SESSION_PATH, "c:\\");
+#endif
+
+
+// GLOBALS
+/** Logging  */
+CFileDump* gMsg;	
+/** Database access */	
+DBAccess* gDB;
+/** .ini file parsing */
+CfgFile gCfg;
+/** XML file parsing */		
+XMLFile* gXML;
+/** Console accessor */		
+LOCAL_D CConsoleBase* gConsole;
+/** Passed in arg list */		
+HBufC* gArgumentLine;
+/** Flag to indicate a successful run */
+TBool gProcessingSuccessful = ETrue;
+/** Flag to indicate whether the '-V' arg was passed in */
+TBool gValidityChecking = EFalse;
+/** flag to indicate whether the execution format is .dll or .exe*/
+TBool gIsExeDLL = EFalse;
+/** flag to indicate whether the configuration file is in XML format */
+TBool gIsXML = ETrue; 
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+TBool gDeprecatedFields = EFalse;
+#endif
+//SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+// PROTOTYPES
+
+TInt ParseCommandLineL(TInt &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut, TDes &aInPref);
+TInt ParseArgument(TInt &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut);
+
+TInt DoProcessL(TBool aIsCfg);
+void DoDeleteL();
+
+TInt DoCfgTemplateL(TDesC &aTable, const TInt &aIndex);
+TInt DoCfgInsertsL(TDesC &aTable, const TInt &aIndex);
+
+TInt DoXMLTemplateL(const TInt &aIndex);
+TInt DoXMLInsertsL(const TInt &aIndex);
+
+TInt SetColumnDetailsL(TInt aIndex, TInt aRecordCount);
+TInt SetXMLColumnDetailsL(TInt aEntryIndex, TInt aIndex, TInt aRecCount);
+
+void DisplayMessage(TPtrC aMessage, TInt aJustTheMessage = EFalse);
+void HelpDump();
+void MainL();
+LOCAL_C void doMainL();
+
+TInt DoProcessL(TBool aIsCfg)
+/** Store the information provided in the configuration file to CommDB
+
+@param aIsCfg Whether the file to be parsed is an older style .cfg rather than .xml
+@return TInt refer only called functions
+@leave refer only called functions and dependant components
+*/
+	{
+	TRAPD(ret, gDB->InitCommsdatL());
+
+	// connect to DB manager
+	if (ret==KErrNone)
+		{
+		TVersion version = gDB->Version();
+		gMsg->Msg(_L("Database Version Maj %d Min %d Build %d"), version.iMajor, version.iMinor, version.iBuild);
+		
+		gMsg->Dbg(_L(""));
+		gMsg->Dbg(_L("Session started"));
+		
+		// loop through tables
+		TInt i = 0;
+		TInt j = 0;
+		TBuf<MAX_BUFFER_LEN> table = tableArray[i];
+		TBuf<MAX_BUFFER_LEN> tempColumn;
+		TBool changed;
+		
+		while (table.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+			{
+			gMsg->Msg(_L(" "));
+			gMsg->Msg(_L("%S Table"), &table);
+			// get a count of editable columns
+			j = 0;
+			tempColumn = ColumnArray[i][j];
+			while(tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+				{
+				j++;
+				tempColumn = ColumnArray[i][j];
+				}
+			gMsg->Dbg(_L("(%d editable fields in table)"), j);
+			
+			TBool commitIndividualRecords = (table.CompareC(_L("ConnectionPreferences")) == 0);
+			
+			if(commitIndividualRecords)
+				{
+				// Commit any current changes
+				TInt ret = gDB->CommitTransaction();
+				if(ret != KErrNone)
+					{
+					gMsg->Msg(_L("ERROR: CommitTransaction returned err [%d]"), ret);
+					if (gValidityChecking) 
+						{
+						gProcessingSuccessful = EFalse;
+						}
+					}
+				}
+			else
+				{
+				gDB->MaybeBeginTransactionL();
+				}
+			gDB->SetCommitIndividualRecords(commitIndividualRecords);
+		
+			changed = EFalse;			
+			//Create a recordset for the table
+			ret = KErrNone;
+			if(!commitIndividualRecords)
+				{
+				TRAP(ret, gDB->CreateOrInsertRecordL(DBAccess::ECreateNew,elementIdArray[i], 0));			
+				}
+			if(ret == KErrNone)
+				{
+				if (aIsCfg?DoCfgTemplateL(table,i):DoXMLTemplateL(i))	
+					{
+					gMsg->Msg(_L(" "));
+					changed = ETrue;
+					}					
+				
+				if (aIsCfg?DoCfgInsertsL(table, i):DoXMLInsertsL(i))
+					{
+					gMsg->Msg(_L(" "));
+					changed = ETrue;
+					}				
+				
+				if (changed)
+					{
+					TInt  commitErr = gDB->CommitChanges();
+
+					if (commitErr == KErrNone)
+						{
+						gMsg->Msg(_L("Insert successful"));
+						}
+					else
+						{
+						gMsg->Msg(_L("Insert failed [%d ]"), commitErr);
+						if (gValidityChecking) 
+							{
+							gProcessingSuccessful = EFalse;
+							}
+						}
+					}	
+				else
+					{
+					gMsg->Dbg(_L("Nothing to process"));	
+					}
+				
+				if(gDB->CommitIndividualRecords())
+					{
+					ret = gDB->CommitChanges();
+					}
+					gDB->CloseTable();				
+
+				}
+			else
+				{
+				gMsg->Dbg(_L("(Creating Record set Failed [%d ])"), ret);	
+				}
+			
+			i++;
+			table = tableArray[i];
+			
+			}
+		ret = gDB->CommitTransaction();
+		gDB->Close();
+		}
+	else
+		{
+		gMsg->Dbg(_L("(Could not connect to Commsdat [%d ])"), ret);
+		}	
+	
+	return ret;
+	}
+
+void DoDeleteL()
+/** Completely erase the communications database, not used when the append flag set
+
+@return void
+@leave refer only called functions and dependant components
+*/
+	{
+	gMsg->Msg(_L("The old database will be replaced ") );
+			
+	// Get a session with the central repository
+	const TUid KCDCommsRepositoryId = { 0xCCCCCC00 };
+	CRepository*  storage = NULL;
+
+	TRAPD(err, storage = CRepository::NewL(KCDCommsRepositoryId));
+	if (KErrNone != err)
+		{
+		gMsg->Msg(_L("Failed to create Central Repository with ID : %x   (error %d)"), KCDCommsRepositoryId, err);
+		_LIT(KCEDPanic, "CED");
+		User::Panic(KCEDPanic, KErrNotFound);
+		}
+	CleanupStack::PushL(storage);
+	
+    // open transaction - if can't do this then fail.
+    User::LeaveIfError(storage->StartTransaction(CRepository::EReadWriteTransaction));
+
+	// Find everything in the database
+	RArray<TUint32> ids;
+    CleanupClosePushL(ids);
+	err = storage->FindL(0, 0, ids);
+	if(err != KErrNotFound)
+		{
+		User::LeaveIfError(err);
+		}
+	
+	// delete everything in the database
+	if (ids.Count())
+		{
+		for ( TInt i = ids.Count()-1; i >=0 ; i--)
+			{
+			if( i == ids.Count()-1 || i>=10000 && i%10000==0 || i<10000 && i>= 1000 && i%1000==0 ||
+				i<1000 && i>=100 && i%100==0 || i<100 && i>=10 && i%10==0 || i<10)
+				{
+				gMsg->Msg(_L("%d"),i);
+				}
+			User::LeaveIfError(storage->Delete(ids[i]));
+			}
+		}
+	
+	TUint32 aErrorId;
+	err = storage->CommitTransaction(aErrorId);
+
+	CleanupStack::PopAndDestroy(2);
+	
+	if (err != KErrNone)
+		{
+		gMsg->Msg(_L("Central Repository CommitTransaction returned err [%d]"), err);
+		}	
+	User::LeaveIfError(err);	
+	}
+
+void MainL()
+/** Central processing unit of CED
+
+@return void
+@leave refer only called functions and dependant components
+*/
+	{
+	TInt bDebugOn = EFalse;
+	TBool bOverWrite = EFalse;
+	TBool bForceXMLProcessing = EFalse;
+	
+	TBuf<MAX_BUFFER_LEN> fIn;
+	TBuf<MAX_BUFFER_LEN> fOut;
+	TBuf<MAX_BUFFER_LEN> fInPref;
+	RFs fsSession;		// file system session
+	
+	// connect to file system
+	User::LeaveIfError(fsSession.Connect());
+	CleanupClosePushL(fsSession);
+	
+	// check command line
+	TInt valid;
+	
+	if (gIsExeDLL == EFalse)
+		{
+		// exe's get arguments from the command line
+		valid = ParseCommandLineL(bDebugOn, bOverWrite, bForceXMLProcessing, fIn, fOut, fInPref);
+		}
+	else
+		{
+		// exedll'd get the parameters passed in 
+		valid = ParseArgument(bDebugOn, bOverWrite, bForceXMLProcessing, fIn, fOut);
+		}
+	
+	if (valid)
+		{					
+		// Get the type of the input file i.e. whether it is
+		// an XML file or a CFG file
+		(fIn.FindF(_L(".XML")) != KErrNotFound)?gIsXML = ETrue:gIsXML = EFalse;
+		
+		// display title
+		gConsole->Printf(_L("------------------------------------------------------------\n"));
+		gConsole->Printf(APPLICATIONNAME);
+		gConsole->Printf(_L("\n------------------------------------------------------------\n\n"));
+		gConsole->Printf(_L("CED is now processing the configuration file from [%S], \n"), &fIn);
+		
+		if ( bOverWrite )	gConsole->Printf(_L("The old database will be replaced \n") );
+		
+		if ( gIsXML )
+			{
+			gConsole->Printf(_L("The config file is in XML format \n") );
+			if ( bForceXMLProcessing )
+				{
+				gConsole->Printf(_L("Invalid table entry links will be allowed \n") );
+				}
+			else
+				{
+				gConsole->Printf(_L("Invalid table entry links will not be allowed \n") );
+				}
+			}
+		else
+			{
+			gConsole->Printf(_L("The config file is in CFG format \n") );
+			}
+		
+		// initialise output log file
+
+#ifndef __TOOLS2__
+		// Set up the session path for WINSCW / ARMv5 incase the log file name has no path.
+		fsSession.SetSessionPath( DEFAULT_SESSION_PATH );
+#endif
+
+		gMsg = CFileDump::NewL(fsSession, fOut, TPtrC(APPLICATIONNAME),
+								TPtrC(CEDUNVERSIONED), bDebugOn, gConsole, EFalse);
+		CleanupStack::PushL(gMsg);
+
+		if (!gMsg->IsInitialised())
+			{
+			gConsole->Printf(_L("Failed to open the output log file [%S]\n"), &fOut);
+			}
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("===================================================="));
+		gMsg->Msg(APPLICATIONNAME);
+		gMsg->Msg(_L("===================================================="));
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("Processing configuration from [%S]"), &fIn);
+		
+		gIsXML?gMsg->Msg(_L("The config file is in XML format ")):gMsg->Msg(_L("The config file is in CFG format ") );			
+		
+		if(gProcessingSuccessful)
+			{
+			gDB = new (ELeave) DBAccess(gIsXML);
+			CleanupStack::PushL(gDB);
+			gDB->CheckElementValidity(gValidityChecking);
+
+	        //If the settings are not ovewritten we are appending
+		    //This will take care of commdb ids
+		    gDB->SetInAppendMode(!bOverWrite);
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+            TBool isMeshCompatible(EFalse);
+                        
+            if (bOverWrite)
+            //The database has to be re-built...
+                {
+                
+                CInputFileParser* fileParser = CInputFileParser::FactoryLC(gIsXML, fIn, gMsg);
+
+                TRAPD(leaveVal, isMeshCompatible = fileParser->IsMeshCompatibleL());
+                CleanupStack::PopAndDestroy(fileParser);
+
+                if (leaveVal == KErrNone)
+                    {
+                    if (!isMeshCompatible)
+                        {
+        				gMsg->Msg(_L("MESHINFO: Configuration file [%S] is not mesh-compatible, inserting default meshtables"), &fIn);
+
+                        // Insert the new mesh related tables/records into the database.
+
+                        // The preface is a .cfg file, whatever the type of the original input file.
+                        //
+    			        if (gCfg.OpenConfigFile(fInPref))
+    				        {
+    						if (bOverWrite)
+    							{
+    				            DoDeleteL();
+    							}
+                            /**
+                              create a link resolver object which resolves all of the
+                              link by tag linking (Link.TableName.Id) to link by recordId
+                              (TableName.RecordId).
+                              This is important because there can be circular referencing
+                              between tables and if these tables contain link by tag refencing
+                              to each other commsDat doesn't allow to commit those tables...
+                            */
+                        	//this object will resolve the linkByTag linking to simple linkByRecId format
+            				LinkByTagResolver* resolver = LinkByTagResolver::NewLC(&gCfg, gMsg);
+                            
+                            //set the resolver object to the gDB object
+                            gDB->SetLinkByTagResolver(resolver);
+                            
+                            //Set the iIsXML field to false as we are processing now a cfg file...
+            				gDB->CfgXmlSetting() = EFalse;
+            				
+            				//The MeshPreface file will be processed first. This is important to know since here
+            				//we don't want to do any mappings...
+            				gDB->SetMeshProcessing(ETrue); 
+            				
+            				DoProcessL(ETrue);
+            				
+            				//if originally xml processing was set then set it back now...
+            				gDB->CfgXmlSetting() = gIsXML;
+            				
+            				//remove the resolver object form the gDB because it's not needed anymore
+            				gDB->RemoveLinkByTagResolver();
+            				CleanupStack::PopAndDestroy(resolver);
+            				resolver = NULL;
+            				
+            				gCfg.CloseConfigFile();
+            				if (!gValidityChecking)
+            					{
+            					gProcessingSuccessful = ETrue;
+            					}
+            				}
+    			        else
+    				        {
+            				gMsg->Error(_L("MESHERR: Configuration file [%S] could not be opened"), &fInPref);
+            				gProcessingSuccessful = EFalse;
+            				}
+            			}
+            		else
+            		    {
+        				gMsg->Msg(_L("MESHINFO: Configuration file [%S] is mesh-compatible"), &fIn);
+            		    }
+            		}
+                else
+                    {
+    				gMsg->Error(_L("MESHERR: Configuration file [%S], processing failed, reason=<%d>"), &fIn, leaveVal);
+    				gProcessingSuccessful = EFalse;
+    				}
+                }
+            else
+                {
+                gMsg->Msg(_L("Appending data to the DB - no need to use the meshpreface config file"));
+                }
+            
+            
+            if (gProcessingSuccessful)
+                {
+#endif
+			// Process the XML configuration file
+			if (gIsXML)
+				{			    
+				// Create the XML database
+				CXMLDatabase* xmlDb = CXMLDatabase::NewL();
+				CleanupStack::PushL(xmlDb);
+				
+				gXML = new (ELeave) XMLFile;
+				CleanupStack::PushL(gXML);
+				
+				if (gXML->OpenConfigFile(fsSession,fIn,xmlDb,bForceXMLProcessing, !bOverWrite))
+					{
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+                    if (isMeshCompatible)
+                        {
+#endif
+						if (bOverWrite)
+    					    {
+    					    DoDeleteL();
+							}
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+        				}
+
+
+                    if (isMeshCompatible)
+                    	{
+                    	gDB->SetMeshProcessing(ETrue);
+                    	}
+                    else
+                    	
+#endif
+						{
+                    	gDB->SetMeshProcessing(EFalse);
+                    	}
+                    
+					TRAPD(ret, DoProcessL(EFalse));
+                    gXML->CloseConfigFile();
+                    
+                    if (gValidityChecking && ret != KErrNone)
+                    	{
+                    	gProcessingSuccessful = EFalse;
+                    	}
+					}
+				else
+					{
+					gMsg->Msg(_L("ERR: A problem was encountered while processing the configuration file [%S]"), &fIn);
+					gProcessingSuccessful = EFalse;
+					}
+				
+				// Cleanup
+				CleanupStack::PopAndDestroy(gXML);
+				CleanupStack::PopAndDestroy(xmlDb);
+
+				gXML=NULL;
+				xmlDb=NULL;
+				}
+			else
+				{
+				if (gCfg.OpenConfigFile(fIn))
+					{
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+                    if (isMeshCompatible)
+                        {
+#endif
+						if (bOverWrite)
+						    {
+    					    DoDeleteL();
+							}
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+        				}
+                    /**
+                      create a link resolver object which resolves all of the
+                      link by tag linking (Link.TableName.Id) to link by recordId
+                      (TableName.RecordId).
+                      This is important because there can be circular referencing
+                      between tables and if these tables contain link by tag refencing
+                      to each other commsDat doesn't allow to commit those tables...
+                    */
+                    LinkByTagResolver* resolver = LinkByTagResolver::NewLC(&gCfg, gMsg);
+                    
+                    if (isMeshCompatible)
+                    	{
+                    	//our config file is a mesh compatible one so we can use the latestVersion in the DBSession
+                    	gDB->SetMeshProcessing(ETrue);
+                    	}
+                    else
+                    	{
+                    	//our config file is not a mesh compatible one so we can should the version 1_1 in the 
+                    	//DBSession
+                    	gDB->SetMeshProcessing(EFalse);
+                    	}
+                    
+                    gDB->SetLinkByTagResolver(resolver);
+#endif
+					TRAPD(ret, DoProcessL(ETrue));
+					gCfg.CloseConfigFile();
+					
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+					gDB->RemoveLinkByTagResolver();
+					CleanupStack::PopAndDestroy(resolver);
+					resolver = NULL;
+#endif
+
+                    if (gValidityChecking && ret != KErrNone)
+                    	{
+                    	gProcessingSuccessful = EFalse;
+                    	}
+					}
+				else
+					{
+					gMsg->Msg(_L("ERR: Configuration file [%S] could not be opened"), &fIn);
+					gProcessingSuccessful = EFalse;
+					}
+				}
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+                }
+#endif
+			CleanupStack::PopAndDestroy(gDB);
+			gDB=NULL;
+			}
+		
+		gMsg->Dbg(_L(""));
+		gMsg->Dbg(_L("Session finished"));
+		gMsg->Dbg(_L(""));
+		gMsg->Msg(_L("==================="));
+		
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+		if (gDeprecatedFields)
+			{
+			gMsg->Msg(_L("WARNING: USE OF DEPRECATED FIELDS"));
+			}
+#endif
+//SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+		// write our processing indicater to the log file
+		gProcessingSuccessful?gMsg->Msg(_L("SUCCESS")):gMsg->Msg(_L("ERROR"));
+	
+		CleanupStack::PopAndDestroy(gMsg);
+		}
+		
+	CleanupStack::PopAndDestroy(&fsSession);
+	}
+
+LOCAL_C void doMainL()
+	{
+	// allocate a gConsole
+	gConsole = Console::NewL(APPLICATIONNAME, TSize(KConsFullScreen, KConsFullScreen));
+	CleanupStack::PushL(gConsole);
+	
+	// call main routine
+	MainL();
+	
+	CleanupStack::PopAndDestroy(gConsole);
+	}
+
+TInt E32Main()
+	{	
+	__UHEAP_MARK;
+	
+	// set up trap cleanup framework
+	CTrapCleanup* theCleanup = CTrapCleanup::New();
+	
+	// call main routine and trap any exceptions
+	TRAPD(ret,doMainL());
+	if(ret != KErrNone && gValidityChecking)
+		{
+		gProcessingSuccessful = EFalse;
+		}
+	
+	// clean up when finished
+	delete theCleanup;
+	
+	__UHEAP_MARKEND;
+	
+	// Convert the boolean idea of "success" into the customary process idea of errorlevel, where zero
+	// is success and anything else designates particular kinds of failure. Specific failure reasons aren't
+	// provided, so the caller should only look for process exit != 0 to mean failure, and then examine the
+	// log to see what failed.
+	return !gProcessingSuccessful;
+	}
+
+
+TInt ParseCommandLineL(TBool &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut, TDes &aInPref)
+/** Parse the command line for any overriding settings from exe command line 
+
+@param bDebugOn Wether to output debug messages to the log file using CFileDump::Dbg(TPtrC text, ...)
+@param bOverWrite Determines whether to append to or erase any existing databases
+@param bForceXMLProcessing Determines if invalid table entry links will be allowed
+@param fIn Path and filename of the configuration database file
+@param fOut Filename of the file to send logging too
+@return ETrue if Successful else EFalse 
+*/
+	{
+	TInt valid = EFalse;
+	CCommandLineArguments *pCmd;
+	pCmd = CCommandLineArguments::NewL();
+	CleanupStack::PushL(pCmd);
+	
+	// set defaults
+	aIn  = XML_TARGET;
+	aOut = LOG_TARGET;
+	aInPref = KMeshPrefaceFile;
+	
+	// Flags for encountering the specification
+	// of an input and an output file
+	TBool bInFound  = EFalse;
+	TBool bOutFound = EFalse;
+	TBool bDatabaseSpecified = EFalse;
+	
+	//By default delete old database 
+	aOverWrite = ETrue;
+	
+	if (pCmd)
+		{
+		TBuf<MAX_ARG_LEN> arg;
+		
+		// check all arguments for switches
+		TInt i = 0;
+		while( ++i < pCmd->Count() )
+			{
+			arg = pCmd->Arg(i);
+			arg.UpperCase();
+			
+			// CED will report all the failures on the end, unlike success in all the cases except missing cfg file
+			// Switch introduced because of high impact on test results and to avoid BC break
+			if ( arg.FindF(_L("-V")) != KErrNotFound )
+				{
+				gValidityChecking = ETrue;
+				continue;
+				}
+
+			//Display help
+			if ( arg.FindF(_L("-H")) != KErrNotFound )
+				{
+				HelpDump();
+				CleanupStack::Pop(pCmd);
+				delete pCmd;
+				return valid;
+				}
+			
+			// Append database switch
+			if ( arg.FindF(_L("-A")) != KErrNotFound )
+				{
+				aOverWrite = EFalse;
+				continue;
+				}
+			
+			// Debug switch
+			if ( arg.FindF(_L("-D")) != KErrNotFound )
+				{
+				aDebugOn = ETrue;
+				continue;
+				}
+
+			// Debug switch
+			if ( arg.FindF(_L("-M")) != KErrNotFound )
+				{
+				aInPref = pCmd->Arg(++i);
+				continue;
+				}
+			
+			// Presence of invalid table entry links
+			// will not cause an error
+			if ( arg.FindF(_L("-F")) != KErrNotFound )
+				{
+				aForceXMLProcessing = ETrue;
+				continue;
+				}
+			
+			// Specification of an input file
+			if ( arg.FindF(_L("-I")) != KErrNotFound )
+				{
+				if( i != pCmd->Count()-1 )
+					{
+					aIn = pCmd->Arg(++i);
+					bInFound = ETrue;
+					continue;
+					}
+				else
+					{
+					gConsole->Printf(_L("Argument missing after '-i' switch\n"));
+#ifndef __TOOLS2__
+					gConsole->Printf(_L("\nPress any key to finish"));
+					gConsole->Getch();
+#endif
+					CleanupStack::Pop(pCmd);
+					delete pCmd;
+					return valid;
+					}
+				}
+			// Specification of an output file
+			if ( arg.FindF(_L("-O")) != KErrNotFound )
+				{
+				if( i != pCmd->Count()-1 )
+					{
+					aOut = pCmd->Arg(++i);
+					bOutFound = ETrue;
+					continue;
+					}
+				else
+					gConsole->Printf(_L("Argument missing after '-o' switch\n"));
+#ifndef __TOOLS2__
+					gConsole->Printf(_L("\nPress any key to finish"));
+					gConsole->Getch();
+#endif
+					CleanupStack::Pop(pCmd);
+					delete pCmd;
+					return valid;
+				}
+#ifdef __TOOLS2__
+			// Specification of the database binary version
+			// This must be specified on the tools2 platform.
+			TBuf<16> databaseVersion;
+			
+			if ( arg.FindF(_L("-B")) != KErrNotFound )
+				{
+				if( i != pCmd->Count()-1 )
+					{
+					databaseVersion = pCmd->Arg(++i);
+					if(databaseVersion.Compare(SUPPORTED_OS) == 0)
+						{
+						bDatabaseSpecified = ETrue;
+						continue;
+						}
+					else
+						{
+						gConsole->Printf(_L("O/S version '%S' is not supported by this version of CED"), &databaseVersion);
+						CleanupStack::Pop(pCmd);
+						delete pCmd;
+						return valid;
+						}
+					}
+				else
+					{
+					gConsole->Printf(_L("Argument missing after '-b' switch"));
+					CleanupStack::Pop(pCmd);
+					delete pCmd;
+					return valid;
+					}
+				}
+#endif
+			// No flag is supplied: first file encountered is the input
+			// file and the following one is the output file
+			
+			if ( !bInFound )
+				{
+				aIn = pCmd->Arg(i);
+				bInFound = ETrue;
+				continue;
+				}
+			if ( !bOutFound )
+				{
+				aOut = pCmd->Arg(i);
+				bOutFound = ETrue;
+				continue;
+				}     
+			}
+		
+		if (aIn.Length() > 0)
+			valid = ETrue;
+		
+		//If here then no prefered config file has been specified.
+		//Find default input file
+        if ( !bInFound )
+			{
+			RFs fs;
+			fs.Connect();
+			CleanupClosePushL(fs);
+			TUint dummy;
+			
+			if(fs.Att(XML_TARGET,dummy)==KErrNone)
+				{
+				aIn  = XML_TARGET;
+				}
+			else if(fs.Att(CFG_TARGET,dummy)==KErrNone)
+				{
+				aIn  = CFG_TARGET;
+				}
+			else
+				{
+				gConsole->Printf(_L("No configuration files found please specify a .cfg or .xml file\n"));
+#ifndef __TOOLS2__
+				gConsole->Printf(_L("\nPress any key to finish"));
+				gConsole->Getch();
+#endif
+				valid=EFalse;
+				}
+			CleanupStack::PopAndDestroy(&fs);
+			}
+		
+#ifdef __TOOLS2__
+		if ( !bDatabaseSpecified )
+			{
+			gConsole->Printf(_L("Must specify the '-b' switch\n"));
+			valid=EFalse;
+			}
+#endif
+		CleanupStack::Pop(pCmd);
+		delete pCmd;	
+	}
+	
+	return valid;
+}
+
+void HelpDump()
+/**
+Prints basic help information to the emulator window including command switches
+*/
+	{
+	gConsole->Printf(_L("Creates/Updates a Comms Database using an input file"));
+	gConsole->Printf(_L("\n\nCED [-a] [-d] [-f] [-i [path]filename] [-o [path]filename]"));
+	gConsole->Printf(_L("\n\n-a\tAppends the data read from the input file to the existing Comms Database."));
+	gConsole->Printf(_L("\n-d\tSwitches debug mode on giving more data in the log file."));
+	gConsole->Printf(_L("\n-f\tAllows invalid data entries. Primarily used for testing."));
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+	gConsole->Printf(_L("\n-m  Specifies the default mesh configuration file to CED. Defaults to reading '%S'."), &KMeshPrefaceFile);
+#endif
+	gConsole->Printf(_L("\n-v  Enables validation of the configuration data while writing to the database."));
+	gConsole->Printf(_L("\n-i  Specifies an input file to CED. Must be either *.xml or *.cfg. Defaults to reading '%S' or '%S'."), &CFG_TARGET, &XML_TARGET);
+	gConsole->Printf(_L("\n-o  Specifies an output file for CED to log to. Defaults to '%S'."), &LOG_TARGET);
+#ifdef __TOOLS2__
+	gConsole->Printf(_L("\n-b  Specifies the binary output should be compatible with this Symbian OS version.\n"));
+#endif
+#ifndef __TOOLS2__
+	gConsole->Printf(_L("\nPress any key to finish"));
+	gConsole->Getch();
+#endif
+	}
+
+TInt ParseArgument(TBool &aDebugOn, TBool &aOverWrite, TBool &aForceXMLProcessing, TDes &aIn, TDes &aOut)
+/** Parse the command line for any overriding settings from DLL call
+
+@param bDebugOn Wether to output debug messages to the log file using CFileDump::Dbg(TPtrC text, ...)
+@param bOverWrite Determines whether to append to or erase any existing databases
+@param bForceXMLProcessing Determines if invalid table entry links will be allowed
+@param fIn Path and filename of the configuration database file
+@param fOut Filename of the file to send logging too
+@return ETrue if Successful else EFalse 
+*/
+	{
+	// use Tlex to decode the cmd line
+	TLex lex(gArgumentLine->Des());
+	
+	// By default delete old database 
+	aOverWrite = ETrue;
+	
+	// get the input file
+	aIn=lex.NextToken();
+	if ( aIn.Length() == 0 ) 
+		aIn = XML_TARGET;
+	
+	// get the output file
+	aOut = lex.NextToken();
+	if ( aOut.Length() == 0 ) // if valid potential 
+		aOut = LOG_TARGET;
+	
+	// get the debug switch parameters
+	if ( gArgumentLine->FindF(_L("-D")) != KErrNotFound )
+		aDebugOn = ETrue;
+	
+	if ( gArgumentLine->FindF(_L("-O")) != KErrNotFound )
+		aDebugOn = ETrue;
+	
+	// append switch
+	if ( gArgumentLine->FindF(_L("-A")) != KErrNotFound )
+		aOverWrite = EFalse;
+	
+	// force processing of XML file even in the
+	// presence of invalid table entry links
+	if ( gArgumentLine->FindF(_L("-F")) != KErrNotFound )
+		aForceXMLProcessing = ETrue;	
+	
+	delete gArgumentLine;
+	
+	return ETrue;
+	}
+
+LOCAL_C TInt ProcessCfgDataL(TDesC &aTable,const TInt &aIndex)
+/** Process old style .cfg database file 
+
+@param aTable Name of the entry being processed
+@param aIndex Counted table number being processed
+@return ETrue if Successful else EFalse 
+*/
+	{
+	TInt recordsInserted(0);  
+	TInt fatalErr(KErrNone); 
+	TBool firstRec(ETrue);
+	TInt valid(KErrNotReady);
+	
+	_LIT(KConnectionPrefTableName, "ConnectionPreferences");
+	while(fatalErr == KErrNone && (firstRec || gCfg.StepToNextBlock()))
+		{
+		if (!firstRec)
+			{
+			gMsg->Msg(_L(" "));	// blank line between records
+			}
+
+		if(gDB->CommitIndividualRecords())
+			{
+ 			gDB->CreateOrInsertRecordL(firstRec? DBAccess::ECreateNew: DBAccess::ECreateInsert,elementIdArray[aIndex], 0);			
+ 			}
+ 		firstRec = EFalse;
+ 		
+		TInt value = recordsInserted + 1;
+		TPtrC idText;
+		_LIT(KCommDbIDTag, "COMMDB_ID ");
+		valid = gCfg.GetSetting(KCommDbIDTag, idText);
+		if (valid == KErrNone)
+			{
+			TLex lex(idText);
+			if(lex.Val(value) != KErrNone)
+				{
+				gMsg->Dbg(_L("Missing COMMDB_ID - defaulting to record count"));
+				}
+			}
+		gDB->CreateOrInsertRecordL(DBAccess::EInsert, 0, value); 			
+		
+		// find out how many fields we are expecting in this insert
+		TPtrC result = NO_MORE_RECORDS;
+		TInt iValue;
+		valid = gCfg.GetSetting(FIELD_COUNT, result);
+		if (valid == KErrNone)
+			{
+			TLex iResult = result;	
+			iValue = 0;		
+			if (iResult.Val(iValue) == KErrNone)
+				gDB->SetFieldCount(iValue);
+			}
+		
+		//Write column info
+		TInt err = SetColumnDetailsL(aIndex, recordsInserted + 1);
+		iValue = gDB->GetFieldCount(); //If Recordname was not supplied, SetColumnDetailsL fn would have added the misisng name..so refresh he actual field count
+		
+		if(err == KErrNone)
+			{
+			if(gDB->GetActualFieldCount() != iValue)
+				{
+				gMsg->Msg(_L(" ERR Table %S Expected [%d] values, read [%d].Field count mismatch!"), &aTable, iValue, gDB->GetActualFieldCount());
+				gDB->RemoveCurrentRecord();
+				if (gValidityChecking) 
+					{
+					gProcessingSuccessful = EFalse;
+					}
+				continue;	// it's not fatal
+				}
+			
+			if(aTable.Compare(KConnectionPrefTableName) == 0)
+				{
+				CMDBRecordBase* dontDelete = gDB->GetCurrentRecord();
+				if(!gDB->IsConnectionPrefValid(*(static_cast<CCDConnectionPrefsRecord*>(dontDelete))))
+					{
+					fatalErr = KErrArgument;	// or should we continue?
+					}					
+				}
+			if(gDB->CommitIndividualRecords())
+				{
+				err = gDB->CommitChanges();
+				}
+			if(err != KErrNone)
+				{
+				gMsg->Msg(_L("Error %d inserting record #%d to %S"), err, recordsInserted + 1, &aTable);
+				if (gValidityChecking) 
+					{
+					gProcessingSuccessful = EFalse;
+					}
+	 			}
+			else
+	 			{
+				recordsInserted++;
+	 			}
+			}
+		else if(err != KErrCancel)	//to ignore cancels called by ced itself, used to process unused entries produced by older ceddumpers
+			{
+			gMsg->Msg(_L("Error %d inserting record #%d to %S"), err, recordsInserted + 1, &aTable);
+			if (gValidityChecking) 
+				{
+				gProcessingSuccessful = EFalse;
+				}
+			
+			gDB->RemoveRecord(recordsInserted);
+			//fatalErr = err;
+			}
+		}
+		
+	return ((fatalErr == KErrNone)?recordsInserted:fatalErr);
+	}
+
+TInt DoCfgTemplateL(TDesC &aTable, const TInt &aIndex)
+/**
+Applying the templates
+
+  @param table A reference to a descriptor containing the name of a table
+  @param index Index in the Table
+  @return ETrue if Successful else EFalse 
+  */
+	{
+	// look for template and load it
+	if (!gCfg.OpenTemplateBlock(aTable))
+		return EFalse;
+	
+	DisplayMessage(_L("Processing template"), ETrue);
+	gDB->RecordIsTemplate(ETrue); 	
+	
+	TInt templateRecordsInserted = ProcessCfgDataL(aTable,aIndex);
+	
+	if (templateRecordsInserted > 0)
+		{
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("[%d] Template record(s) successfully inserted"), templateRecordsInserted);
+		}
+	else
+		{
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("Insert record failed Err:[%d]"), templateRecordsInserted);
+		}
+	
+	return templateRecordsInserted;
+	}
+
+TInt DoCfgInsertsL(TDesC &aTable, const TInt &aIndex)
+/**
+Runs through all the steps involved in applying an insert to a particular table.
+
+  @param table A reference to a descriptor containing the name of a table
+  @param index Index in the Table
+  @return ETrue if Successful else EFalse 
+  */
+	{
+	
+	// look for any inserts and load the first one
+	if (!gCfg.OpenAddBlock(aTable))
+		return EFalse;
+	
+	DisplayMessage(_L("Processing inserts"), ETrue);
+	gDB->RecordIsTemplate(EFalse); 	
+
+	TInt recordsInserted = ProcessCfgDataL(aTable,aIndex);
+	
+	if (recordsInserted >= 0)
+		{
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("[%d] record(s) successfully inserted"), recordsInserted);
+		}
+	else
+		{
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("Insert record failed Err:[%d]"), recordsInserted);
+		}
+	return recordsInserted;			
+	}
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+/**
+Loops through the table of deprecated columns/parameters and gives an information 
+to the user question column/parameter is deprecated. 
+
+  @param aIndex    Index in the elementIdArray Table
+  @param aColumnName Name of the questioned column/parameter
+*/
+void VerifyDeprecatedFields(TInt aIndex, TPtrC& aColumnName)
+	{
+	TBuf<MAX_BUFFER_LEN> tempColumn;
+	TInt i = 0;
+	if (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord 
+		|| elementIdArray[aIndex] == KCDTIdIncomingGprsRecord )
+		{
+		tempColumn = DeprecParamArray[i];
+		while(tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+			{
+			if (aColumnName.Compare(tempColumn) == 0 )
+				{
+				gMsg->Msg(_L(" Warning - Use of deprecated parameter [%S]"), &aColumnName);
+				gDeprecatedFields = ETrue;
+				}
+			tempColumn = DeprecParamArray[++i];
+			}
+		}
+	}
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+TBool IsGprsGatewayField(TInt aIndex, const TPtrC& aColumnName)
+/**
+Determine if a field being processed is the IpGateway field in OutgoingGPRS table
+
+@param aIndex index into elementIdArray[] for identifying table
+@param aColumnName descriptor identifying the field
+*/
+	{
+	return (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord && aColumnName.Compare(TPtrC(GPRS_IP_GATEWAY)) == 0);
+	}
+
+TInt SetupIpGatewayFieldDefaultL(TInt aIndex)
+/**
+Setup a safe default value for the IpGateway field in OutgoingGPRS tables.  If a value has not
+been specified in the CFG or XML file, then it would ordinarily default to 0.0.0.0.  However,
+this value will mean that the TCP/IP stack will not setup a default route.  Consequently,
+we must setup a safe default of 0.0.0.1.
+
+@param aIndex index into elementIdArray[] for identifying the table
+*/
+	{
+	if (elementIdArray[aIndex] == KCDTIdOutgoingGprsRecord)	// only for OutgoingGPRS table records !
+		{
+		// Only setup IpGateway field if it is not already present in the OutgoingGPRS template record.
+		if (!gDB->TemplateFieldPresentL(KCDTIdOutgoingGprsRecord | KCDTIdWCDMAIPGateway))
+			{
+			TPtrC setting;
+			TPtrC column;
+			_LIT(KGprsIpGateway, "0.0.0.1");
+			setting.Set(KGprsIpGateway());
+			column.Set(TPtrC(GPRS_IP_GATEWAY));
+			gMsg->Msg(_L(" NOTE  [%S] set to default value of %S"), &column, &setting);
+			TInt ret = gDB->SetColAndAttribL(column, setting);
+			gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the gateway field
+			return ret;
+			}
+		}
+	return KErrNone;
+	}
+	
+void HandleConnPrefWithoutDefaultIap()
+/**
+Handle special case of ConnPref record without default IAP set (empty db use case)
+*/
+	{
+	if(gDB->GetCurrentRecord()->TableId() == KCDTIdConnectionPrefsRecord)
+		{
+		CCDConnectionPrefsRecord* connPref = static_cast<CCDConnectionPrefsRecord*>(gDB->GetCurrentRecord());
+		if(!(connPref->iDefaultIAP.ElementId() & KCDChangedFlag))
+			{
+			connPref->iDefaultIAP = 0;
+			}
+		}
+	}
+
+TInt SetColumnDetailsL(TInt aIndex, TInt aRecordCount)
+/**
+Loops through all the columns of a particular table.  If any of the columns match the setting
+in the log file, it is stored, along with the value to write into this field.
+
+@param aTable    A reference to a descriptor containing the name of a table
+@param aIndex    Index in the Table
+@param aRecCnt   Index of the Record in the table
+@return ETrue    if Successful else EFalse 
+*/
+	{	
+	
+	static TBuf<MAX_BUFFER_LEN> tempColumn;
+	TPtrC column;
+	TPtrC setting;
+	TInt valid(KErrNone);
+	TInt i = 0;
+	tempColumn = ColumnArray[aIndex][i];
+	TInt fieldValueRead(KErrNone);
+	TBool gprsGatewayFieldIsSet = EFalse;		// whether IpGateway field in OutgoingGPRS table record has been set
+
+	// loop through columns of table
+	while( (valid==KErrNone) && (tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0))
+		{		
+		// get a column from the config file
+		gMsg->Dbg(_L(" Looking for [%S]"), &tempColumn);
+		// set the read value to the column
+		fieldValueRead = gCfg.GetSetting(tempColumn,setting);
+		if(fieldValueRead == KErrNone)
+			{
+			column.Set(tempColumn);
+         	
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS			
+			VerifyDeprecatedFields(aIndex, column);
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS			
+
+			// Determine whether the GPRS IP Gateway field has been set or not
+			if (IsGprsGatewayField(aIndex, column))
+				{
+				gprsGatewayFieldIsSet = ETrue;
+				}
+
+			if( (tempColumn.Compare(TPtrC(COMMDB_NAME)) == 0) &&
+				(setting.Compare(TPtrC(COMMDB_UNUSED_NAME)) == 0)
+				)
+				{
+				//this record is not valid,,,remove
+				gDB->RemoveCurrentRecord();
+				if (gValidityChecking) 
+					{
+					gProcessingSuccessful = EFalse;
+					}
+				return KErrCancel;				
+				}
+			
+			valid = gDB->SetColAndAttribL(column,setting);
+			}	
+		// decrement the field count for fields simply left blank
+		else if(fieldValueRead == KErrArgument)
+			{
+			gDB->SetFieldCount(gDB->GetFieldCount() - 1);	
+			}
+		i++;
+		tempColumn = ColumnArray[aIndex][i];	
+		}
+	
+	//if the record is not empty and also has its name field or fieldvalue missing, set a default name, using the 
+	//record id if set, else simply the record count
+	//Only do this if not entering a Template Record
+    if(gDB->GetCurrentRecord()->RecordId() != KCDDefaultRecord && 
+       ((!gDB->IsNameSet() && gDB->GetActualFieldCount()) ||
+        (!gDB->IsNameSet() && KErrArgument)) )	
+		{
+		_LIT(KNameTemplate, "DefaultRecordName-%d");
+		TBuf<MAX_BUFFER_LEN> recordName;
+		TInt recId = gDB->GetCurrentRecord()->RecordId();
+		recordName.Format(KNameTemplate, recId? recId: aRecordCount);
+		column.Set(TPtrC(COMMDB_NAME));		
+		setting.Set(TPtrC(recordName));	    			
+		valid = gDB->SetColAndAttribL(column,setting);			
+		gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the missing name
+	    }
+	
+	if (valid == KErrNone && !gprsGatewayFieldIsSet)
+		{
+		// If required, setup a suitable default value for IpGateway field in OutgoingGPRS table records
+		valid = SetupIpGatewayFieldDefaultL(aIndex);
+		}
+	
+	// Handle special case of ConnPref record without default IAP set (empty db use case)
+	HandleConnPrefWithoutDefaultIap();
+
+	return valid;
+	}
+
+LOCAL_C TInt ProcessXmlDataL(TBool aIsTemplate,const TInt &aIndex)
+/** Runs through all the steps involved in applying an insert to a particular table
+	(for the XML configuration file) 
+
+@param aIsTemplate Wether the entry being processed is a template or add entry
+@param aIndex Counted table number being processed
+@return Number of successfully inserted records
+*/
+	{
+	TBuf<MAX_BUFFER_LEN> xmlTableName = xmlTableArray[aIndex];
+	xmlTableName.Append(_L("Table"));
+	
+	// look for template
+	TInt startIndex = gXML->GetStartingIndex(xmlTableName);
+	TInt lastIndex  = gXML->GetLastIndex(xmlTableName);
+	
+	if(startIndex == -1 || lastIndex == -1)
+		return EFalse;
+	
+	if(aIsTemplate)
+		{
+		DisplayMessage(_L("Processing template"), ETrue);	
+		gDB->RecordIsTemplate(ETrue); 
+		}
+	else
+		{
+		DisplayMessage(_L("Processing inserts"), ETrue);	
+		gDB->RecordIsTemplate(EFalse); 
+		}
+	
+	TInt recordsInserted(0);
+	TInt ret(KErrNone);
+	
+	for(TInt iEntryIndex = startIndex; iEntryIndex <= lastIndex; iEntryIndex++)
+		{
+		if(aIsTemplate)
+			{
+			if(gXML->GetOperation(iEntryIndex).Compare(_L("template")) != 0)
+				{
+				continue;	
+				}				
+			}
+		else
+			{
+			if(gXML->GetOperation(iEntryIndex).Compare(_L("add")) != 0)
+				{
+				continue;
+				}					
+			}
+		
+		gMsg->Msg(_L("Record Number: #[%d]"), gXML->GetElementRecordID(iEntryIndex));
+		if(gDB->CommitIndividualRecords())
+			{
+			gDB->CreateOrInsertRecordL(iEntryIndex == startIndex? DBAccess::ECreateNew: DBAccess::ECreateInsert,elementIdArray[aIndex], 0);			
+			}
+	    
+	    //!!!!!!!!!!!!!!!!!the record ID of the given xmlDBentry should be read here...
+	    
+		//gDB->CreateOrInsertRecordL(DBAccess::EInsert,0,0); 
+		
+		gDB->CreateOrInsertRecordL(DBAccess::EInsert,0,gXML->GetElementRecordID(iEntryIndex)); 
+		
+		// find out how many fields we are expecting in this insert
+		TInt iValue = gXML->GetEntryNumberParameters(iEntryIndex);
+        gDB->SetFieldCount(iValue);
+        
+        //Write column info
+		ret = SetXMLColumnDetailsL(iEntryIndex,aIndex,iEntryIndex - startIndex + 1);
+		/*if(ret != KErrNone)
+			return ret;*/
+		
+		if(gDB->CommitIndividualRecords())
+			{
+			ret = gDB->CommitChanges();
+			}
+		if(ret != KErrNone)
+			{
+			gMsg->Msg(_L("Error %d inserting record #%d to %S"), ret, iEntryIndex - startIndex + 1, &xmlTableName);
+
+			if (gValidityChecking) 
+				{
+				gProcessingSuccessful = EFalse;
+				}
+			
+			gDB->RemoveRecord(gXML->GetElementRecordID(iEntryIndex)-1);
+			
+			}
+		else
+			{
+			recordsInserted++;
+			}
+		}
+	
+	if (recordsInserted)
+		{
+		gMsg->Msg(_L(" "));
+		gMsg->Msg(_L("[%d] record(s) successfully inserted"), recordsInserted);
+		}
+	
+	return recordsInserted;	
+	}
+
+
+TInt DoXMLInsertsL(const TInt &aIndex)
+/**
+Runs through all the steps involved in applying an insert to a particular table.
+
+@param index Index in the Table
+@return Number of successfully inserted records
+*/
+	{
+	return (ProcessXmlDataL(EFalse,aIndex));
+	}
+
+TInt DoXMLTemplateL(const TInt &aIndex)
+/**
+Applying the templates (for the XML configuration file)
+
+@param index Index in the Table
+@return Number of successfully inserted records
+*/
+	{
+	return (ProcessXmlDataL(ETrue,aIndex));
+	}
+
+TInt SetXMLColumnDetailsL(TInt aEntryIndex, TInt aIndex, TInt aRecCount)
+/** Loops through all the columns of a particular table.  If any of the columns match the setting
+	in the log file, it is stored, along with the value to write into this field.
+
+@param aEntryIndex 
+@param aIndex 
+@param aRecCount 
+@return True if successful else false 
+*/
+	{
+	static TBuf<MAX_BUFFER_LEN> tempColumn;
+	TPtrC setting;
+	TPtrC column;
+	TInt valid(KErrNone);
+	TInt i = 0;
+	TBool gprsGatewayFieldIsSet = EFalse;		// whether IpGateway field in OutgoingGPRS table record has been set
+
+	tempColumn = ColumnArray[aIndex][i];
+	
+	
+	// loop through columns of table
+	while( (valid==KErrNone) && tempColumn.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+		{
+		// get a column from the config file
+		gMsg->Dbg(_L(" Looking for [%S]"), &tempColumn);
+		
+		if (gXML->GetSetting(aEntryIndex, tempColumn, setting))
+			{
+			column.Set(ColumnArray[aIndex][i]);	
+			valid = gDB->SetColAndAttribL(column,setting);
+
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS			
+			VerifyDeprecatedFields(aIndex, column);
+#endif
+// SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+
+			// Determine whether the GPRS IP Gateway field has been set or not
+			if (IsGprsGatewayField(aIndex, column))
+				{
+				gprsGatewayFieldIsSet = ETrue;
+				}
+			}
+		i++;
+		tempColumn = ColumnArray[aIndex][i];
+		}	
+	
+	//if the record is not empty and also has its name missing, set a default name
+    //only do this if not processing a template record
+	if(!gDB->IsNameSet() && 
+        gDB->GetActualFieldCount() && 
+        gDB->GetCurrentRecord()->RecordId() != KCDDefaultRecord)	
+		{		
+		_LIT(KNameTemplate, "DefaultRecordName-%d");
+		TBuf<MAX_BUFFER_LEN> recordName;
+		recordName.Format(KNameTemplate, aRecCount);
+		column.Set(TPtrC(COMMDB_NAME));		
+		setting.Set(TPtrC(recordName));	    			
+		valid = gDB->SetColAndAttribL(column,setting);	
+		gDB->SetFieldCount(gDB->GetFieldCount() + 1); //field count increment by one because we added the missing name
+	    }
+
+	if (valid == KErrNone && !gprsGatewayFieldIsSet)
+		{
+		// If required, setup a suitable default value for IpGateway field in OutgoingGPRS table records
+		valid = SetupIpGatewayFieldDefaultL(aIndex);
+		}
+	
+	// Handle special case of ConnPref record without default IAP set (empty db use case)
+	HandleConnPrefWithoutDefaultIap();
+
+	return valid;
+	}
+
+void DisplayMessage(TPtrC aMessage, TInt aJustTheMessage)
+/**
+Writes a message to the log file, along with any associated error.
+
+@param aMessage Message to be written 
+@param aJustTheMessage Output only the plain message to the log file
+*/
+	{
+	if (aJustTheMessage)
+		{
+		gMsg->Msg(_L("%S"), &aMessage);
+		}
+	else
+		{
+		if (gDB->ErrorCode() != KErrAlreadyExists && gDB->ErrorCode() != E_ALREADYEXISTS)
+			gMsg->Msg(_L(" "));
+		
+		gMsg->Msg(_L(" "));
+		
+		if (gDB->ErrorCode())
+			{
+			static TBuf<MAX_BUFFER_LEN> errorText;
+			errorText = gDB->ErrorText();
+			
+			if (gDB->ErrorCode() == KErrAlreadyExists || gDB->ErrorCode() == E_ALREADYEXISTS)
+				gMsg->Msg(_L("WARN: %S failed: %S [%d]"), &aMessage, &errorText, gDB->ErrorCode());
+			else if (gDB->ErrorCode() < 0)
+				gMsg->Msg(_L("ERR: %S failed: %S [%d]"), &aMessage, &errorText, gDB->ErrorCode());
+			else
+				gMsg->Msg(_L("ERR: %S failed: %S"), &aMessage, &errorText);
+			}
+		else
+			{
+			gMsg->Msg(_L("ERR: %S failed"), &aMessage);
+			}
+		
+		// don't fail when the record is there already
+		if (gDB->ErrorCode() != KErrAlreadyExists && gDB->ErrorCode() != E_ALREADYEXISTS)
+			{
+			gMsg->Msg(_L(" "));
+			gMsg->Msg(_L(" "));
+			gProcessingSuccessful = EFalse;
+			}
+		}
+	}
+
+
+#ifndef __TOOLS2__
+EXPORT_C TInt NewApplicationL(const TDesC& aText)
+/**
+entry point used in WINS when ced is build as a exedll
+
+@param Text Command line argument
+*/
+	{
+	// save the command line info
+	gArgumentLine=aText.AllocL();
+	
+	// record that ced is running as a exe dll
+	gIsExeDLL = ETrue;
+	
+	// call main
+	return E32Main();
+	}
+#endif
+
+